@bquery/bquery 1.7.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/README.md +760 -716
  2. package/dist/{a11y-C5QOVvRn.js → a11y-DVBCy09c.js} +3 -3
  3. package/dist/a11y-DVBCy09c.js.map +1 -0
  4. package/dist/a11y.es.mjs +1 -1
  5. package/dist/component/library.d.ts.map +1 -1
  6. package/dist/{component-CuuTijA6.js → component-L3-JfOFz.js} +5 -5
  7. package/dist/component-L3-JfOFz.js.map +1 -0
  8. package/dist/component.es.mjs +1 -1
  9. package/dist/{config-BW35FKuA.js → config-DhT9auRm.js} +1 -1
  10. package/dist/{config-BW35FKuA.js.map → config-DhT9auRm.js.map} +1 -1
  11. package/dist/{constraints-3lV9yyBw.js → constraints-D5RHQLmP.js} +1 -1
  12. package/dist/constraints-D5RHQLmP.js.map +1 -0
  13. package/dist/core/collection.d.ts +86 -0
  14. package/dist/core/collection.d.ts.map +1 -1
  15. package/dist/core/element.d.ts +28 -0
  16. package/dist/core/element.d.ts.map +1 -1
  17. package/dist/core/shared.d.ts +6 -0
  18. package/dist/core/shared.d.ts.map +1 -1
  19. package/dist/core-DdtZHzsS.js +168 -0
  20. package/dist/core-DdtZHzsS.js.map +1 -0
  21. package/dist/{core-Cjl7GUu8.js → core-EMYSLzaT.js} +289 -259
  22. package/dist/core-EMYSLzaT.js.map +1 -0
  23. package/dist/core.es.mjs +48 -47
  24. package/dist/{custom-directives-7wAShnnd.js → custom-directives-Dr4C5lVV.js} +1 -1
  25. package/dist/custom-directives-Dr4C5lVV.js.map +1 -0
  26. package/dist/{devtools-D2fQLhDN.js → devtools-BhB2iDPT.js} +2 -2
  27. package/dist/devtools-BhB2iDPT.js.map +1 -0
  28. package/dist/devtools.es.mjs +1 -1
  29. package/dist/{dnd-B8EgyzaI.js → dnd-NwZBYh4l.js} +1 -1
  30. package/dist/dnd-NwZBYh4l.js.map +1 -0
  31. package/dist/dnd.es.mjs +1 -1
  32. package/dist/{env-NeVmr4Gf.js → env-CTdvLaH2.js} +1 -1
  33. package/dist/env-CTdvLaH2.js.map +1 -0
  34. package/dist/forms/create-form.d.ts.map +1 -1
  35. package/dist/forms/index.d.ts +3 -2
  36. package/dist/forms/index.d.ts.map +1 -1
  37. package/dist/forms/types.d.ts +46 -0
  38. package/dist/forms/types.d.ts.map +1 -1
  39. package/dist/forms/use-field.d.ts +34 -0
  40. package/dist/forms/use-field.d.ts.map +1 -0
  41. package/dist/forms/validators.d.ts +25 -0
  42. package/dist/forms/validators.d.ts.map +1 -1
  43. package/dist/forms-UcRHsYxC.js +227 -0
  44. package/dist/forms-UcRHsYxC.js.map +1 -0
  45. package/dist/forms.es.mjs +14 -12
  46. package/dist/full.d.ts +17 -26
  47. package/dist/full.d.ts.map +1 -1
  48. package/dist/full.es.mjs +206 -181
  49. package/dist/full.iife.js +33 -33
  50. package/dist/full.iife.js.map +1 -1
  51. package/dist/full.umd.js +33 -33
  52. package/dist/full.umd.js.map +1 -1
  53. package/dist/function-Cybd57JV.js +33 -0
  54. package/dist/function-Cybd57JV.js.map +1 -0
  55. package/dist/{i18n-BnnhTFOS.js → i18n-kuF6Ekj6.js} +3 -3
  56. package/dist/i18n-kuF6Ekj6.js.map +1 -0
  57. package/dist/i18n.es.mjs +1 -1
  58. package/dist/index.es.mjs +251 -228
  59. package/dist/media/breakpoints.d.ts.map +1 -1
  60. package/dist/media/types.d.ts +2 -2
  61. package/dist/media/types.d.ts.map +1 -1
  62. package/dist/{media-Di2Ta22s.js → media-i-fB5WxI.js} +3 -3
  63. package/dist/media-i-fB5WxI.js.map +1 -0
  64. package/dist/media.es.mjs +1 -1
  65. package/dist/{motion-qPj_TYGv.js → motion-BJsAuULb.js} +2 -2
  66. package/dist/motion-BJsAuULb.js.map +1 -0
  67. package/dist/motion.es.mjs +1 -1
  68. package/dist/{mount-SM07RUa6.js → mount-B4Y8bk8Z.js} +5 -5
  69. package/dist/mount-B4Y8bk8Z.js.map +1 -0
  70. package/dist/{platform-CPbCprb6.js → platform-Dw2gE3zI.js} +3 -3
  71. package/dist/{platform-CPbCprb6.js.map → platform-Dw2gE3zI.js.map} +1 -1
  72. package/dist/platform.es.mjs +2 -2
  73. package/dist/plugin/registry.d.ts.map +1 -1
  74. package/dist/{plugin-cPoOHFLY.js → plugin-C2WuC8SF.js} +20 -18
  75. package/dist/plugin-C2WuC8SF.js.map +1 -0
  76. package/dist/plugin.es.mjs +1 -1
  77. package/dist/reactive/async-data.d.ts +28 -3
  78. package/dist/reactive/async-data.d.ts.map +1 -1
  79. package/dist/reactive/computed.d.ts +3 -0
  80. package/dist/reactive/computed.d.ts.map +1 -1
  81. package/dist/reactive/effect.d.ts +3 -0
  82. package/dist/reactive/effect.d.ts.map +1 -1
  83. package/dist/reactive/http.d.ts +194 -0
  84. package/dist/reactive/http.d.ts.map +1 -0
  85. package/dist/reactive/index.d.ts +2 -2
  86. package/dist/reactive/index.d.ts.map +1 -1
  87. package/dist/reactive/pagination.d.ts +126 -0
  88. package/dist/reactive/pagination.d.ts.map +1 -0
  89. package/dist/reactive/polling.d.ts +55 -0
  90. package/dist/reactive/polling.d.ts.map +1 -0
  91. package/dist/reactive/readonly.d.ts +20 -1
  92. package/dist/reactive/readonly.d.ts.map +1 -1
  93. package/dist/reactive/rest.d.ts +293 -0
  94. package/dist/reactive/rest.d.ts.map +1 -0
  95. package/dist/reactive/scope.d.ts +140 -0
  96. package/dist/reactive/scope.d.ts.map +1 -0
  97. package/dist/reactive/signal.d.ts +16 -2
  98. package/dist/reactive/signal.d.ts.map +1 -1
  99. package/dist/reactive/to-value.d.ts +57 -0
  100. package/dist/reactive/to-value.d.ts.map +1 -0
  101. package/dist/reactive/websocket.d.ts +285 -0
  102. package/dist/reactive/websocket.d.ts.map +1 -0
  103. package/dist/reactive-DwkhUJfP.js +1148 -0
  104. package/dist/reactive-DwkhUJfP.js.map +1 -0
  105. package/dist/reactive.es.mjs +38 -19
  106. package/dist/{registry-CWf368tT.js → registry-B08iilIh.js} +1 -1
  107. package/dist/{registry-CWf368tT.js.map → registry-B08iilIh.js.map} +1 -1
  108. package/dist/router/constraints.d.ts.map +1 -1
  109. package/dist/router/index.d.ts +1 -1
  110. package/dist/router/index.d.ts.map +1 -1
  111. package/dist/router/router.d.ts.map +1 -1
  112. package/dist/router/state.d.ts +25 -2
  113. package/dist/router/state.d.ts.map +1 -1
  114. package/dist/router-CQikC9Ed.js +492 -0
  115. package/dist/router-CQikC9Ed.js.map +1 -0
  116. package/dist/router.es.mjs +9 -8
  117. package/dist/ssr/hydrate.d.ts.map +1 -1
  118. package/dist/{ssr-B2qd_WBB.js → ssr-_dAcGdzu.js} +4 -4
  119. package/dist/ssr-_dAcGdzu.js.map +1 -0
  120. package/dist/ssr.es.mjs +1 -1
  121. package/dist/store/persisted.d.ts.map +1 -1
  122. package/dist/{store-DWpyH6p5.js → store-Cb3gPRve.js} +7 -7
  123. package/dist/store-Cb3gPRve.js.map +1 -0
  124. package/dist/store.es.mjs +2 -2
  125. package/dist/storybook.es.mjs.map +1 -1
  126. package/dist/{testing-CsqjNUyy.js → testing-C5Sjfsna.js} +8 -8
  127. package/dist/testing-C5Sjfsna.js.map +1 -0
  128. package/dist/testing.es.mjs +1 -1
  129. package/dist/{type-guards-Do9DWgNp.js → type-guards-BMX2c0LP.js} +1 -1
  130. package/dist/{type-guards-Do9DWgNp.js.map → type-guards-BMX2c0LP.js.map} +1 -1
  131. package/dist/untrack-D0fnO5k2.js +36 -0
  132. package/dist/untrack-D0fnO5k2.js.map +1 -0
  133. package/dist/view/custom-directives.d.ts.map +1 -1
  134. package/dist/view.es.mjs +4 -4
  135. package/package.json +178 -177
  136. package/src/a11y/announce.ts +131 -131
  137. package/src/a11y/audit.ts +314 -314
  138. package/src/a11y/index.ts +68 -68
  139. package/src/a11y/media-preferences.ts +255 -255
  140. package/src/a11y/roving-tab-index.ts +164 -164
  141. package/src/a11y/skip-link.ts +255 -255
  142. package/src/a11y/trap-focus.ts +184 -184
  143. package/src/a11y/types.ts +183 -183
  144. package/src/component/component.ts +599 -599
  145. package/src/component/html.ts +153 -153
  146. package/src/component/index.ts +52 -52
  147. package/src/component/library.ts +540 -542
  148. package/src/component/scope.ts +212 -212
  149. package/src/component/types.ts +310 -310
  150. package/src/core/collection.ts +876 -707
  151. package/src/core/element.ts +1015 -981
  152. package/src/core/env.ts +60 -60
  153. package/src/core/index.ts +49 -49
  154. package/src/core/shared.ts +77 -62
  155. package/src/core/utils/index.ts +148 -148
  156. package/src/devtools/devtools.ts +410 -410
  157. package/src/devtools/index.ts +48 -48
  158. package/src/devtools/types.ts +104 -104
  159. package/src/dnd/draggable.ts +296 -296
  160. package/src/dnd/droppable.ts +228 -228
  161. package/src/dnd/index.ts +62 -62
  162. package/src/dnd/sortable.ts +307 -307
  163. package/src/dnd/types.ts +293 -293
  164. package/src/forms/create-form.ts +320 -278
  165. package/src/forms/index.ts +70 -65
  166. package/src/forms/types.ts +203 -154
  167. package/src/forms/use-field.ts +231 -0
  168. package/src/forms/validators.ts +294 -265
  169. package/src/full.ts +554 -480
  170. package/src/i18n/formatting.ts +67 -67
  171. package/src/i18n/i18n.ts +200 -200
  172. package/src/i18n/index.ts +67 -67
  173. package/src/i18n/translate.ts +182 -182
  174. package/src/i18n/types.ts +171 -171
  175. package/src/index.ts +108 -108
  176. package/src/media/battery.ts +116 -116
  177. package/src/media/breakpoints.ts +129 -131
  178. package/src/media/clipboard.ts +80 -80
  179. package/src/media/device-sensors.ts +158 -158
  180. package/src/media/geolocation.ts +119 -119
  181. package/src/media/index.ts +76 -76
  182. package/src/media/media-query.ts +92 -92
  183. package/src/media/network.ts +115 -115
  184. package/src/media/types.ts +177 -177
  185. package/src/media/viewport.ts +84 -84
  186. package/src/motion/index.ts +57 -57
  187. package/src/motion/morph.ts +151 -151
  188. package/src/motion/parallax.ts +120 -120
  189. package/src/motion/reduced-motion.ts +66 -66
  190. package/src/motion/types.ts +271 -271
  191. package/src/motion/typewriter.ts +164 -164
  192. package/src/plugin/index.ts +37 -37
  193. package/src/plugin/registry.ts +284 -269
  194. package/src/plugin/types.ts +137 -137
  195. package/src/reactive/async-data.ts +250 -29
  196. package/src/reactive/computed.ts +144 -130
  197. package/src/reactive/effect.ts +29 -6
  198. package/src/reactive/http.ts +790 -0
  199. package/src/reactive/index.ts +60 -0
  200. package/src/reactive/pagination.ts +317 -0
  201. package/src/reactive/polling.ts +179 -0
  202. package/src/reactive/readonly.ts +52 -8
  203. package/src/reactive/rest.ts +859 -0
  204. package/src/reactive/scope.ts +276 -0
  205. package/src/reactive/signal.ts +61 -1
  206. package/src/reactive/to-value.ts +71 -0
  207. package/src/reactive/websocket.ts +849 -0
  208. package/src/router/bq-link.ts +279 -279
  209. package/src/router/constraints.ts +204 -201
  210. package/src/router/index.ts +49 -49
  211. package/src/router/match.ts +312 -312
  212. package/src/router/path-pattern.ts +52 -52
  213. package/src/router/query.ts +38 -38
  214. package/src/router/router.ts +421 -402
  215. package/src/router/state.ts +51 -3
  216. package/src/router/types.ts +139 -139
  217. package/src/router/use-route.ts +68 -68
  218. package/src/router/utils.ts +157 -157
  219. package/src/security/index.ts +12 -12
  220. package/src/ssr/hydrate.ts +84 -82
  221. package/src/ssr/index.ts +70 -70
  222. package/src/ssr/render.ts +508 -508
  223. package/src/ssr/serialize.ts +296 -296
  224. package/src/ssr/types.ts +81 -81
  225. package/src/store/create-store.ts +467 -467
  226. package/src/store/index.ts +27 -27
  227. package/src/store/persisted.ts +245 -249
  228. package/src/store/types.ts +247 -247
  229. package/src/store/utils.ts +135 -135
  230. package/src/storybook/index.ts +480 -480
  231. package/src/testing/index.ts +42 -42
  232. package/src/testing/testing.ts +593 -593
  233. package/src/testing/types.ts +170 -170
  234. package/src/view/custom-directives.ts +28 -30
  235. package/src/view/evaluate.ts +292 -292
  236. package/src/view/process.ts +108 -108
  237. package/dist/a11y-C5QOVvRn.js.map +0 -1
  238. package/dist/component-CuuTijA6.js.map +0 -1
  239. package/dist/constraints-3lV9yyBw.js.map +0 -1
  240. package/dist/core-Cjl7GUu8.js.map +0 -1
  241. package/dist/core-DnlyjbF2.js +0 -112
  242. package/dist/core-DnlyjbF2.js.map +0 -1
  243. package/dist/custom-directives-7wAShnnd.js.map +0 -1
  244. package/dist/devtools-D2fQLhDN.js.map +0 -1
  245. package/dist/dnd-B8EgyzaI.js.map +0 -1
  246. package/dist/env-NeVmr4Gf.js.map +0 -1
  247. package/dist/forms-C3yovgH9.js +0 -141
  248. package/dist/forms-C3yovgH9.js.map +0 -1
  249. package/dist/i18n-BnnhTFOS.js.map +0 -1
  250. package/dist/media-Di2Ta22s.js.map +0 -1
  251. package/dist/motion-qPj_TYGv.js.map +0 -1
  252. package/dist/mount-SM07RUa6.js.map +0 -1
  253. package/dist/plugin-cPoOHFLY.js.map +0 -1
  254. package/dist/reactive-Cfv0RK6x.js +0 -233
  255. package/dist/reactive-Cfv0RK6x.js.map +0 -1
  256. package/dist/router-BrthaP_z.js +0 -473
  257. package/dist/router-BrthaP_z.js.map +0 -1
  258. package/dist/ssr-B2qd_WBB.js.map +0 -1
  259. package/dist/store-DWpyH6p5.js.map +0 -1
  260. package/dist/testing-CsqjNUyy.js.map +0 -1
  261. package/dist/untrack-DJVQQ2WM.js +0 -33
  262. package/dist/untrack-DJVQQ2WM.js.map +0 -1
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Imperative HTTP client with Axios-like API, interceptors, retry, timeout,
3
+ * cancellation, and progress tracking — built on the native Fetch API.
4
+ *
5
+ * @module bquery/reactive
6
+ */
7
+ import { type BqueryFetchParseAs } from '../platform/config';
8
+ /** Configuration for automatic request retries. */
9
+ export interface RetryConfig {
10
+ /** Maximum number of retry attempts (default: 3). */
11
+ count: number;
12
+ /** Delay in ms between retries, or a function receiving the attempt index. */
13
+ delay?: number | ((attempt: number) => number);
14
+ /** Predicate deciding whether to retry a given error. Defaults to network / 5xx errors. */
15
+ retryOn?: (error: HttpError, attempt: number) => boolean;
16
+ /** Called before each retry attempt with the error and 1-indexed attempt number. */
17
+ onRetry?: (error: HttpError, attempt: number) => void;
18
+ }
19
+ /** Progress information emitted during upload or download. */
20
+ export interface HttpProgressEvent {
21
+ /** Bytes transferred so far. */
22
+ loaded: number;
23
+ /** Total bytes if known, otherwise 0. */
24
+ total: number;
25
+ /** Percentage between 0 and 100, or `undefined` when total is unknown. */
26
+ percent: number | undefined;
27
+ }
28
+ /** Full request configuration accepted by the HTTP client. */
29
+ export interface HttpRequestConfig extends Omit<RequestInit, 'body' | 'headers' | 'signal'> {
30
+ /** Request URL (resolved against `baseUrl`). */
31
+ url?: string;
32
+ /** Base URL prepended to relative request URLs. */
33
+ baseUrl?: string;
34
+ /** Request headers. */
35
+ headers?: HeadersInit;
36
+ /** Query parameters appended to the URL. */
37
+ query?: Record<string, unknown>;
38
+ /** Request body — plain objects/arrays are JSON-serialised automatically. */
39
+ body?: BodyInit | Record<string, unknown> | unknown[] | null;
40
+ /** Request timeout in milliseconds. 0 means no timeout (default). */
41
+ timeout?: number;
42
+ /** Response parsing strategy. */
43
+ parseAs?: BqueryFetchParseAs;
44
+ /** Custom status validation. Returns `true` for acceptable statuses. Default: `status >= 200 && status < 300`. */
45
+ validateStatus?: (status: number) => boolean;
46
+ /** Custom fetch implementation for testing or adapters. */
47
+ fetcher?: typeof fetch;
48
+ /** External `AbortSignal` for request cancellation. */
49
+ signal?: AbortSignal;
50
+ /** Retry configuration. Pass a number for simple retry count, or a `RetryConfig` object. */
51
+ retry?: number | RetryConfig;
52
+ /** Called repeatedly as response body chunks arrive. */
53
+ onDownloadProgress?: (event: HttpProgressEvent) => void;
54
+ }
55
+ /** Structured HTTP response returned by every client method. */
56
+ export interface HttpResponse<T = unknown> {
57
+ /** Parsed response data. */
58
+ data: T;
59
+ /** HTTP status code. */
60
+ status: number;
61
+ /** HTTP status text. */
62
+ statusText: string;
63
+ /** Response headers. */
64
+ headers: Headers;
65
+ /** Resolved request configuration used for this call. */
66
+ config: HttpRequestConfig;
67
+ }
68
+ /** Error subclass thrown on failed HTTP requests with rich metadata. */
69
+ export declare class HttpError extends Error {
70
+ /** HTTP response (available when the server replied). */
71
+ response?: HttpResponse;
72
+ /** Resolved request configuration. */
73
+ config: HttpRequestConfig;
74
+ /** Original error code string (e.g. `'TIMEOUT'`, `'ABORT'`, `'NETWORK'`). */
75
+ code: string;
76
+ constructor(message: string, config: HttpRequestConfig, code: string, response?: HttpResponse);
77
+ }
78
+ /** Single interceptor handler pair. */
79
+ export interface Interceptor<T> {
80
+ fulfilled?: (value: T) => T | Promise<T>;
81
+ rejected?: (error: unknown) => unknown;
82
+ }
83
+ /** Manager for adding and removing interceptors. */
84
+ export interface InterceptorManager<T> {
85
+ /** Register an interceptor. Returns a numeric id for later removal via `eject()`. */
86
+ use(fulfilled?: (value: T) => T | Promise<T>, rejected?: (error: unknown) => unknown): number;
87
+ /** Remove a previously registered interceptor by id. */
88
+ eject(id: number): void;
89
+ /** Remove all interceptors. */
90
+ clear(): void;
91
+ }
92
+ /** Imperative HTTP client with interceptors and convenience method shortcuts. */
93
+ export interface HttpClient {
94
+ /** Send a request using the provided configuration. */
95
+ request<T = unknown>(config: HttpRequestConfig): Promise<HttpResponse<T>>;
96
+ /** Send a GET request. */
97
+ get<T = unknown>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
98
+ /** Send a POST request. */
99
+ post<T = unknown>(url: string, body?: HttpRequestConfig['body'], config?: HttpRequestConfig): Promise<HttpResponse<T>>;
100
+ /** Send a PUT request. */
101
+ put<T = unknown>(url: string, body?: HttpRequestConfig['body'], config?: HttpRequestConfig): Promise<HttpResponse<T>>;
102
+ /** Send a PATCH request. */
103
+ patch<T = unknown>(url: string, body?: HttpRequestConfig['body'], config?: HttpRequestConfig): Promise<HttpResponse<T>>;
104
+ /** Send a DELETE request. */
105
+ delete<T = unknown>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
106
+ /** Send a HEAD request. */
107
+ head<T = unknown>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
108
+ /** Send an OPTIONS request. */
109
+ options<T = unknown>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
110
+ /** Request and response interceptors. */
111
+ interceptors: {
112
+ request: InterceptorManager<HttpRequestConfig>;
113
+ response: InterceptorManager<HttpResponse>;
114
+ };
115
+ /** The merged default configuration used by this client. */
116
+ defaults: HttpRequestConfig;
117
+ }
118
+ /**
119
+ * Create a preconfigured HTTP client instance with interceptors.
120
+ *
121
+ * @param defaults - Default request configuration merged into every request
122
+ * @returns An `HttpClient` with `.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`, `.head()`, `.options()`
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * import { createHttp } from '@bquery/bquery/reactive';
127
+ *
128
+ * const api = createHttp({
129
+ * baseUrl: 'https://api.example.com',
130
+ * headers: { authorization: 'Bearer token' },
131
+ * timeout: 10_000,
132
+ * });
133
+ *
134
+ * api.interceptors.request.use((config) => {
135
+ * config.headers = { ...Object.fromEntries(new Headers(config.headers)), 'x-req-id': crypto.randomUUID() };
136
+ * return config;
137
+ * });
138
+ *
139
+ * const { data } = await api.get<User[]>('/users');
140
+ * ```
141
+ */
142
+ export declare function createHttp(defaults?: HttpRequestConfig): HttpClient;
143
+ /**
144
+ * Default HTTP client instance using global bQuery fetch config.
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * import { http } from '@bquery/bquery/reactive';
149
+ *
150
+ * const { data } = await http.get<User[]>('/api/users');
151
+ * const { data: created } = await http.post('/api/users', { name: 'Ada' });
152
+ * ```
153
+ */
154
+ export declare const http: HttpClient;
155
+ /** Options for `createRequestQueue()`. */
156
+ export interface RequestQueueOptions {
157
+ /** Maximum number of concurrent in-flight requests (default: 6). */
158
+ concurrency?: number;
159
+ }
160
+ /** Return value of `createRequestQueue()`. */
161
+ export interface RequestQueue {
162
+ /** Enqueue a request. Returns a promise that resolves when the request completes. */
163
+ add: <T = unknown>(execute: () => Promise<HttpResponse<T>>) => Promise<HttpResponse<T>>;
164
+ /** Number of requests currently being processed. */
165
+ readonly pending: number;
166
+ /** Number of requests waiting in the queue. */
167
+ readonly size: number;
168
+ /** Remove all pending (not yet started) requests from the queue. Their promises will reject. */
169
+ clear: () => void;
170
+ }
171
+ /**
172
+ * Create a request queue with a concurrency limit.
173
+ *
174
+ * Useful for rate-limiting parallel HTTP requests (e.g. browser connection limits,
175
+ * API throttling) while maintaining a simple promise-based interface.
176
+ *
177
+ * @param options - Queue configuration
178
+ * @returns A `RequestQueue` with `.add()`, `.clear()`, `.pending`, and `.size`
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * import { createRequestQueue, createHttp } from '@bquery/bquery/reactive';
183
+ *
184
+ * const api = createHttp({ baseUrl: 'https://api.example.com' });
185
+ * const queue = createRequestQueue({ concurrency: 3 });
186
+ *
187
+ * // These will run at most 3 at a time
188
+ * const results = await Promise.all(
189
+ * ids.map(id => queue.add(() => api.get(`/items/${id}`)))
190
+ * );
191
+ * ```
192
+ */
193
+ export declare function createRequestQueue(options?: RequestQueueOptions): RequestQueue;
194
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/reactive/http.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,6 @@
3
3
  *
4
4
  * @module bquery/reactive
5
5
  */
6
- export { Computed, Signal, batch, computed, createUseFetch, effect, isComputed, isSignal, linkedSignal, persistedSignal, readonly, signal, useAsyncData, useFetch, untrack, watch, } from './signal';
7
- export type { AsyncDataState, AsyncDataStatus, AsyncWatchSource, CleanupFn, FetchInput, LinkedSignal, Observer, ReadonlySignal, UseAsyncDataOptions, UseFetchOptions, } from './signal';
6
+ export { Computed, Signal, batch, computed, createHttp, createRequestQueue, createRestClient, createUseFetch, deduplicateRequest, effect, effectScope, getCurrentScope, http, HttpError, isComputed, isSignal, linkedSignal, onScopeDispose, persistedSignal, readonly, signal, toValue, useAsyncData, useEventSource, useFetch, useInfiniteFetch, usePaginatedFetch, usePolling, useResource, useResourceList, useSubmit, useWebSocket, useWebSocketChannel, untrack, watch, } from './signal';
7
+ export type { AsyncDataState, AsyncDataStatus, AsyncWatchSource, ChannelMessage, ChannelSubscription, CleanupFn, EffectScope, FetchInput, HttpClient, HttpProgressEvent, HttpRequestConfig, HttpResponse, IdExtractor, InfiniteState, Interceptor, InterceptorManager, LinkedSignal, MaybeSignal, Observer, EventSourceStatus, PaginatedState, PollingState, ReadonlySignal, ReadonlySignalHandle, RequestQueue, RequestQueueOptions, ResourceListActions, RestClient, RetryConfig, UseAsyncDataOptions, UseEventSourceOptions, UseEventSourceReturn, UseFetchOptions, UseFetchRetryConfig, UseInfiniteFetchOptions, UsePaginatedFetchOptions, UsePollingOptions, UseResourceListOptions, UseResourceListReturn, UseResourceOptions, UseResourceReturn, UseSubmitOptions, UseSubmitReturn, UseWebSocketChannelOptions, UseWebSocketChannelReturn, UseWebSocketOptions, UseWebSocketReturn, WebSocketHeartbeatConfig, WebSocketReconnectConfig, WebSocketSerializer, WebSocketStatus, } from './signal';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reactive/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,QAAQ,EACR,MAAM,EACN,KAAK,EACL,QAAQ,EACR,cAAc,EACd,MAAM,EACN,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,KAAK,GACN,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,eAAe,GAChB,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reactive/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,QAAQ,EACR,MAAM,EACN,KAAK,EACL,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,MAAM,EACN,WAAW,EACX,eAAe,EACf,IAAI,EACJ,SAAS,EACT,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,eAAe,EACf,QAAQ,EACR,MAAM,EACN,OAAO,EACP,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,eAAe,EACf,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,OAAO,EACP,KAAK,GACN,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,SAAS,EACT,WAAW,EACX,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,eAAe,GAChB,MAAM,UAAU,CAAC"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Pagination and infinite-scroll composables for reactive data fetching.
3
+ *
4
+ * @module bquery/reactive
5
+ */
6
+ import { Signal } from './core';
7
+ import { type AsyncDataState, type AsyncDataStatus, type UseFetchOptions } from './async-data';
8
+ /** Options for usePaginatedFetch(). */
9
+ export interface UsePaginatedFetchOptions<TResponse = unknown, TData = TResponse> extends UseFetchOptions<TResponse, TData> {
10
+ /** Initial page number (default: 1). */
11
+ initialPage?: number;
12
+ }
13
+ /** Return value of usePaginatedFetch(). */
14
+ export interface PaginatedState<TData> extends AsyncDataState<TData> {
15
+ /** Current page number signal (writable). */
16
+ page: Signal<number>;
17
+ /** Go to the next page. */
18
+ next: () => Promise<TData | undefined>;
19
+ /** Go to the previous page (minimum 1). */
20
+ prev: () => Promise<TData | undefined>;
21
+ /** Jump to a specific page. */
22
+ goTo: (page: number) => Promise<TData | undefined>;
23
+ }
24
+ /**
25
+ * Reactive paginated fetch composable.
26
+ *
27
+ * Takes a URL factory receiving the current page number, and exposes
28
+ * `page`, `next()`, `prev()`, and `goTo()` helpers alongside the
29
+ * standard `AsyncDataState`.
30
+ *
31
+ * @template TResponse - Raw parsed response type
32
+ * @template TData - Stored response type after optional transformation
33
+ * @param inputFactory - Function that receives the page number and returns a URL string, URL, or Request
34
+ * @param options - Fetch and pagination options
35
+ * @returns Paginated data state
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { usePaginatedFetch } from '@bquery/bquery/reactive';
40
+ *
41
+ * const users = usePaginatedFetch<User[]>(
42
+ * (page) => `/api/users?page=${page}`,
43
+ * { baseUrl: 'https://api.example.com' }
44
+ * );
45
+ *
46
+ * // Navigate pages
47
+ * await users.next();
48
+ * await users.prev();
49
+ * await users.goTo(5);
50
+ * console.log(users.page.value); // 5
51
+ * ```
52
+ */
53
+ export declare const usePaginatedFetch: <TResponse = unknown, TData = TResponse>(inputFactory: (page: number) => string | URL | Request, options?: UsePaginatedFetchOptions<TResponse, TData>) => PaginatedState<TData>;
54
+ /** Options for useInfiniteFetch(). */
55
+ export interface UseInfiniteFetchOptions<TResponse = unknown, TData = TResponse, TCursor = number> extends Omit<UseFetchOptions<TResponse, TData>, 'transform'> {
56
+ /** Extract the cursor for the next page from a response. */
57
+ getNextCursor: (lastResponse: TResponse, allPages: TResponse[]) => TCursor | undefined;
58
+ /** Transform all accumulated pages into the final data shape. */
59
+ transform?: (pages: TResponse[]) => TData;
60
+ /** Initial cursor value (default: undefined, meaning first page). */
61
+ initialCursor?: TCursor;
62
+ }
63
+ /** Return value of useInfiniteFetch(). */
64
+ export interface InfiniteState<TData, TResponse = unknown> {
65
+ /** All accumulated page data, transformed. */
66
+ data: Signal<TData | undefined>;
67
+ /** Raw accumulated pages. */
68
+ pages: Signal<TResponse[]>;
69
+ /** Last error encountered. */
70
+ error: Signal<Error | null>;
71
+ /** Current lifecycle status. */
72
+ status: Signal<AsyncDataStatus>;
73
+ /** Computed boolean that mirrors `status === 'pending'`. */
74
+ pending: {
75
+ readonly value: boolean;
76
+ peek(): boolean;
77
+ };
78
+ /** Whether there are more pages to load. */
79
+ hasMore: {
80
+ readonly value: boolean;
81
+ peek(): boolean;
82
+ };
83
+ /** Fetch the next page and append it to the accumulated data. */
84
+ fetchNextPage: () => Promise<TData | undefined>;
85
+ /** Reset all pages and re-fetch from the initial cursor. */
86
+ refresh: () => Promise<TData | undefined>;
87
+ /** Clear all accumulated data. */
88
+ clear: () => void;
89
+ /** Dispose reactive watchers and prevent future executions. */
90
+ dispose: () => void;
91
+ }
92
+ /**
93
+ * Reactive infinite-scroll / load-more composable.
94
+ *
95
+ * Accumulates pages of data and exposes `fetchNextPage()` to load
96
+ * additional results. Uses a cursor-based approach with `getNextCursor()`
97
+ * to determine pagination.
98
+ *
99
+ * @template TResponse - Raw parsed response type for a single page
100
+ * @template TData - Transformed accumulated data type
101
+ * @template TCursor - Cursor type used for pagination
102
+ * @param inputFactory - Function receiving the cursor and returning a FetchInput
103
+ * @param options - Fetch and infinite-scroll options
104
+ * @returns Infinite data state with fetchNextPage(), hasMore, and accumulated pages
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * import { useInfiniteFetch } from '@bquery/bquery/reactive';
109
+ *
110
+ * const feed = useInfiniteFetch<Post[], Post[]>(
111
+ * (cursor) => `/api/posts?cursor=${cursor ?? ''}`,
112
+ * {
113
+ * getNextCursor: (page) => page.length > 0 ? page[page.length - 1].id : undefined,
114
+ * transform: (pages) => pages.flat(),
115
+ * baseUrl: 'https://api.example.com',
116
+ * }
117
+ * );
118
+ *
119
+ * // Load more pages
120
+ * await feed.fetchNextPage();
121
+ * console.log(feed.data.value); // All accumulated posts
122
+ * console.log(feed.hasMore.value); // true if more pages available
123
+ * ```
124
+ */
125
+ export declare const useInfiniteFetch: <TResponse = unknown, TData = TResponse[], TCursor = number>(inputFactory: (cursor: TCursor | undefined) => string | URL | Request, options: UseInfiniteFetchOptions<TResponse, TData, TCursor>) => InfiniteState<TData, TResponse>;
126
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/reactive/pagination.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Reactive polling composable for periodic data fetching.
3
+ *
4
+ * @module bquery/reactive
5
+ */
6
+ import { type AsyncDataState, type FetchInput, type UseFetchOptions } from './async-data';
7
+ /** Options for usePolling(). */
8
+ export interface UsePollingOptions<TResponse = unknown, TData = TResponse> extends UseFetchOptions<TResponse, TData> {
9
+ /** Polling interval in milliseconds. */
10
+ interval: number;
11
+ /** Whether polling is initially enabled (default: true). Can be a reactive getter. */
12
+ enabled?: boolean | (() => boolean);
13
+ /** Pause polling when the document is hidden (default: true). */
14
+ pauseOnHidden?: boolean;
15
+ /** Pause polling when the browser is offline (default: true). */
16
+ pauseOnOffline?: boolean;
17
+ }
18
+ /** Extended return value from usePolling(). */
19
+ export interface PollingState<TData> extends AsyncDataState<TData> {
20
+ /** Pause polling. */
21
+ pause: () => void;
22
+ /** Resume polling. */
23
+ resume: () => void;
24
+ /** Reactive boolean indicating whether polling is currently active. */
25
+ isActive: {
26
+ readonly value: boolean;
27
+ peek(): boolean;
28
+ };
29
+ }
30
+ /**
31
+ * Reactive polling composable that periodically fetches data.
32
+ *
33
+ * @template TResponse - Raw parsed response type
34
+ * @template TData - Stored response type after optional transformation
35
+ * @param input - Request URL, Request object, or lazy input factory
36
+ * @param options - Polling and fetch options
37
+ * @returns Extended fetch state with pause(), resume(), and isActive
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { usePolling } from '@bquery/bquery/reactive';
42
+ *
43
+ * const notifications = usePolling<Notification[]>('/api/notifications', {
44
+ * interval: 30_000,
45
+ * pauseOnHidden: true,
46
+ * pauseOnOffline: true,
47
+ * });
48
+ *
49
+ * // Manually pause/resume
50
+ * notifications.pause();
51
+ * notifications.resume();
52
+ * ```
53
+ */
54
+ export declare const usePolling: <TResponse = unknown, TData = TResponse>(input: FetchInput, options: UsePollingOptions<TResponse, TData>) => PollingState<TData>;
55
+ //# sourceMappingURL=polling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/reactive/polling.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAY,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpG,gCAAgC;AAChC,MAAM,WAAW,iBAAiB,CAAC,SAAS,GAAG,OAAO,EAAE,KAAK,GAAG,SAAS,CAAE,SAAQ,eAAe,CAChG,SAAS,EACT,KAAK,CACN;IACC,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACpC,iEAAiE;IACjE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iEAAiE;IACjE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,+CAA+C;AAC/C,MAAM,WAAW,YAAY,CAAC,KAAK,CAAE,SAAQ,cAAc,CAAC,KAAK,CAAC;IAChE,qBAAqB;IACrB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,sBAAsB;IACtB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,uEAAuE;IACvE,QAAQ,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,IAAI,OAAO,CAAA;KAAE,CAAC;CACxD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,UAAU,GAAI,SAAS,GAAG,OAAO,EAAE,KAAK,GAAG,SAAS,EAC/D,OAAO,UAAU,EACjB,SAAS,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC,KAC3C,YAAY,CAAC,KAAK,CAkHpB,CAAC"}
@@ -2,6 +2,11 @@
2
2
  * Read-only signal wrappers.
3
3
  */
4
4
  import type { Signal } from './core';
5
+ declare const READONLY_SIGNAL_BRAND: unique symbol;
6
+ /** @internal */
7
+ type ReadonlySignalWrapper<T> = ReadonlySignal<T> & {
8
+ readonly [READONLY_SIGNAL_BRAND]: true;
9
+ };
5
10
  /**
6
11
  * A readonly wrapper around a signal that prevents writes.
7
12
  * Provides read-only access to a signal's value while maintaining reactivity.
@@ -14,6 +19,12 @@ export interface ReadonlySignal<T> {
14
19
  /** Gets the current value without dependency tracking. */
15
20
  peek(): T;
16
21
  }
22
+ /**
23
+ * Determines whether a value is a bQuery readonly signal wrapper.
24
+ *
25
+ * @internal
26
+ */
27
+ export declare const isReadonlySignal: <T>(value: unknown) => value is ReturnType<typeof readonly<T>>;
17
28
  /**
18
29
  * Creates a read-only view of a signal.
19
30
  * Useful for exposing reactive state without allowing modifications.
@@ -22,5 +33,13 @@ export interface ReadonlySignal<T> {
22
33
  * @param sig - The signal to wrap
23
34
  * @returns A readonly signal wrapper
24
35
  */
25
- export declare const readonly: <T>(sig: Signal<T>) => ReadonlySignal<T>;
36
+ export declare const readonly: <T>(sig: Signal<T>) => ReadonlySignalWrapper<T>;
37
+ /**
38
+ * Branded readonly wrapper type produced by {@link readonly}.
39
+ *
40
+ * Useful for APIs that compose additional behavior on top of a readonly signal
41
+ * without widening to arbitrary structural `{ value, peek }` objects.
42
+ */
43
+ export type ReadonlySignalHandle<T> = ReturnType<typeof readonly<T>>;
44
+ export {};
26
45
  //# sourceMappingURL=readonly.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"readonly.d.ts","sourceRoot":"","sources":["../../src/reactive/readonly.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,0DAA0D;IAC1D,IAAI,IAAI,CAAC,CAAC;CACX;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,KAAG,cAAc,CAAC,CAAC,CAO3D,CAAC"}
1
+ {"version":3,"file":"readonly.d.ts","sourceRoot":"","sources":["../../src/reactive/readonly.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,QAAA,MAAM,qBAAqB,EAAE,OAAO,MAAwC,CAAC;AAE7E,gBAAgB;AAChB,KAAK,qBAAqB,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,GAAG;IAClD,QAAQ,CAAC,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC;CACxC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,0DAA0D;IAC1D,IAAI,IAAI,CAAC,CAAC;CACX;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,OAAO,OAAO,KAAG,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAM1F,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,KAAG,qBAAqB,CAAC,CAAC,CAuBrC,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC"}