@vielzeug/courier 1.1.4 → 2.0.0

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 (131) hide show
  1. package/README.md +10 -12
  2. package/dist/_dev.cjs +1 -1
  3. package/dist/_dev.cjs.map +1 -1
  4. package/dist/_dev.js +1 -1
  5. package/dist/_dev.js.map +1 -1
  6. package/dist/api.cjs +1 -1
  7. package/dist/api.cjs.map +1 -1
  8. package/dist/api.d.ts +4 -7
  9. package/dist/api.d.ts.map +1 -1
  10. package/dist/api.js +1 -1
  11. package/dist/api.js.map +1 -1
  12. package/dist/courier.cjs +5 -6
  13. package/dist/courier.cjs.map +1 -1
  14. package/dist/courier.d.ts +20 -142
  15. package/dist/courier.d.ts.map +1 -1
  16. package/dist/courier.iife.js +5 -6
  17. package/dist/courier.iife.js.map +1 -1
  18. package/dist/courier.js +5 -6
  19. package/dist/courier.js.map +1 -1
  20. package/dist/devtools.cjs.map +1 -1
  21. package/dist/devtools.d.ts +0 -28
  22. package/dist/devtools.d.ts.map +1 -1
  23. package/dist/devtools.js.map +1 -1
  24. package/dist/errors.cjs +1 -1
  25. package/dist/errors.cjs.map +1 -1
  26. package/dist/errors.d.ts +0 -3
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/errors.js +1 -1
  29. package/dist/errors.js.map +1 -1
  30. package/dist/index.cjs +1 -1
  31. package/dist/index.d.ts +6 -22
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +1 -1
  34. package/dist/interceptors.cjs +1 -1
  35. package/dist/interceptors.cjs.map +1 -1
  36. package/dist/interceptors.js +1 -1
  37. package/dist/interceptors.js.map +1 -1
  38. package/dist/query.cjs +1 -1
  39. package/dist/query.cjs.map +1 -1
  40. package/dist/query.d.ts +8 -101
  41. package/dist/query.d.ts.map +1 -1
  42. package/dist/query.js +1 -1
  43. package/dist/query.js.map +1 -1
  44. package/dist/serialize.cjs +1 -1
  45. package/dist/serialize.cjs.map +1 -1
  46. package/dist/serialize.d.ts +1 -1
  47. package/dist/serialize.d.ts.map +1 -1
  48. package/dist/serialize.js +1 -1
  49. package/dist/serialize.js.map +1 -1
  50. package/dist/stream.cjs +5 -1
  51. package/dist/stream.cjs.map +1 -1
  52. package/dist/stream.d.ts +22 -39
  53. package/dist/stream.d.ts.map +1 -1
  54. package/dist/stream.js +5 -1
  55. package/dist/stream.js.map +1 -1
  56. package/dist/transport.cjs.map +1 -1
  57. package/dist/transport.d.ts +1 -1
  58. package/dist/transport.js.map +1 -1
  59. package/dist/types.d.ts +38 -46
  60. package/dist/types.d.ts.map +1 -1
  61. package/dist/url.cjs.map +1 -1
  62. package/dist/url.d.ts +0 -9
  63. package/dist/url.d.ts.map +1 -1
  64. package/dist/url.js.map +1 -1
  65. package/package.json +4 -4
  66. package/dist/batcher.cjs +0 -2
  67. package/dist/batcher.cjs.map +0 -1
  68. package/dist/batcher.d.ts +0 -66
  69. package/dist/batcher.d.ts.map +0 -1
  70. package/dist/batcher.js +0 -2
  71. package/dist/batcher.js.map +0 -1
  72. package/dist/focus.cjs +0 -2
  73. package/dist/focus.cjs.map +0 -1
  74. package/dist/focus.d.ts +0 -25
  75. package/dist/focus.d.ts.map +0 -1
  76. package/dist/focus.js +0 -2
  77. package/dist/focus.js.map +0 -1
  78. package/dist/mutation.cjs +0 -2
  79. package/dist/mutation.cjs.map +0 -1
  80. package/dist/mutation.d.ts +0 -81
  81. package/dist/mutation.d.ts.map +0 -1
  82. package/dist/mutation.js +0 -2
  83. package/dist/mutation.js.map +0 -1
  84. package/dist/persist.cjs +0 -2
  85. package/dist/persist.cjs.map +0 -1
  86. package/dist/persist.d.ts +0 -86
  87. package/dist/persist.d.ts.map +0 -1
  88. package/dist/persist.js +0 -2
  89. package/dist/persist.js.map +0 -1
  90. package/dist/query-cache.cjs +0 -2
  91. package/dist/query-cache.cjs.map +0 -1
  92. package/dist/query-cache.d.ts +0 -88
  93. package/dist/query-cache.d.ts.map +0 -1
  94. package/dist/query-cache.js +0 -2
  95. package/dist/query-cache.js.map +0 -1
  96. package/dist/query-observe.cjs +0 -2
  97. package/dist/query-observe.cjs.map +0 -1
  98. package/dist/query-observe.d.ts +0 -17
  99. package/dist/query-observe.d.ts.map +0 -1
  100. package/dist/query-observe.js +0 -2
  101. package/dist/query-observe.js.map +0 -1
  102. package/dist/retry.cjs +0 -2
  103. package/dist/retry.cjs.map +0 -1
  104. package/dist/retry.d.ts +0 -34
  105. package/dist/retry.d.ts.map +0 -1
  106. package/dist/retry.js +0 -2
  107. package/dist/retry.js.map +0 -1
  108. package/dist/stream-readable.cjs +0 -3
  109. package/dist/stream-readable.cjs.map +0 -1
  110. package/dist/stream-readable.d.ts +0 -46
  111. package/dist/stream-readable.d.ts.map +0 -1
  112. package/dist/stream-readable.js +0 -3
  113. package/dist/stream-readable.js.map +0 -1
  114. package/dist/stream-shared.cjs +0 -2
  115. package/dist/stream-shared.cjs.map +0 -1
  116. package/dist/stream-shared.d.ts +0 -41
  117. package/dist/stream-shared.d.ts.map +0 -1
  118. package/dist/stream-shared.js +0 -2
  119. package/dist/stream-shared.js.map +0 -1
  120. package/dist/stream-sse.cjs +0 -6
  121. package/dist/stream-sse.cjs.map +0 -1
  122. package/dist/stream-sse.d.ts +0 -59
  123. package/dist/stream-sse.d.ts.map +0 -1
  124. package/dist/stream-sse.js +0 -6
  125. package/dist/stream-sse.js.map +0 -1
  126. package/dist/sync-store.cjs +0 -2
  127. package/dist/sync-store.cjs.map +0 -1
  128. package/dist/sync-store.d.ts +0 -20
  129. package/dist/sync-store.d.ts.map +0 -1
  130. package/dist/sync-store.js +0 -2
  131. package/dist/sync-store.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"devtools.cjs","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["/**\n * @vielzeug/courier — debug utilities for HTTP client visualisation.\n *\n * Import from the dedicated sub-path so it is tree-shaken from production bundles:\n * ```ts\n * import { debugCourier } from '@vielzeug/courier/devtools';\n * ```\n */\n\nimport type { Courier, CourierOptions } from './courier';\n\nimport { createCourier } from './courier';\nimport { withLogging } from './interceptors';\n\n/**\n * Creates a {@link Courier} with request/response logging pre-wired to `console.debug`.\n *\n * Equivalent to `createCourier(options)` with `client.use(withLogging())` already\n * registered, but imported from a dedicated sub-path so the `console.debug` reference\n * is tree-shaken from production bundles when this sub-path is not imported.\n *\n * **Development only.** `withLogging()` logs the full request URL, including any query\n * parameters — if those may contain tokens or PII, use `createCourier()` with a custom\n * `withLogging({ logger })` that sanitizes the URL instead, or none at all in production.\n *\n * @example\n * ```ts\n * import { debugCourier } from '@vielzeug/courier/devtools';\n *\n * const client = debugCourier({ baseUrl: 'https://api.example.com' });\n * await client.api.get('/users');\n * // GET https://api.example.com/users 200 (42ms)\n * ```\n */\nexport function debugCourier(options?: CourierOptions): Courier {\n const client = createCourier(options);\n\n client.use(withLogging());\n\n return client;\n}\n"],"mappings":"oIAkCA,SAAgB,EAAa,EAAmC,CAC9D,IAAM,EAAS,EAAA,cAAc,CAAO,EAIpC,OAFA,EAAO,IAAI,EAAA,YAAY,CAAC,EAEjB,CACT"}
1
+ {"version":3,"file":"devtools.cjs","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["import type { Courier, CourierOptions } from './courier';\n\nimport { createCourier } from './courier';\nimport { withLogging } from './interceptors';\n\nexport function debugCourier(options?: CourierOptions): Courier {\n const client = createCourier(options);\n\n client.use(withLogging());\n\n return client;\n}\n"],"mappings":"oIAKA,SAAgB,EAAa,EAAmC,CAC9D,IAAM,EAAS,EAAA,cAAc,CAAO,EAIpC,OAFA,EAAO,IAAI,EAAA,YAAY,CAAC,EAEjB,CACT"}
@@ -1,31 +1,3 @@
1
- /**
2
- * @vielzeug/courier — debug utilities for HTTP client visualisation.
3
- *
4
- * Import from the dedicated sub-path so it is tree-shaken from production bundles:
5
- * ```ts
6
- * import { debugCourier } from '@vielzeug/courier/devtools';
7
- * ```
8
- */
9
1
  import type { Courier, CourierOptions } from './courier';
10
- /**
11
- * Creates a {@link Courier} with request/response logging pre-wired to `console.debug`.
12
- *
13
- * Equivalent to `createCourier(options)` with `client.use(withLogging())` already
14
- * registered, but imported from a dedicated sub-path so the `console.debug` reference
15
- * is tree-shaken from production bundles when this sub-path is not imported.
16
- *
17
- * **Development only.** `withLogging()` logs the full request URL, including any query
18
- * parameters — if those may contain tokens or PII, use `createCourier()` with a custom
19
- * `withLogging({ logger })` that sanitizes the URL instead, or none at all in production.
20
- *
21
- * @example
22
- * ```ts
23
- * import { debugCourier } from '@vielzeug/courier/devtools';
24
- *
25
- * const client = debugCourier({ baseUrl: 'https://api.example.com' });
26
- * await client.api.get('/users');
27
- * // GET https://api.example.com/users 200 (42ms)
28
- * ```
29
- */
30
2
  export declare function debugCourier(options?: CourierOptions): Courier;
31
3
  //# sourceMappingURL=devtools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKzD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAM9D"}
1
+ {"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKzD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAM9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"devtools.js","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["/**\n * @vielzeug/courier — debug utilities for HTTP client visualisation.\n *\n * Import from the dedicated sub-path so it is tree-shaken from production bundles:\n * ```ts\n * import { debugCourier } from '@vielzeug/courier/devtools';\n * ```\n */\n\nimport type { Courier, CourierOptions } from './courier';\n\nimport { createCourier } from './courier';\nimport { withLogging } from './interceptors';\n\n/**\n * Creates a {@link Courier} with request/response logging pre-wired to `console.debug`.\n *\n * Equivalent to `createCourier(options)` with `client.use(withLogging())` already\n * registered, but imported from a dedicated sub-path so the `console.debug` reference\n * is tree-shaken from production bundles when this sub-path is not imported.\n *\n * **Development only.** `withLogging()` logs the full request URL, including any query\n * parameters — if those may contain tokens or PII, use `createCourier()` with a custom\n * `withLogging({ logger })` that sanitizes the URL instead, or none at all in production.\n *\n * @example\n * ```ts\n * import { debugCourier } from '@vielzeug/courier/devtools';\n *\n * const client = debugCourier({ baseUrl: 'https://api.example.com' });\n * await client.api.get('/users');\n * // GET https://api.example.com/users 200 (42ms)\n * ```\n */\nexport function debugCourier(options?: CourierOptions): Courier {\n const client = createCourier(options);\n\n client.use(withLogging());\n\n return client;\n}\n"],"mappings":"6FAkCA,SAAgB,EAAa,EAAmC,CAC9D,IAAM,EAAS,EAAc,CAAO,EAIpC,OAFA,EAAO,IAAI,EAAY,CAAC,EAEjB,CACT"}
1
+ {"version":3,"file":"devtools.js","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["import type { Courier, CourierOptions } from './courier';\n\nimport { createCourier } from './courier';\nimport { withLogging } from './interceptors';\n\nexport function debugCourier(options?: CourierOptions): Courier {\n const client = createCourier(options);\n\n client.use(withLogging());\n\n return client;\n}\n"],"mappings":"6FAKA,SAAgB,EAAa,EAAmC,CAC9D,IAAM,EAAS,EAAc,CAAO,EAIpC,OAFA,EAAO,IAAI,EAAY,CAAC,EAEjB,CACT"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class t extends e{url;method;status;data;headers;constructor(e){super(e.message),this.url=e.url,this.method=e.method,this.status=e.status,this.data=e.data,this.headers=e.headers}static fromResponse(e,n,r,i){return new t({data:n,headers:e.headers,message:e.statusText||`HTTP ${e.status}`,method:r,status:e.status,url:i})}static is(e,n){return e instanceof t&&(n===void 0||e.status===n)}},n=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},r=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},i=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},a=class extends e{data;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.data=t}},o=class extends e{},s=class extends e{constructor(e){super(`[courier] ${e} disposed`)}},c=class extends e{};function l(e,t,a,o){let s=e instanceof Error?e.message:String(e),c=o?.reason;return c instanceof Error&&c.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):e instanceof DOMException?e.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):new i({cause:e,message:s,method:t,url:a}):e instanceof Error&&e.name===`AbortError`||o?.aborted?new i({cause:e,message:s,method:t,url:a}):new n({cause:e,message:s,method:t,url:a})}exports.CourierAbortError=i,exports.CourierBatcherError=o,exports.CourierDisposedError=s,exports.CourierError=e,exports.CourierHttpError=t,exports.CourierNetworkError=n,exports.CourierParseError=c,exports.CourierSchemaValidationError=a,exports.CourierTimeoutError=r,exports.classifyRequestError=l;
1
+ var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class t extends e{url;method;status;data;headers;constructor(e){super(e.message),this.url=e.url,this.method=e.method,this.status=e.status,this.data=e.data,this.headers=e.headers}static fromResponse(e,n,r,i){return new t({data:n,headers:e.headers,message:e.statusText||`HTTP ${e.status}`,method:r,status:e.status,url:i})}static is(e,n){return e instanceof t&&(n===void 0||e.status===n)}},n=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},r=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},i=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},a=class extends e{data;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.data=t}},o=class extends e{constructor(e){super(`[courier] ${e} disposed`)}},s=class extends e{};function c(e,t,a,o){let s=e instanceof Error?e.message:String(e),c=o?.reason;return c instanceof Error&&c.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):e instanceof DOMException?e.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):new i({cause:e,message:s,method:t,url:a}):e instanceof Error&&e.name===`AbortError`||o?.aborted?new i({cause:e,message:s,method:t,url:a}):new n({cause:e,message:s,method:t,url:a})}exports.CourierAbortError=i,exports.CourierDisposedError=o,exports.CourierError=e,exports.CourierHttpError=t,exports.CourierNetworkError=n,exports.CourierParseError=s,exports.CourierSchemaValidationError=a,exports.CourierTimeoutError=r,exports.classifyRequestError=c;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Base class for all courier errors.\n * Use `instanceof CourierError` to catch any courier-originated error in one branch.\n * Use `HttpError.is(e, status?)` to check for a specific HTTP status code.\n */\nexport class CourierError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is CourierError {\n return err instanceof CourierError;\n }\n}\n\n/**\n * Thrown when the server responds with a non-2xx HTTP status code.\n * Use `HttpError.is(e, status?)` to narrow to a specific status.\n */\nexport class CourierHttpError extends CourierError {\n readonly url: string;\n readonly method: string;\n readonly status: number;\n readonly data: unknown;\n readonly headers: Headers;\n\n constructor(opts: { data: unknown; headers: Headers; message: string; method: string; status: number; url: string }) {\n super(opts.message);\n this.url = opts.url;\n this.method = opts.method;\n this.status = opts.status;\n this.data = opts.data;\n this.headers = opts.headers;\n }\n\n static fromResponse(res: Response, data: unknown, method: string, url: string): CourierHttpError {\n return new CourierHttpError({\n data,\n headers: res.headers,\n message: res.statusText || `HTTP ${res.status}`,\n method,\n status: res.status,\n url,\n });\n }\n\n static is(err: unknown, status?: number): err is CourierHttpError {\n return err instanceof CourierHttpError && (status === undefined || err.status === status);\n }\n}\n\n/**\n * Thrown when a fetch fails due to a network-level error (DNS, TCP, CORS, etc.)\n * with no HTTP response. Distinct from `HttpError` so callers never need to check\n * for a missing `status` field.\n */\nexport class CourierNetworkError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is aborted via `AbortSignal.timeout()` or a caller-supplied\n * timeout option. Distinct from `AbortError` so callers can show retry UI on timeouts\n * without checking any `kind` discriminant.\n */\nexport class CourierTimeoutError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is cancelled via a caller-supplied `AbortSignal` or\n * `cancelAll()` / `dispose()`. Safe to ignore in most UI handlers.\n */\nexport class CourierAbortError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a response body fails schema validation (via the `schema` option).\n * Distinct from the HTTP error classes so callers can separately handle network failures\n * vs. data contract violations without inspecting the error shape.\n */\nexport class CourierSchemaValidationError extends CourierError {\n /** The raw (pre-validation) response body that failed parsing. */\n readonly data: unknown;\n\n constructor(cause: unknown, data: unknown) {\n super(cause instanceof Error ? cause.message : String(cause), { cause });\n this.data = data;\n }\n}\n\n/** Thrown when the batcher's resolve function returns an unexpected number of results. */\nexport class CourierBatcherError extends CourierError {}\n\n/** Thrown when a method is called on a disposed client instance. */\nexport class CourierDisposedError extends CourierError {\n constructor(clientName: string) {\n super(`[courier] ${clientName} disposed`);\n }\n}\n\n/** Thrown when a response body cannot be read or parsed. */\nexport class CourierParseError extends CourierError {}\n\n/**\n * Classify an error thrown by `fetch` or an abort signal into the appropriate\n * courier error class. Signal reason is checked first so a timed-out signal\n * always produces `TimeoutError` even when `fetch` throws a generic Error.\n *\n * We check `.name` rather than `instanceof DOMException` because `AbortSignal.timeout()`\n * sets reason to the *native* Node.js DOMException which may differ from the environment's\n * global DOMException (e.g. jsdom), causing `instanceof` checks to fail cross-realm.\n */\nexport function classifyRequestError(\n cause: unknown,\n method: string,\n url: string,\n signal?: AbortSignal,\n): CourierNetworkError | CourierTimeoutError | CourierAbortError {\n const message = cause instanceof Error ? cause.message : String(cause);\n\n // Signal reason is authoritative — a timed-out signal carries a TimeoutError reason\n // regardless of what error `fetch` actually threw.\n const reason = signal?.reason;\n\n if (reason instanceof Error && reason.name === 'TimeoutError') {\n return new CourierTimeoutError({ cause, message, method, url });\n }\n\n if (cause instanceof DOMException) {\n if (cause.name === 'TimeoutError') return new CourierTimeoutError({ cause, message, method, url });\n\n return new CourierAbortError({ cause, message, method, url });\n }\n\n if ((cause instanceof Error && cause.name === 'AbortError') || signal?.aborted) {\n return new CourierAbortError({ cause, message, method, url });\n }\n\n return new CourierNetworkError({ cause, message, method, url });\n}\n"],"mappings":"AAKA,IAAa,EAAb,MAAa,UAAqB,KAAM,CACtC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,IAAI,OAAO,KACvB,OAAO,eAAe,KAAM,IAAI,OAAO,SAAS,CAClD,CAEA,OAAO,GAAG,EAAmC,CAC3C,OAAO,aAAe,CACxB,CACF,EAMa,EAAb,MAAa,UAAyB,CAAa,CACjD,IACA,OACA,OACA,KACA,QAEA,YAAY,EAAyG,CACnH,MAAM,EAAK,OAAO,EAClB,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,OACnB,KAAK,OAAS,EAAK,OACnB,KAAK,KAAO,EAAK,KACjB,KAAK,QAAU,EAAK,OACtB,CAEA,OAAO,aAAa,EAAe,EAAe,EAAgB,EAA+B,CAC/F,OAAO,IAAI,EAAiB,CAC1B,OACA,QAAS,EAAI,QACb,QAAS,EAAI,YAAc,QAAQ,EAAI,SACvC,SACA,OAAQ,EAAI,OACZ,KACF,CAAC,CACH,CAEA,OAAO,GAAG,EAAc,EAA0C,CAChE,OAAO,aAAe,IAAqB,IAAW,IAAA,IAAa,EAAI,SAAW,EACpF,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAMa,EAAb,cAAuC,CAAa,CAClD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAkD,CAAa,CAE7D,KAEA,YAAY,EAAgB,EAAe,CACzC,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAG,CAAE,OAAM,CAAC,EACvE,KAAK,KAAO,CACd,CACF,EAGa,EAAb,cAAyC,CAAa,CAAC,EAG1C,EAAb,cAA0C,CAAa,CACrD,YAAY,EAAoB,CAC9B,MAAM,aAAa,EAAW,UAAU,CAC1C,CACF,EAGa,EAAb,cAAuC,CAAa,CAAC,EAWrD,SAAgB,EACd,EACA,EACA,EACA,EAC+D,CAC/D,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAI/D,EAAS,GAAQ,OAgBvB,OAdI,aAAkB,OAAS,EAAO,OAAS,eACtC,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAG5D,aAAiB,aACf,EAAM,OAAS,eAAuB,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAE1F,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGzD,aAAiB,OAAS,EAAM,OAAS,cAAiB,GAAQ,QAC9D,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGvD,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,CAChE"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Base class for all courier errors.\n * Use `instanceof CourierError` to catch any courier-originated error in one branch.\n * Use `HttpError.is(e, status?)` to check for a specific HTTP status code.\n */\nexport class CourierError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is CourierError {\n return err instanceof CourierError;\n }\n}\n\n/**\n * Thrown when the server responds with a non-2xx HTTP status code.\n * Use `HttpError.is(e, status?)` to narrow to a specific status.\n */\nexport class CourierHttpError extends CourierError {\n readonly url: string;\n readonly method: string;\n readonly status: number;\n readonly data: unknown;\n readonly headers: Headers;\n\n constructor(opts: { data: unknown; headers: Headers; message: string; method: string; status: number; url: string }) {\n super(opts.message);\n this.url = opts.url;\n this.method = opts.method;\n this.status = opts.status;\n this.data = opts.data;\n this.headers = opts.headers;\n }\n\n static fromResponse(res: Response, data: unknown, method: string, url: string): CourierHttpError {\n return new CourierHttpError({\n data,\n headers: res.headers,\n message: res.statusText || `HTTP ${res.status}`,\n method,\n status: res.status,\n url,\n });\n }\n\n static is(err: unknown, status?: number): err is CourierHttpError {\n return err instanceof CourierHttpError && (status === undefined || err.status === status);\n }\n}\n\n/**\n * Thrown when a fetch fails due to a network-level error (DNS, TCP, CORS, etc.)\n * with no HTTP response. Distinct from `HttpError` so callers never need to check\n * for a missing `status` field.\n */\nexport class CourierNetworkError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is aborted via `AbortSignal.timeout()` or a caller-supplied\n * timeout option. Distinct from `AbortError` so callers can show retry UI on timeouts\n * without checking any `kind` discriminant.\n */\nexport class CourierTimeoutError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is cancelled via a caller-supplied `AbortSignal` or\n * `cancelAll()` / `dispose()`. Safe to ignore in most UI handlers.\n */\nexport class CourierAbortError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a response body fails schema validation (via the `schema` option).\n * Distinct from the HTTP error classes so callers can separately handle network failures\n * vs. data contract violations without inspecting the error shape.\n */\nexport class CourierSchemaValidationError extends CourierError {\n /** The raw (pre-validation) response body that failed parsing. */\n readonly data: unknown;\n\n constructor(cause: unknown, data: unknown) {\n super(cause instanceof Error ? cause.message : String(cause), { cause });\n this.data = data;\n }\n}\n\n/** Thrown when a method is called on a disposed client instance. */\nexport class CourierDisposedError extends CourierError {\n constructor(clientName: string) {\n super(`[courier] ${clientName} disposed`);\n }\n}\n\n/** Thrown when a response body cannot be read or parsed. */\nexport class CourierParseError extends CourierError {}\n\n/**\n * Classify an error thrown by `fetch` or an abort signal into the appropriate\n * courier error class. Signal reason is checked first so a timed-out signal\n * always produces `TimeoutError` even when `fetch` throws a generic Error.\n *\n * We check `.name` rather than `instanceof DOMException` because `AbortSignal.timeout()`\n * sets reason to the *native* Node.js DOMException which may differ from the environment's\n * global DOMException (e.g. jsdom), causing `instanceof` checks to fail cross-realm.\n */\nexport function classifyRequestError(\n cause: unknown,\n method: string,\n url: string,\n signal?: AbortSignal,\n): CourierNetworkError | CourierTimeoutError | CourierAbortError {\n const message = cause instanceof Error ? cause.message : String(cause);\n\n // Signal reason is authoritative — a timed-out signal carries a TimeoutError reason\n // regardless of what error `fetch` actually threw.\n const reason = signal?.reason;\n\n if (reason instanceof Error && reason.name === 'TimeoutError') {\n return new CourierTimeoutError({ cause, message, method, url });\n }\n\n if (cause instanceof DOMException) {\n if (cause.name === 'TimeoutError') return new CourierTimeoutError({ cause, message, method, url });\n\n return new CourierAbortError({ cause, message, method, url });\n }\n\n if ((cause instanceof Error && cause.name === 'AbortError') || signal?.aborted) {\n return new CourierAbortError({ cause, message, method, url });\n }\n\n return new CourierNetworkError({ cause, message, method, url });\n}\n"],"mappings":"AAKA,IAAa,EAAb,MAAa,UAAqB,KAAM,CACtC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAmC,CAC3C,OAAO,aAAe,CACxB,CACF,EAMa,EAAb,MAAa,UAAyB,CAAa,CACjD,IACA,OACA,OACA,KACA,QAEA,YAAY,EAAyG,CACnH,MAAM,EAAK,OAAO,EAClB,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,OACnB,KAAK,OAAS,EAAK,OACnB,KAAK,KAAO,EAAK,KACjB,KAAK,QAAU,EAAK,OACtB,CAEA,OAAO,aAAa,EAAe,EAAe,EAAgB,EAA+B,CAC/F,OAAO,IAAI,EAAiB,CAC1B,OACA,QAAS,EAAI,QACb,QAAS,EAAI,YAAc,QAAQ,EAAI,SACvC,SACA,OAAQ,EAAI,OACZ,KACF,CAAC,CACH,CAEA,OAAO,GAAG,EAAc,EAA0C,CAChE,OAAO,aAAe,IAAqB,IAAW,IAAA,IAAa,EAAI,SAAW,EACpF,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAMa,EAAb,cAAuC,CAAa,CAClD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAkD,CAAa,CAE7D,KAEA,YAAY,EAAgB,EAAe,CACzC,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAG,CAAE,OAAM,CAAC,EACvE,KAAK,KAAO,CACd,CACF,EAGa,EAAb,cAA0C,CAAa,CACrD,YAAY,EAAoB,CAC9B,MAAM,aAAa,EAAW,UAAU,CAC1C,CACF,EAGa,EAAb,cAAuC,CAAa,CAAC,EAWrD,SAAgB,EACd,EACA,EACA,EACA,EAC+D,CAC/D,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAI/D,EAAS,GAAQ,OAgBvB,OAdI,aAAkB,OAAS,EAAO,OAAS,eACtC,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAG5D,aAAiB,aACf,EAAM,OAAS,eAAuB,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAE1F,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGzD,aAAiB,OAAS,EAAM,OAAS,cAAiB,GAAQ,QAC9D,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGvD,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,CAChE"}
package/dist/errors.d.ts CHANGED
@@ -82,9 +82,6 @@ export declare class CourierSchemaValidationError extends CourierError {
82
82
  readonly data: unknown;
83
83
  constructor(cause: unknown, data: unknown);
84
84
  }
85
- /** Thrown when the batcher's resolve function returns an unexpected number of results. */
86
- export declare class CourierBatcherError extends CourierError {
87
- }
88
85
  /** Thrown when a method is called on a disposed client instance. */
89
86
  export declare class CourierDisposedError extends CourierError {
90
87
  constructor(clientName: string);
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;IAMhD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY;CAG7C;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,IAAI,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IASnH,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB;IAWhG,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,IAAI,gBAAgB;CAGlE;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;CAKpF;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;CAKpF;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;CAKpF;AAED;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,YAAY;IAC5D,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBAEX,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO;CAI1C;AAED,0FAA0F;AAC1F,qBAAa,mBAAoB,SAAQ,YAAY;CAAG;AAExD,oEAAoE;AACpE,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,UAAU,EAAE,MAAM;CAG/B;AAED,4DAA4D;AAC5D,qBAAa,iBAAkB,SAAQ,YAAY;CAAG;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,GACnB,mBAAmB,GAAG,mBAAmB,GAAG,iBAAiB,CAsB/D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;IAMhD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY;CAG7C;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,IAAI,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IASnH,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB;IAWhG,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,IAAI,gBAAgB;CAGlE;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;CAKpF;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;CAKpF;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;CAKpF;AAED;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,YAAY;IAC5D,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBAEX,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO;CAI1C;AAED,oEAAoE;AACpE,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,UAAU,EAAE,MAAM;CAG/B;AAED,4DAA4D;AAC5D,qBAAa,iBAAkB,SAAQ,YAAY;CAAG;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,GACnB,mBAAmB,GAAG,mBAAmB,GAAG,iBAAiB,CAsB/D"}
package/dist/errors.js CHANGED
@@ -1,2 +1,2 @@
1
- var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class t extends e{url;method;status;data;headers;constructor(e){super(e.message),this.url=e.url,this.method=e.method,this.status=e.status,this.data=e.data,this.headers=e.headers}static fromResponse(e,n,r,i){return new t({data:n,headers:e.headers,message:e.statusText||`HTTP ${e.status}`,method:r,status:e.status,url:i})}static is(e,n){return e instanceof t&&(n===void 0||e.status===n)}},n=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},r=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},i=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},a=class extends e{data;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.data=t}},o=class extends e{},s=class extends e{constructor(e){super(`[courier] ${e} disposed`)}},c=class extends e{};function l(e,t,a,o){let s=e instanceof Error?e.message:String(e),c=o?.reason;return c instanceof Error&&c.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):e instanceof DOMException?e.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):new i({cause:e,message:s,method:t,url:a}):e instanceof Error&&e.name===`AbortError`||o?.aborted?new i({cause:e,message:s,method:t,url:a}):new n({cause:e,message:s,method:t,url:a})}export{i as CourierAbortError,o as CourierBatcherError,s as CourierDisposedError,e as CourierError,t as CourierHttpError,n as CourierNetworkError,c as CourierParseError,a as CourierSchemaValidationError,r as CourierTimeoutError,l as classifyRequestError};
1
+ var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class t extends e{url;method;status;data;headers;constructor(e){super(e.message),this.url=e.url,this.method=e.method,this.status=e.status,this.data=e.data,this.headers=e.headers}static fromResponse(e,n,r,i){return new t({data:n,headers:e.headers,message:e.statusText||`HTTP ${e.status}`,method:r,status:e.status,url:i})}static is(e,n){return e instanceof t&&(n===void 0||e.status===n)}},n=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},r=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},i=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},a=class extends e{data;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.data=t}},o=class extends e{constructor(e){super(`[courier] ${e} disposed`)}},s=class extends e{};function c(e,t,a,o){let s=e instanceof Error?e.message:String(e),c=o?.reason;return c instanceof Error&&c.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):e instanceof DOMException?e.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):new i({cause:e,message:s,method:t,url:a}):e instanceof Error&&e.name===`AbortError`||o?.aborted?new i({cause:e,message:s,method:t,url:a}):new n({cause:e,message:s,method:t,url:a})}export{i as CourierAbortError,o as CourierDisposedError,e as CourierError,t as CourierHttpError,n as CourierNetworkError,s as CourierParseError,a as CourierSchemaValidationError,r as CourierTimeoutError,c as classifyRequestError};
2
2
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Base class for all courier errors.\n * Use `instanceof CourierError` to catch any courier-originated error in one branch.\n * Use `HttpError.is(e, status?)` to check for a specific HTTP status code.\n */\nexport class CourierError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is CourierError {\n return err instanceof CourierError;\n }\n}\n\n/**\n * Thrown when the server responds with a non-2xx HTTP status code.\n * Use `HttpError.is(e, status?)` to narrow to a specific status.\n */\nexport class CourierHttpError extends CourierError {\n readonly url: string;\n readonly method: string;\n readonly status: number;\n readonly data: unknown;\n readonly headers: Headers;\n\n constructor(opts: { data: unknown; headers: Headers; message: string; method: string; status: number; url: string }) {\n super(opts.message);\n this.url = opts.url;\n this.method = opts.method;\n this.status = opts.status;\n this.data = opts.data;\n this.headers = opts.headers;\n }\n\n static fromResponse(res: Response, data: unknown, method: string, url: string): CourierHttpError {\n return new CourierHttpError({\n data,\n headers: res.headers,\n message: res.statusText || `HTTP ${res.status}`,\n method,\n status: res.status,\n url,\n });\n }\n\n static is(err: unknown, status?: number): err is CourierHttpError {\n return err instanceof CourierHttpError && (status === undefined || err.status === status);\n }\n}\n\n/**\n * Thrown when a fetch fails due to a network-level error (DNS, TCP, CORS, etc.)\n * with no HTTP response. Distinct from `HttpError` so callers never need to check\n * for a missing `status` field.\n */\nexport class CourierNetworkError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is aborted via `AbortSignal.timeout()` or a caller-supplied\n * timeout option. Distinct from `AbortError` so callers can show retry UI on timeouts\n * without checking any `kind` discriminant.\n */\nexport class CourierTimeoutError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is cancelled via a caller-supplied `AbortSignal` or\n * `cancelAll()` / `dispose()`. Safe to ignore in most UI handlers.\n */\nexport class CourierAbortError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a response body fails schema validation (via the `schema` option).\n * Distinct from the HTTP error classes so callers can separately handle network failures\n * vs. data contract violations without inspecting the error shape.\n */\nexport class CourierSchemaValidationError extends CourierError {\n /** The raw (pre-validation) response body that failed parsing. */\n readonly data: unknown;\n\n constructor(cause: unknown, data: unknown) {\n super(cause instanceof Error ? cause.message : String(cause), { cause });\n this.data = data;\n }\n}\n\n/** Thrown when the batcher's resolve function returns an unexpected number of results. */\nexport class CourierBatcherError extends CourierError {}\n\n/** Thrown when a method is called on a disposed client instance. */\nexport class CourierDisposedError extends CourierError {\n constructor(clientName: string) {\n super(`[courier] ${clientName} disposed`);\n }\n}\n\n/** Thrown when a response body cannot be read or parsed. */\nexport class CourierParseError extends CourierError {}\n\n/**\n * Classify an error thrown by `fetch` or an abort signal into the appropriate\n * courier error class. Signal reason is checked first so a timed-out signal\n * always produces `TimeoutError` even when `fetch` throws a generic Error.\n *\n * We check `.name` rather than `instanceof DOMException` because `AbortSignal.timeout()`\n * sets reason to the *native* Node.js DOMException which may differ from the environment's\n * global DOMException (e.g. jsdom), causing `instanceof` checks to fail cross-realm.\n */\nexport function classifyRequestError(\n cause: unknown,\n method: string,\n url: string,\n signal?: AbortSignal,\n): CourierNetworkError | CourierTimeoutError | CourierAbortError {\n const message = cause instanceof Error ? cause.message : String(cause);\n\n // Signal reason is authoritative — a timed-out signal carries a TimeoutError reason\n // regardless of what error `fetch` actually threw.\n const reason = signal?.reason;\n\n if (reason instanceof Error && reason.name === 'TimeoutError') {\n return new CourierTimeoutError({ cause, message, method, url });\n }\n\n if (cause instanceof DOMException) {\n if (cause.name === 'TimeoutError') return new CourierTimeoutError({ cause, message, method, url });\n\n return new CourierAbortError({ cause, message, method, url });\n }\n\n if ((cause instanceof Error && cause.name === 'AbortError') || signal?.aborted) {\n return new CourierAbortError({ cause, message, method, url });\n }\n\n return new CourierNetworkError({ cause, message, method, url });\n}\n"],"mappings":"AAKA,IAAa,EAAb,MAAa,UAAqB,KAAM,CACtC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,IAAI,OAAO,KACvB,OAAO,eAAe,KAAM,IAAI,OAAO,SAAS,CAClD,CAEA,OAAO,GAAG,EAAmC,CAC3C,OAAO,aAAe,CACxB,CACF,EAMa,EAAb,MAAa,UAAyB,CAAa,CACjD,IACA,OACA,OACA,KACA,QAEA,YAAY,EAAyG,CACnH,MAAM,EAAK,OAAO,EAClB,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,OACnB,KAAK,OAAS,EAAK,OACnB,KAAK,KAAO,EAAK,KACjB,KAAK,QAAU,EAAK,OACtB,CAEA,OAAO,aAAa,EAAe,EAAe,EAAgB,EAA+B,CAC/F,OAAO,IAAI,EAAiB,CAC1B,OACA,QAAS,EAAI,QACb,QAAS,EAAI,YAAc,QAAQ,EAAI,SACvC,SACA,OAAQ,EAAI,OACZ,KACF,CAAC,CACH,CAEA,OAAO,GAAG,EAAc,EAA0C,CAChE,OAAO,aAAe,IAAqB,IAAW,IAAA,IAAa,EAAI,SAAW,EACpF,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAMa,EAAb,cAAuC,CAAa,CAClD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAkD,CAAa,CAE7D,KAEA,YAAY,EAAgB,EAAe,CACzC,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAG,CAAE,OAAM,CAAC,EACvE,KAAK,KAAO,CACd,CACF,EAGa,EAAb,cAAyC,CAAa,CAAC,EAG1C,EAAb,cAA0C,CAAa,CACrD,YAAY,EAAoB,CAC9B,MAAM,aAAa,EAAW,UAAU,CAC1C,CACF,EAGa,EAAb,cAAuC,CAAa,CAAC,EAWrD,SAAgB,EACd,EACA,EACA,EACA,EAC+D,CAC/D,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAI/D,EAAS,GAAQ,OAgBvB,OAdI,aAAkB,OAAS,EAAO,OAAS,eACtC,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAG5D,aAAiB,aACf,EAAM,OAAS,eAAuB,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAE1F,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGzD,aAAiB,OAAS,EAAM,OAAS,cAAiB,GAAQ,QAC9D,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGvD,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,CAChE"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Base class for all courier errors.\n * Use `instanceof CourierError` to catch any courier-originated error in one branch.\n * Use `HttpError.is(e, status?)` to check for a specific HTTP status code.\n */\nexport class CourierError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is CourierError {\n return err instanceof CourierError;\n }\n}\n\n/**\n * Thrown when the server responds with a non-2xx HTTP status code.\n * Use `HttpError.is(e, status?)` to narrow to a specific status.\n */\nexport class CourierHttpError extends CourierError {\n readonly url: string;\n readonly method: string;\n readonly status: number;\n readonly data: unknown;\n readonly headers: Headers;\n\n constructor(opts: { data: unknown; headers: Headers; message: string; method: string; status: number; url: string }) {\n super(opts.message);\n this.url = opts.url;\n this.method = opts.method;\n this.status = opts.status;\n this.data = opts.data;\n this.headers = opts.headers;\n }\n\n static fromResponse(res: Response, data: unknown, method: string, url: string): CourierHttpError {\n return new CourierHttpError({\n data,\n headers: res.headers,\n message: res.statusText || `HTTP ${res.status}`,\n method,\n status: res.status,\n url,\n });\n }\n\n static is(err: unknown, status?: number): err is CourierHttpError {\n return err instanceof CourierHttpError && (status === undefined || err.status === status);\n }\n}\n\n/**\n * Thrown when a fetch fails due to a network-level error (DNS, TCP, CORS, etc.)\n * with no HTTP response. Distinct from `HttpError` so callers never need to check\n * for a missing `status` field.\n */\nexport class CourierNetworkError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is aborted via `AbortSignal.timeout()` or a caller-supplied\n * timeout option. Distinct from `AbortError` so callers can show retry UI on timeouts\n * without checking any `kind` discriminant.\n */\nexport class CourierTimeoutError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is cancelled via a caller-supplied `AbortSignal` or\n * `cancelAll()` / `dispose()`. Safe to ignore in most UI handlers.\n */\nexport class CourierAbortError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a response body fails schema validation (via the `schema` option).\n * Distinct from the HTTP error classes so callers can separately handle network failures\n * vs. data contract violations without inspecting the error shape.\n */\nexport class CourierSchemaValidationError extends CourierError {\n /** The raw (pre-validation) response body that failed parsing. */\n readonly data: unknown;\n\n constructor(cause: unknown, data: unknown) {\n super(cause instanceof Error ? cause.message : String(cause), { cause });\n this.data = data;\n }\n}\n\n/** Thrown when a method is called on a disposed client instance. */\nexport class CourierDisposedError extends CourierError {\n constructor(clientName: string) {\n super(`[courier] ${clientName} disposed`);\n }\n}\n\n/** Thrown when a response body cannot be read or parsed. */\nexport class CourierParseError extends CourierError {}\n\n/**\n * Classify an error thrown by `fetch` or an abort signal into the appropriate\n * courier error class. Signal reason is checked first so a timed-out signal\n * always produces `TimeoutError` even when `fetch` throws a generic Error.\n *\n * We check `.name` rather than `instanceof DOMException` because `AbortSignal.timeout()`\n * sets reason to the *native* Node.js DOMException which may differ from the environment's\n * global DOMException (e.g. jsdom), causing `instanceof` checks to fail cross-realm.\n */\nexport function classifyRequestError(\n cause: unknown,\n method: string,\n url: string,\n signal?: AbortSignal,\n): CourierNetworkError | CourierTimeoutError | CourierAbortError {\n const message = cause instanceof Error ? cause.message : String(cause);\n\n // Signal reason is authoritative — a timed-out signal carries a TimeoutError reason\n // regardless of what error `fetch` actually threw.\n const reason = signal?.reason;\n\n if (reason instanceof Error && reason.name === 'TimeoutError') {\n return new CourierTimeoutError({ cause, message, method, url });\n }\n\n if (cause instanceof DOMException) {\n if (cause.name === 'TimeoutError') return new CourierTimeoutError({ cause, message, method, url });\n\n return new CourierAbortError({ cause, message, method, url });\n }\n\n if ((cause instanceof Error && cause.name === 'AbortError') || signal?.aborted) {\n return new CourierAbortError({ cause, message, method, url });\n }\n\n return new CourierNetworkError({ cause, message, method, url });\n}\n"],"mappings":"AAKA,IAAa,EAAb,MAAa,UAAqB,KAAM,CACtC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAmC,CAC3C,OAAO,aAAe,CACxB,CACF,EAMa,EAAb,MAAa,UAAyB,CAAa,CACjD,IACA,OACA,OACA,KACA,QAEA,YAAY,EAAyG,CACnH,MAAM,EAAK,OAAO,EAClB,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,OACnB,KAAK,OAAS,EAAK,OACnB,KAAK,KAAO,EAAK,KACjB,KAAK,QAAU,EAAK,OACtB,CAEA,OAAO,aAAa,EAAe,EAAe,EAAgB,EAA+B,CAC/F,OAAO,IAAI,EAAiB,CAC1B,OACA,QAAS,EAAI,QACb,QAAS,EAAI,YAAc,QAAQ,EAAI,SACvC,SACA,OAAQ,EAAI,OACZ,KACF,CAAC,CACH,CAEA,OAAO,GAAG,EAAc,EAA0C,CAChE,OAAO,aAAe,IAAqB,IAAW,IAAA,IAAa,EAAI,SAAW,EACpF,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAMa,EAAb,cAAuC,CAAa,CAClD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAkD,CAAa,CAE7D,KAEA,YAAY,EAAgB,EAAe,CACzC,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAG,CAAE,OAAM,CAAC,EACvE,KAAK,KAAO,CACd,CACF,EAGa,EAAb,cAA0C,CAAa,CACrD,YAAY,EAAoB,CAC9B,MAAM,aAAa,EAAW,UAAU,CAC1C,CACF,EAGa,EAAb,cAAuC,CAAa,CAAC,EAWrD,SAAgB,EACd,EACA,EACA,EACA,EAC+D,CAC/D,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAI/D,EAAS,GAAQ,OAgBvB,OAdI,aAAkB,OAAS,EAAO,OAAS,eACtC,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAG5D,aAAiB,aACf,EAAM,OAAS,eAAuB,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAE1F,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGzD,aAAiB,OAAS,EAAM,OAAS,cAAiB,GAAQ,QAC9D,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGvD,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,CAChE"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./api.cjs"),n=require("./mutation.cjs"),r=require("./query.cjs"),i=require("./stream.cjs"),a=require("./courier.cjs"),o=require("./interceptors.cjs"),s=require("./batcher.cjs"),c=require("./focus.cjs"),l=require("./persist.cjs"),u=require("./sync-store.cjs");exports.CourierAbortError=e.CourierAbortError,exports.CourierBatcherError=e.CourierBatcherError,exports.CourierDisposedError=e.CourierDisposedError,exports.CourierError=e.CourierError,exports.CourierHttpError=e.CourierHttpError,exports.CourierNetworkError=e.CourierNetworkError,exports.CourierParseError=e.CourierParseError,exports.CourierSchemaValidationError=e.CourierSchemaValidationError,exports.CourierTimeoutError=e.CourierTimeoutError,exports.bindRefetch=c.bindRefetch,exports.createApi=t.createApi,exports.createBatcher=s.createBatcher,exports.createCourier=a.createCourier,exports.createMutation=n.createMutation,exports.createQuery=r.createQuery,exports.createStream=i.createStream,exports.hydrateQueryCache=l.hydrateQueryCache,exports.persistQueryCache=l.persistQueryCache,exports.toSyncStore=u.toSyncStore,exports.withBearerAuth=o.withBearerAuth,exports.withLogging=o.withLogging,exports.withRequestId=o.withRequestId;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./courier.cjs"),n=require("./interceptors.cjs");exports.CourierAbortError=e.CourierAbortError,exports.CourierDisposedError=e.CourierDisposedError,exports.CourierError=e.CourierError,exports.CourierHttpError=e.CourierHttpError,exports.CourierNetworkError=e.CourierNetworkError,exports.CourierParseError=e.CourierParseError,exports.CourierSchemaValidationError=e.CourierSchemaValidationError,exports.CourierTimeoutError=e.CourierTimeoutError,exports.createCourier=t.createCourier,exports.withBearerAuth=n.withBearerAuth,exports.withLogging=n.withLogging,exports.withRequestId=n.withRequestId;
package/dist/index.d.ts CHANGED
@@ -1,24 +1,8 @@
1
- export { createApi } from './api';
2
- export type { ApiClient, FetchContext, Interceptor } from './api';
3
- export { createBatcher } from './batcher';
4
- export type { Batcher, BatcherOptions } from './batcher';
5
- export { createCourier } from './courier';
6
- export type { Courier, CourierMutationOptions, CourierOptions } from './courier';
7
- export { CourierAbortError, CourierBatcherError, CourierDisposedError, CourierError, CourierHttpError, CourierNetworkError, CourierParseError, CourierSchemaValidationError, CourierTimeoutError, } from './errors';
8
- export { bindRefetch } from './focus';
1
+ export { createCourier, type Courier, type CourierOptions } from './courier';
2
+ export { CourierAbortError, CourierDisposedError, CourierError, CourierHttpError, CourierNetworkError, CourierParseError, CourierSchemaValidationError, CourierTimeoutError, } from './errors';
9
3
  export { withBearerAuth, withLogging, withRequestId } from './interceptors';
10
- export { createMutation } from './mutation';
11
- export type { Mutation, MutationFn, MutationOptions, SettledResult } from './mutation';
12
- export { hydrateQueryCache, persistQueryCache } from './persist';
13
- export type { PersistOptions, PersistStorage } from './persist';
14
- export { createQuery } from './query';
15
- export type { ObserveOptions, QueryClient, QueryClientOptions, QueryFn, QueryFnContext, QueryOptions } from './query';
16
- export { toSyncStore } from './sync-store';
17
- export type { ResponseType } from './response';
18
- export type { RetryOptions } from './retry';
19
- export { createStream } from './stream';
20
- export type { ReadableConfig, ReconnectOptions, SseOptions, SseSource, SseStatus, StreamClient, StreamRequestConfig, } from './stream';
21
- export type { TransportOptions } from './transport';
22
- export type { AsyncState, AsyncStatus, MutationState, QueryKey, QueryKeyAtom, QueryState, SyncStore, Unsubscribe, } from './types';
23
- export type { CourierRequestConfig as RequestConfig, HttpRequestConfig, Params } from './url';
4
+ export type { FetchContext, Interceptor, TransportOptions } from './transport';
5
+ export type { HttpRequestConfig as RequestConfig, Params } from './url';
6
+ export type { AsyncState, MutationContext, MutationOptions, QueryCache, QueryContext, QueryDefinition, QueryKey, QueryKeyAtom, Unsubscribe, } from './types';
7
+ export type { StreamEvent, StreamOptions } from './stream';
24
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGzD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGjF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,4BAA4B,EAC5B,mBAAmB,GACpB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG5E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGvF,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACjE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGtH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,GACpB,MAAM,UAAU,CAAC;AAGlB,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,YAAY,EACV,UAAU,EACV,WAAW,EACX,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,YAAY,EAAE,oBAAoB,IAAI,aAAa,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,4BAA4B,EAC5B,mBAAmB,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/E,YAAY,EAAE,iBAAiB,IAAI,aAAa,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACxE,YAAY,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,UAAU,EACV,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{CourierAbortError as e,CourierBatcherError as t,CourierDisposedError as n,CourierError as r,CourierHttpError as i,CourierNetworkError as a,CourierParseError as o,CourierSchemaValidationError as s,CourierTimeoutError as c}from"./errors.js";import{createApi as l}from"./api.js";import{createMutation as u}from"./mutation.js";import{createQuery as d}from"./query.js";import{createStream as f}from"./stream.js";import{createCourier as p}from"./courier.js";import{withBearerAuth as m,withLogging as h,withRequestId as g}from"./interceptors.js";import{createBatcher as _}from"./batcher.js";import{bindRefetch as v}from"./focus.js";import{hydrateQueryCache as y,persistQueryCache as b}from"./persist.js";import{toSyncStore as x}from"./sync-store.js";export{e as CourierAbortError,t as CourierBatcherError,n as CourierDisposedError,r as CourierError,i as CourierHttpError,a as CourierNetworkError,o as CourierParseError,s as CourierSchemaValidationError,c as CourierTimeoutError,v as bindRefetch,l as createApi,_ as createBatcher,p as createCourier,u as createMutation,d as createQuery,f as createStream,y as hydrateQueryCache,b as persistQueryCache,x as toSyncStore,m as withBearerAuth,h as withLogging,g as withRequestId};
1
+ import{CourierAbortError as e,CourierDisposedError as t,CourierError as n,CourierHttpError as r,CourierNetworkError as i,CourierParseError as a,CourierSchemaValidationError as o,CourierTimeoutError as s}from"./errors.js";import{createCourier as c}from"./courier.js";import{withBearerAuth as l,withLogging as u,withRequestId as d}from"./interceptors.js";export{e as CourierAbortError,t as CourierDisposedError,n as CourierError,r as CourierHttpError,i as CourierNetworkError,a as CourierParseError,o as CourierSchemaValidationError,s as CourierTimeoutError,c as createCourier,l as withBearerAuth,u as withLogging,d as withRequestId};
@@ -1,2 +1,2 @@
1
- let e=require("@vielzeug/arsenal");function t(e){return async(t,n)=>{let r=typeof e==`function`?await e():e;return n(t.withHeaders({authorization:`Bearer ${r}`}))}}function n(t){let n=t?.header??`x-request-id`,r=t?.generate??e.uuid;return(e,t)=>t(e.withHeaders({[n]:r()}))}function r(e){let t=e?.logger??((e,t)=>{console.debug(e,t)});return async(e,n)=>{let r=performance.now(),i=(e.init.method??`GET`).toUpperCase();try{let a=await n(e),o=Math.round(performance.now()-r);return t(`${i} ${e.url} ${a.status} (${o}ms)`,{duration:o,method:i,status:a.status,url:e.url}),a}catch(n){let a=Math.round(performance.now()-r);throw t(`${i} ${e.url} ERR (${a}ms)`,{duration:a,method:i,status:0,url:e.url}),n}}}exports.withBearerAuth=t,exports.withLogging=r,exports.withRequestId=n;
1
+ let e=require("@vielzeug/arsenal/random");function t(e){return async(t,n)=>{let r=typeof e==`function`?await e():e;return n(t.withHeaders({authorization:`Bearer ${r}`}))}}function n(t){let n=t?.header??`x-request-id`,r=t?.generate??e.uuid;return(e,t)=>t(e.withHeaders({[n]:r()}))}function r(e){let t=e?.logger??((e,t)=>{console.debug(e,t)});return async(e,n)=>{let r=performance.now(),i=(e.init.method??`GET`).toUpperCase();try{let a=await n(e),o=Math.round(performance.now()-r);return t(`${i} ${e.url} ${a.status} (${o}ms)`,{duration:o,method:i,status:a.status,url:e.url}),a}catch(n){let a=Math.round(performance.now()-r);throw t(`${i} ${e.url} ERR (${a}ms)`,{duration:a,method:i,status:0,url:e.url}),n}}}exports.withBearerAuth=t,exports.withLogging=r,exports.withRequestId=n;
2
2
  //# sourceMappingURL=interceptors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"interceptors.cjs","names":[],"sources":["../src/interceptors.ts"],"sourcesContent":["import { uuid } from '@vielzeug/arsenal';\n\nimport type { Interceptor } from './transport';\n\n/**\n * Attaches a Bearer token `Authorization` header to every request.\n * The token can be a static string or an async function (useful for refresh flows).\n *\n * @example\n * ```ts\n * client.use(withBearerAuth(() => tokenStore.getAccessToken()));\n * ```\n */\nexport function withBearerAuth(token: string | (() => string | Promise<string>)): Interceptor {\n return async (ctx, next) => {\n const t = typeof token === 'function' ? await token() : token;\n\n return next(ctx.withHeaders({ authorization: `Bearer ${t}` }));\n };\n}\n\n/**\n * Adds a unique request ID to every request as a header.\n *\n * Defaults to `x-request-id` populated with `crypto.randomUUID()`.\n *\n * @example\n * ```ts\n * client.use(withRequestId());\n * client.use(withRequestId({ header: 'x-trace-id' }));\n * ```\n */\nexport function withRequestId(opts?: { generate?: () => string; header?: string }): Interceptor {\n const header = opts?.header ?? 'x-request-id';\n const generate = opts?.generate ?? uuid;\n\n return (ctx, next) => next(ctx.withHeaders({ [header]: generate() }));\n}\n\n/**\n * Logs each request's method, URL, status code, and duration.\n *\n * Defaults to `console.debug`. Supply a custom `logger` for structured logging.\n *\n * **Security note:** The full URL is logged, including any query parameters.\n * If your URLs may contain sensitive data (tokens, PII), provide a custom\n * `logger` that sanitizes the URL before writing to persistent logs.\n *\n * @example\n * ```ts\n * client.use(withLogging());\n * client.use(withLogging({ logger: (msg, meta) => logger.info(meta) }));\n * ```\n */\nexport function withLogging(opts?: {\n logger?: (msg: string, meta: { duration: number; method: string; status: number; url: string }) => void;\n}): Interceptor {\n const log =\n opts?.logger ??\n ((msg, meta) => {\n console.debug(msg, meta);\n });\n\n return async (ctx, next) => {\n const start = performance.now();\n const method = ((ctx.init as RequestInit).method ?? 'GET').toUpperCase();\n\n try {\n const res = await next(ctx);\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ${res.status} (${duration}ms)`, {\n duration,\n method,\n status: res.status,\n url: ctx.url,\n });\n\n return res;\n } catch (err) {\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ERR (${duration}ms)`, {\n duration,\n method,\n status: 0,\n url: ctx.url,\n });\n\n throw err;\n }\n };\n}\n"],"mappings":"mCAaA,SAAgB,EAAe,EAA+D,CAC5F,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAI,OAAO,GAAU,WAAa,MAAM,EAAM,EAAI,EAExD,OAAO,EAAK,EAAI,YAAY,CAAE,cAAe,UAAU,GAAI,CAAC,CAAC,CAC/D,CACF,CAaA,SAAgB,EAAc,EAAkE,CAC9F,IAAM,EAAS,GAAM,QAAU,eACzB,EAAW,GAAM,UAAY,EAAA,KAEnC,OAAQ,EAAK,IAAS,EAAK,EAAI,YAAY,EAAG,GAAS,EAAS,CAAE,CAAC,CAAC,CACtE,CAiBA,SAAgB,EAAY,EAEZ,CACd,IAAM,EACJ,GAAM,UACJ,EAAK,IAAS,CACd,QAAQ,MAAM,EAAK,CAAI,CACzB,GAEF,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAQ,YAAY,IAAI,EACxB,GAAW,EAAI,KAAqB,QAAU,MAAA,CAAO,YAAY,EAEvE,GAAI,CACF,IAAM,EAAM,MAAM,EAAK,CAAG,EACpB,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,OAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,GAAG,EAAI,OAAO,IAAI,EAAS,KAAM,CACxD,WACA,SACA,OAAQ,EAAI,OACZ,IAAK,EAAI,GACX,CAAC,EAEM,CACT,OAAS,EAAK,CACZ,IAAM,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,MAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,QAAQ,EAAS,KAAM,CAC9C,WACA,SACA,OAAQ,EACR,IAAK,EAAI,GACX,CAAC,EAEK,CACR,CACF,CACF"}
1
+ {"version":3,"file":"interceptors.cjs","names":[],"sources":["../src/interceptors.ts"],"sourcesContent":["import { uuid } from '@vielzeug/arsenal/random';\n\nimport type { Interceptor } from './transport';\n\n/**\n * Attaches a Bearer token `Authorization` header to every request.\n * The token can be a static string or an async function (useful for refresh flows).\n *\n * @example\n * ```ts\n * client.use(withBearerAuth(() => tokenStore.getAccessToken()));\n * ```\n */\nexport function withBearerAuth(token: string | (() => string | Promise<string>)): Interceptor {\n return async (ctx, next) => {\n const t = typeof token === 'function' ? await token() : token;\n\n return next(ctx.withHeaders({ authorization: `Bearer ${t}` }));\n };\n}\n\n/**\n * Adds a unique request ID to every request as a header.\n *\n * Defaults to `x-request-id` populated with `crypto.randomUUID()`.\n *\n * @example\n * ```ts\n * client.use(withRequestId());\n * client.use(withRequestId({ header: 'x-trace-id' }));\n * ```\n */\nexport function withRequestId(opts?: { generate?: () => string; header?: string }): Interceptor {\n const header = opts?.header ?? 'x-request-id';\n const generate = opts?.generate ?? uuid;\n\n return (ctx, next) => next(ctx.withHeaders({ [header]: generate() }));\n}\n\n/**\n * Logs each request's method, URL, status code, and duration.\n *\n * Defaults to `console.debug`. Supply a custom `logger` for structured logging.\n *\n * **Security note:** The full URL is logged, including any query parameters.\n * If your URLs may contain sensitive data (tokens, PII), provide a custom\n * `logger` that sanitizes the URL before writing to persistent logs.\n *\n * @example\n * ```ts\n * client.use(withLogging());\n * client.use(withLogging({ logger: (msg, meta) => logger.info(meta) }));\n * ```\n */\nexport function withLogging(opts?: {\n logger?: (msg: string, meta: { duration: number; method: string; status: number; url: string }) => void;\n}): Interceptor {\n const log =\n opts?.logger ??\n ((msg, meta) => {\n console.debug(msg, meta);\n });\n\n return async (ctx, next) => {\n const start = performance.now();\n const method = ((ctx.init as RequestInit).method ?? 'GET').toUpperCase();\n\n try {\n const res = await next(ctx);\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ${res.status} (${duration}ms)`, {\n duration,\n method,\n status: res.status,\n url: ctx.url,\n });\n\n return res;\n } catch (err) {\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ERR (${duration}ms)`, {\n duration,\n method,\n status: 0,\n url: ctx.url,\n });\n\n throw err;\n }\n };\n}\n"],"mappings":"0CAaA,SAAgB,EAAe,EAA+D,CAC5F,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAI,OAAO,GAAU,WAAa,MAAM,EAAM,EAAI,EAExD,OAAO,EAAK,EAAI,YAAY,CAAE,cAAe,UAAU,GAAI,CAAC,CAAC,CAC/D,CACF,CAaA,SAAgB,EAAc,EAAkE,CAC9F,IAAM,EAAS,GAAM,QAAU,eACzB,EAAW,GAAM,UAAY,EAAA,KAEnC,OAAQ,EAAK,IAAS,EAAK,EAAI,YAAY,EAAG,GAAS,EAAS,CAAE,CAAC,CAAC,CACtE,CAiBA,SAAgB,EAAY,EAEZ,CACd,IAAM,EACJ,GAAM,UACJ,EAAK,IAAS,CACd,QAAQ,MAAM,EAAK,CAAI,CACzB,GAEF,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAQ,YAAY,IAAI,EACxB,GAAW,EAAI,KAAqB,QAAU,MAAA,CAAO,YAAY,EAEvE,GAAI,CACF,IAAM,EAAM,MAAM,EAAK,CAAG,EACpB,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,OAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,GAAG,EAAI,OAAO,IAAI,EAAS,KAAM,CACxD,WACA,SACA,OAAQ,EAAI,OACZ,IAAK,EAAI,GACX,CAAC,EAEM,CACT,OAAS,EAAK,CACZ,IAAM,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,MAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,QAAQ,EAAS,KAAM,CAC9C,WACA,SACA,OAAQ,EACR,IAAK,EAAI,GACX,CAAC,EAEK,CACR,CACF,CACF"}
@@ -1,2 +1,2 @@
1
- import{uuid as e}from"@vielzeug/arsenal";function t(e){return async(t,n)=>{let r=typeof e==`function`?await e():e;return n(t.withHeaders({authorization:`Bearer ${r}`}))}}function n(t){let n=t?.header??`x-request-id`,r=t?.generate??e;return(e,t)=>t(e.withHeaders({[n]:r()}))}function r(e){let t=e?.logger??((e,t)=>{console.debug(e,t)});return async(e,n)=>{let r=performance.now(),i=(e.init.method??`GET`).toUpperCase();try{let a=await n(e),o=Math.round(performance.now()-r);return t(`${i} ${e.url} ${a.status} (${o}ms)`,{duration:o,method:i,status:a.status,url:e.url}),a}catch(n){let a=Math.round(performance.now()-r);throw t(`${i} ${e.url} ERR (${a}ms)`,{duration:a,method:i,status:0,url:e.url}),n}}}export{t as withBearerAuth,r as withLogging,n as withRequestId};
1
+ import{uuid as e}from"@vielzeug/arsenal/random";function t(e){return async(t,n)=>{let r=typeof e==`function`?await e():e;return n(t.withHeaders({authorization:`Bearer ${r}`}))}}function n(t){let n=t?.header??`x-request-id`,r=t?.generate??e;return(e,t)=>t(e.withHeaders({[n]:r()}))}function r(e){let t=e?.logger??((e,t)=>{console.debug(e,t)});return async(e,n)=>{let r=performance.now(),i=(e.init.method??`GET`).toUpperCase();try{let a=await n(e),o=Math.round(performance.now()-r);return t(`${i} ${e.url} ${a.status} (${o}ms)`,{duration:o,method:i,status:a.status,url:e.url}),a}catch(n){let a=Math.round(performance.now()-r);throw t(`${i} ${e.url} ERR (${a}ms)`,{duration:a,method:i,status:0,url:e.url}),n}}}export{t as withBearerAuth,r as withLogging,n as withRequestId};
2
2
  //# sourceMappingURL=interceptors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interceptors.js","names":[],"sources":["../src/interceptors.ts"],"sourcesContent":["import { uuid } from '@vielzeug/arsenal';\n\nimport type { Interceptor } from './transport';\n\n/**\n * Attaches a Bearer token `Authorization` header to every request.\n * The token can be a static string or an async function (useful for refresh flows).\n *\n * @example\n * ```ts\n * client.use(withBearerAuth(() => tokenStore.getAccessToken()));\n * ```\n */\nexport function withBearerAuth(token: string | (() => string | Promise<string>)): Interceptor {\n return async (ctx, next) => {\n const t = typeof token === 'function' ? await token() : token;\n\n return next(ctx.withHeaders({ authorization: `Bearer ${t}` }));\n };\n}\n\n/**\n * Adds a unique request ID to every request as a header.\n *\n * Defaults to `x-request-id` populated with `crypto.randomUUID()`.\n *\n * @example\n * ```ts\n * client.use(withRequestId());\n * client.use(withRequestId({ header: 'x-trace-id' }));\n * ```\n */\nexport function withRequestId(opts?: { generate?: () => string; header?: string }): Interceptor {\n const header = opts?.header ?? 'x-request-id';\n const generate = opts?.generate ?? uuid;\n\n return (ctx, next) => next(ctx.withHeaders({ [header]: generate() }));\n}\n\n/**\n * Logs each request's method, URL, status code, and duration.\n *\n * Defaults to `console.debug`. Supply a custom `logger` for structured logging.\n *\n * **Security note:** The full URL is logged, including any query parameters.\n * If your URLs may contain sensitive data (tokens, PII), provide a custom\n * `logger` that sanitizes the URL before writing to persistent logs.\n *\n * @example\n * ```ts\n * client.use(withLogging());\n * client.use(withLogging({ logger: (msg, meta) => logger.info(meta) }));\n * ```\n */\nexport function withLogging(opts?: {\n logger?: (msg: string, meta: { duration: number; method: string; status: number; url: string }) => void;\n}): Interceptor {\n const log =\n opts?.logger ??\n ((msg, meta) => {\n console.debug(msg, meta);\n });\n\n return async (ctx, next) => {\n const start = performance.now();\n const method = ((ctx.init as RequestInit).method ?? 'GET').toUpperCase();\n\n try {\n const res = await next(ctx);\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ${res.status} (${duration}ms)`, {\n duration,\n method,\n status: res.status,\n url: ctx.url,\n });\n\n return res;\n } catch (err) {\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ERR (${duration}ms)`, {\n duration,\n method,\n status: 0,\n url: ctx.url,\n });\n\n throw err;\n }\n };\n}\n"],"mappings":"yCAaA,SAAgB,EAAe,EAA+D,CAC5F,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAI,OAAO,GAAU,WAAa,MAAM,EAAM,EAAI,EAExD,OAAO,EAAK,EAAI,YAAY,CAAE,cAAe,UAAU,GAAI,CAAC,CAAC,CAC/D,CACF,CAaA,SAAgB,EAAc,EAAkE,CAC9F,IAAM,EAAS,GAAM,QAAU,eACzB,EAAW,GAAM,UAAY,EAEnC,OAAQ,EAAK,IAAS,EAAK,EAAI,YAAY,EAAG,GAAS,EAAS,CAAE,CAAC,CAAC,CACtE,CAiBA,SAAgB,EAAY,EAEZ,CACd,IAAM,EACJ,GAAM,UACJ,EAAK,IAAS,CACd,QAAQ,MAAM,EAAK,CAAI,CACzB,GAEF,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAQ,YAAY,IAAI,EACxB,GAAW,EAAI,KAAqB,QAAU,MAAA,CAAO,YAAY,EAEvE,GAAI,CACF,IAAM,EAAM,MAAM,EAAK,CAAG,EACpB,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,OAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,GAAG,EAAI,OAAO,IAAI,EAAS,KAAM,CACxD,WACA,SACA,OAAQ,EAAI,OACZ,IAAK,EAAI,GACX,CAAC,EAEM,CACT,OAAS,EAAK,CACZ,IAAM,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,MAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,QAAQ,EAAS,KAAM,CAC9C,WACA,SACA,OAAQ,EACR,IAAK,EAAI,GACX,CAAC,EAEK,CACR,CACF,CACF"}
1
+ {"version":3,"file":"interceptors.js","names":[],"sources":["../src/interceptors.ts"],"sourcesContent":["import { uuid } from '@vielzeug/arsenal/random';\n\nimport type { Interceptor } from './transport';\n\n/**\n * Attaches a Bearer token `Authorization` header to every request.\n * The token can be a static string or an async function (useful for refresh flows).\n *\n * @example\n * ```ts\n * client.use(withBearerAuth(() => tokenStore.getAccessToken()));\n * ```\n */\nexport function withBearerAuth(token: string | (() => string | Promise<string>)): Interceptor {\n return async (ctx, next) => {\n const t = typeof token === 'function' ? await token() : token;\n\n return next(ctx.withHeaders({ authorization: `Bearer ${t}` }));\n };\n}\n\n/**\n * Adds a unique request ID to every request as a header.\n *\n * Defaults to `x-request-id` populated with `crypto.randomUUID()`.\n *\n * @example\n * ```ts\n * client.use(withRequestId());\n * client.use(withRequestId({ header: 'x-trace-id' }));\n * ```\n */\nexport function withRequestId(opts?: { generate?: () => string; header?: string }): Interceptor {\n const header = opts?.header ?? 'x-request-id';\n const generate = opts?.generate ?? uuid;\n\n return (ctx, next) => next(ctx.withHeaders({ [header]: generate() }));\n}\n\n/**\n * Logs each request's method, URL, status code, and duration.\n *\n * Defaults to `console.debug`. Supply a custom `logger` for structured logging.\n *\n * **Security note:** The full URL is logged, including any query parameters.\n * If your URLs may contain sensitive data (tokens, PII), provide a custom\n * `logger` that sanitizes the URL before writing to persistent logs.\n *\n * @example\n * ```ts\n * client.use(withLogging());\n * client.use(withLogging({ logger: (msg, meta) => logger.info(meta) }));\n * ```\n */\nexport function withLogging(opts?: {\n logger?: (msg: string, meta: { duration: number; method: string; status: number; url: string }) => void;\n}): Interceptor {\n const log =\n opts?.logger ??\n ((msg, meta) => {\n console.debug(msg, meta);\n });\n\n return async (ctx, next) => {\n const start = performance.now();\n const method = ((ctx.init as RequestInit).method ?? 'GET').toUpperCase();\n\n try {\n const res = await next(ctx);\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ${res.status} (${duration}ms)`, {\n duration,\n method,\n status: res.status,\n url: ctx.url,\n });\n\n return res;\n } catch (err) {\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ERR (${duration}ms)`, {\n duration,\n method,\n status: 0,\n url: ctx.url,\n });\n\n throw err;\n }\n };\n}\n"],"mappings":"gDAaA,SAAgB,EAAe,EAA+D,CAC5F,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAI,OAAO,GAAU,WAAa,MAAM,EAAM,EAAI,EAExD,OAAO,EAAK,EAAI,YAAY,CAAE,cAAe,UAAU,GAAI,CAAC,CAAC,CAC/D,CACF,CAaA,SAAgB,EAAc,EAAkE,CAC9F,IAAM,EAAS,GAAM,QAAU,eACzB,EAAW,GAAM,UAAY,EAEnC,OAAQ,EAAK,IAAS,EAAK,EAAI,YAAY,EAAG,GAAS,EAAS,CAAE,CAAC,CAAC,CACtE,CAiBA,SAAgB,EAAY,EAEZ,CACd,IAAM,EACJ,GAAM,UACJ,EAAK,IAAS,CACd,QAAQ,MAAM,EAAK,CAAI,CACzB,GAEF,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAQ,YAAY,IAAI,EACxB,GAAW,EAAI,KAAqB,QAAU,MAAA,CAAO,YAAY,EAEvE,GAAI,CACF,IAAM,EAAM,MAAM,EAAK,CAAG,EACpB,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,OAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,GAAG,EAAI,OAAO,IAAI,EAAS,KAAM,CACxD,WACA,SACA,OAAQ,EAAI,OACZ,IAAK,EAAI,GACX,CAAC,EAEM,CACT,OAAS,EAAK,CACZ,IAAM,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,MAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,QAAQ,EAAS,KAAM,CAC9C,WACA,SACA,OAAQ,EACR,IAAK,EAAI,GACX,CAAC,EAEK,CACR,CACF,CACF"}
package/dist/query.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs"),t=require("./query-cache.cjs"),n=require("./query-observe.cjs");function r(r){let i=!1,a=new AbortController,o=new Map,s=new Map,c=t.buildCacheContext({delay:r?.delay,gcTime:r?.gcTime,shouldRetry:r?.shouldRetry,staleTime:r?.staleTime,times:r?.times},o,s,n.notify);async function l(n){if(i)throw new e.CourierDisposedError(`QueryClient`);let{enabled:r=!0,fn:a,gcTime:s,initialData:l,key:u,staleTime:d,...f}=n;if(!r){let e=t.hashKey(u);return o.get(e)?.data??void 0}let p=t.ensureEntry(c,u),m=t.makeFetchConfig(c,{fn:a,gcTime:s,staleTime:d,...f});if(l!==void 0&&p.status===`loading`&&p.data===void 0){let e=t.resolveValue(l);e!==void 0&&(p.data=e,p.error=null,p.status=`success`,p.updatedAt=Date.now())}return p.status===`success`&&p.updatedAt!==void 0&&Date.now()-p.updatedAt<m.staleTime&&!p.isFetching?(p.lastConfig=m,p.data):(p.lastConfig=m,p.inflight?p.inflight.promise:t.startFetch(c,p,m))}function u(e){if(!e.lastConfig){t.evictEntry(c,e);return}e.isFetching||t.startFetch(c,e,e.lastConfig).catch(()=>{})}function d(e){let n=e.map(e=>t.hashAtom(e));for(let e of[...o.values()])if(t.isKeyOrPrefix(e,n)){if(e.observers.size>0){u(e);continue}t.evictEntry(c,e)}}function f(e,r,i){let a=t.ensureEntry(c,e),o=i?.gcTime??a.lastConfig?.gcTime??c.gcTimeDefault;a.data=typeof r==`function`?r(a.data):r,a.error=null,a.status=`success`,a.updatedAt=i?.updatedAt??Date.now(),a.isFetching=!1,a.inflight=null,n.notify(a),t.scheduleGc(c,a,o)}function p(e){return e.observers.size===0||!e.lastConfig||e.isFetching?!1:e.status===`success`&&e.updatedAt!==void 0||e.status===`error`&&e.data!==void 0&&e.updatedAt!==void 0?Date.now()-e.updatedAt>=e.lastConfig.staleTime:!1}function m(e){let{fetch:t=!0,key:r,placeholderData:i,select:a}=e,o=n.watchInternal(c,r,{placeholderData:i,select:a});return t&&e.fn&&l({...e}).catch(()=>{}),o}return{cancel(e){let n=o.get(t.hashKey(e));n?.inflight&&n.inflight.controller.abort()},cancelAll(){for(let e of o.values())e.inflight?.controller.abort()},clear(){for(let e of[...o.values()])t.evictEntry(c,e)},get disposalSignal(){return a.signal},dispose(){if(!i){i=!0,c.disposed=!0,a.abort();for(let[,e]of o)e.observers.clear(),e.inflight?.controller.abort();for(let[,e]of s)clearTimeout(e);s.clear(),o.clear()}},get disposed(){return i},fetch:l,fetchMany(e){return Promise.all(e.map(e=>l(e)))},get(e){let n=o.get(t.hashKey(e));return n?n.data:void 0},getState(e){let r=o.get(t.hashKey(e));return r?n.toBaseState(r):null},invalidate:d,keys(){return[...o.values()].map(e=>e.key)},observe:m,observeMany(e){let t=e.map(e=>n.watchInternal(c,e));return{peek(){return t.map(e=>e.peek())},subscribe(e){let n=t.map(t=>t.subscribe(e));return()=>{for(let e of n)e()}}}},refetchStale(){for(let e of[...o.values()])p(e)&&t.startFetch(c,e,e.lastConfig).catch(()=>{})},remove(e){let n=o.get(t.hashKey(e));n&&t.evictEntry(c,n)},set:f,get size(){return o.size},[Symbol.dispose](){this.dispose()}}}exports.createQuery=r;
1
+ const e=require("./errors.cjs");require("./serialize.cjs"),require("./_dev.cjs");let t=require("@vielzeug/arsenal/object");var n=0;function r(e=!1){return{data:void 0,error:null,isFetching:e,status:`loading`,updatedAt:void 0}}function i(i){let a=new Map,o=new Map,s=i?.signal?.aborted??!1,c=e=>{for(let n of[...o.get((0,t.hash)(e))??[]])n()},l=()=>{for(let e of a.values())e.controller?.abort()},u=()=>{let e=[...a.values()].map(e=>e.key);l(),a.clear();for(let t of e)c(t)};i?.signal?.addEventListener(`abort`,()=>{s=!0,u()},{once:!0});let d=e=>{let n=(0,t.hash)(e),i=a.get(n);return i||(i={controller:void 0,definition:void 0,key:e,promise:void 0,snapshot:r()},a.set(n,i)),i},f=(a,o)=>{if(s)return Promise.reject(new e.CourierDisposedError(`QueryCache`));if(!a.definition)return Promise.reject(Error(`No fetch function registered for query ${(0,t.hash)(a.key)}.`));let l=a.definition.staleTime??i?.staleTime??n;if(!o&&a.snapshot.status===`success`&&Date.now()-a.snapshot.updatedAt<l&&!a.snapshot.isFetching)return Promise.resolve(a.snapshot.data);if(a.promise)return a.promise;let u=new AbortController;a.controller=u,a.snapshot=a.snapshot.status===`success`?{...a.snapshot,isFetching:!0}:{...r(!0)},c(a.key);let d=Promise.resolve().then(()=>a.definition.fetch({key:a.key,signal:u.signal})).then(e=>(a.snapshot={data:e,error:null,isFetching:!1,status:`success`,updatedAt:Date.now()},a.controller=void 0,a.promise=void 0,c(a.key),e),e=>{let t=e instanceof Error?e:Error(String(e));throw a.snapshot={data:a.snapshot.status===`success`?a.snapshot.data:void 0,error:t,isFetching:!1,status:`error`,updatedAt:Date.now()},a.controller=void 0,a.promise=void 0,c(a.key),t});return a.promise=d,d};return{cancelAll:l,clear:u,fetch(e,t){let n=d(e.key);return n.definition=e,f(n,t?.force??!1)},get(e){let n=a.get((0,t.hash)(e));return n?.snapshot.status===`success`?n.snapshot.data:void 0},getSnapshot(e){return a.get((0,t.hash)(e))?.snapshot??null},invalidate(e){for(let n of a.values())e.length<=n.key.length&&e.every((e,r)=>(0,t.hash)(e)===(0,t.hash)(n.key[r]))&&(n.snapshot.status===`success`&&(n.snapshot={...n.snapshot,updatedAt:0}),c(n.key))},keys(){return[...a.values()].map(e=>e.key)},refetchStale(){for(let e of a.values()){if(!e.definition||e.snapshot.status!==`success`||e.snapshot.isFetching)continue;let r=e.definition.staleTime??i?.staleTime??n;Date.now()-e.snapshot.updatedAt>=r&&f(e,!0).catch(()=>{`${(0,t.hash)(e.key)}`})}},set(e,t,n){let r=d(e);r.snapshot={data:t,error:null,isFetching:!1,status:`success`,updatedAt:n?.updatedAt??Date.now()},c(e)},subscribe(e,n){let r=(0,t.hash)(e),i=o.get(r)??new Set;return i.add(n),o.set(r,i),()=>{i.delete(n),i.size===0&&o.delete(r)}}}}exports.createQueryCache=i;
2
2
  //# sourceMappingURL=query.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"query.cjs","names":[],"sources":["../src/query.ts"],"sourcesContent":["import type { RetryOptions } from './retry';\nimport type { QueryKey, QueryState, SyncStore, Unsubscribe } from './types';\n\nimport { CourierDisposedError } from './errors';\nimport {\n buildCacheContext,\n ensureEntry,\n evictEntry,\n hashAtom,\n hashKey,\n isKeyOrPrefix,\n makeFetchConfig,\n resolveValue,\n scheduleGc,\n startFetch,\n type CacheContext,\n type CacheEntry,\n type FetchConfig,\n type QueryFn,\n type QueryFnContext,\n} from './query-cache';\nimport { notify, toBaseState, watchInternal } from './query-observe';\n\nexport type { QueryFn, QueryFnContext };\n\n/**\n * Options for `qc.fetch()`. Always throws on error and returns `T`.\n * Use `observe()` for reactive subscriptions with select/placeholder support.\n */\nexport type QueryOptions<T> = {\n /**\n * When `false` the fetch is skipped and the current cached value is returned.\n * If no cached data exists yet, the return value is `undefined` — use `getState()`\n * to inspect entry status in that case.\n * Defaults to `true`.\n */\n enabled?: boolean;\n fn: QueryFn<T>;\n gcTime?: number;\n /** Pre-seed the cache as a successful entry when no data exists. Subject to normal staleTime checks. */\n initialData?: T | (() => T | undefined);\n key: QueryKey;\n staleTime?: number;\n} & RetryOptions;\n\n/**\n * Shared reactive fields for `observe()`.\n */\ntype ObserveExtras<T, S> = {\n /**\n * Temporary value shown while a fetch is in-flight and no cached data exists.\n * Does not affect cache state — only the value returned by `store.peek()`.\n */\n placeholderData?: S | (() => S | undefined);\n /** Transform the cached data before it is delivered to store subscribers. */\n select?: (data: T | undefined) => S | undefined;\n};\n\n/**\n * Options for `qc.observe()`. Two forms:\n *\n * - `fetch?: true` (default) — triggers a background fetch; `fn` is required.\n * - `fetch: false` — read-only store; `fn` is not required or called.\n *\n * Errors surface via `store.peek().status === 'error'`, not via Promise rejection.\n */\nexport type ObserveOptions<T, S = T> =\n | ({ fetch?: true } & QueryOptions<T> & ObserveExtras<T, S>)\n | ({ fetch: false; key: QueryKey } & Partial<QueryOptions<T>> & ObserveExtras<T, S>);\n\nexport type QueryClientOptions = {\n gcTime?: number;\n staleTime?: number;\n} & RetryOptions;\n\n/**\n * Creates a key-based query cache with request deduplication, retries, stale-time/gc-time\n * eviction, and `observe()`-based reactive subscriptions (`SyncStore`-compatible).\n *\n * @example\n * ```ts\n * const qc = createQuery({ staleTime: 30_000 });\n *\n * // One-shot fetch, always resolves or throws\n * const user = await qc.fetch({ key: ['users', 1], fn: ({ signal }) => fetchUser(1, signal) });\n *\n * // Reactive subscription — errors surface via store.peek().status, not rejection\n * const store = qc.observe({ key: ['users', 1], fn: ({ signal }) => fetchUser(1, signal) });\n * const unsub = store.subscribe(() => console.log(store.peek()));\n *\n * // later:\n * qc.dispose();\n * ```\n */\nexport function createQuery(opts?: QueryClientOptions) {\n let disposed = false;\n const disposeController = new AbortController();\n const entries = new Map<string, CacheEntry>();\n const gcTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n const ctx: CacheContext = buildCacheContext(\n {\n delay: opts?.delay,\n gcTime: opts?.gcTime,\n shouldRetry: opts?.shouldRetry,\n staleTime: opts?.staleTime,\n times: opts?.times,\n },\n entries,\n gcTimers,\n notify,\n );\n\n async function fetchQuery<T>(options: QueryOptions<T>): Promise<T> {\n if (disposed) throw new CourierDisposedError('QueryClient');\n\n const { enabled = true, fn, gcTime, initialData, key, staleTime, ...retryOpts } = options;\n\n // When disabled and no existing entry, return undefined without creating a cache entry.\n if (!enabled) {\n const h = hashKey(key);\n const existing = entries.get(h);\n\n return (existing?.data as T | undefined) ?? (undefined as unknown as T);\n }\n\n const entry = ensureEntry<T>(ctx, key);\n const config = makeFetchConfig<T>(ctx, { fn, gcTime, staleTime, ...retryOpts });\n\n if (initialData !== undefined && entry.status === 'loading' && entry.data === undefined) {\n const initVal = resolveValue(initialData);\n\n if (initVal !== undefined) {\n entry.data = initVal;\n entry.error = null;\n entry.status = 'success';\n entry.updatedAt = Date.now();\n }\n }\n\n if (\n entry.status === 'success' &&\n entry.updatedAt !== undefined &&\n Date.now() - entry.updatedAt < config.staleTime &&\n !entry.isFetching\n ) {\n entry.lastConfig = config;\n\n return entry.data as T;\n }\n\n entry.lastConfig = config;\n\n if (entry.inflight) return entry.inflight.promise;\n\n return startFetch(ctx, entry, config);\n }\n\n function revalidateObservedEntry<T>(entry: CacheEntry<T>): void {\n if (!entry.lastConfig) {\n evictEntry(ctx, entry);\n\n return;\n }\n\n if (entry.isFetching) return;\n\n startFetch(ctx, entry, entry.lastConfig as FetchConfig<T>).catch(() => {});\n }\n\n function invalidate(key: QueryKey): void {\n const prefixHash = key.map((k) => hashAtom(k));\n\n for (const entry of [...entries.values()]) {\n if (isKeyOrPrefix(entry, prefixHash)) {\n if (entry.observers.size > 0) {\n revalidateObservedEntry(entry);\n continue;\n }\n\n evictEntry(ctx, entry);\n }\n }\n }\n\n function set<T>(key: QueryKey, data: T, opts?: { gcTime?: number; updatedAt?: number }): void;\n function set<T>(\n key: QueryKey,\n updater: (old: T | undefined) => T,\n opts?: { gcTime?: number; updatedAt?: number },\n ): void;\n function set<T>(\n key: QueryKey,\n dataOrUpdater: T | ((old: T | undefined) => T),\n opts?: { gcTime?: number; updatedAt?: number },\n ): void {\n const entry = ensureEntry<T>(ctx, key);\n const gcTime = opts?.gcTime ?? entry.lastConfig?.gcTime ?? ctx.gcTimeDefault;\n\n entry.data =\n typeof dataOrUpdater === 'function' ? (dataOrUpdater as (old: T | undefined) => T)(entry.data) : dataOrUpdater;\n entry.error = null;\n entry.status = 'success';\n entry.updatedAt = opts?.updatedAt ?? Date.now();\n entry.isFetching = false;\n entry.inflight = null;\n notify(entry);\n scheduleGc(ctx, entry, gcTime);\n }\n\n function isStaleAndRevalidatable(entry: CacheEntry): boolean {\n if (entry.observers.size === 0 || !entry.lastConfig || entry.isFetching) return false;\n\n if (entry.status === 'success' && entry.updatedAt !== undefined) {\n return Date.now() - entry.updatedAt >= entry.lastConfig.staleTime;\n }\n\n if (entry.status === 'error' && entry.data !== undefined && entry.updatedAt !== undefined) {\n return Date.now() - entry.updatedAt >= entry.lastConfig.staleTime;\n }\n\n return false;\n }\n\n /**\n * Returns a `SyncStore` for `key` and optionally triggers a background fetch.\n *\n * **With fetch (default):** pass `fn` and the store triggers a background fetch on creation.\n * Errors surface via `store.peek().status === 'error'`, not via Promise rejection.\n *\n * **Without fetch:** pass `fetch: false` — `fn` is not required. The store reflects\n * whatever is in the cache. Useful when another path is responsible for populating the entry.\n *\n * @example\n * ```ts\n * // Fetch form\n * const store = qc.observe({ key: ['users', 1], fn: ({ signal }) => fetchUser(1, signal) });\n *\n * // Read-only form — no fn required\n * const store = qc.observe({ key: ['users', 1], fetch: false });\n * ```\n */\n function observe<T = unknown, S = T>(options: ObserveOptions<T, S>): SyncStore<QueryState<S>> {\n const {\n fetch: shouldFetch = true,\n key,\n placeholderData,\n select,\n } = options as {\n fetch?: boolean;\n key: QueryKey;\n placeholderData?: S | (() => S | undefined);\n select?: (data: T | undefined) => S | undefined;\n };\n\n const store = watchInternal<T, S>(ctx, key, { placeholderData, select });\n\n if (shouldFetch && (options as { fn?: QueryFn<T> }).fn) {\n fetchQuery({ ...(options as QueryOptions<T>) }).catch(() => {});\n }\n\n return store;\n }\n\n return {\n cancel(key: QueryKey): void {\n const entry = entries.get(hashKey(key));\n\n if (!entry?.inflight) return;\n\n entry.inflight.controller.abort();\n },\n\n cancelAll(): void {\n for (const entry of entries.values()) {\n entry.inflight?.controller.abort();\n }\n },\n\n clear(): void {\n for (const entry of [...entries.values()]) {\n evictEntry(ctx, entry);\n }\n },\n\n get disposalSignal(): AbortSignal {\n return disposeController.signal;\n },\n\n dispose(): void {\n if (disposed) return;\n\n disposed = true;\n ctx.disposed = true;\n disposeController.abort();\n\n for (const [, entry] of entries) {\n entry.observers.clear();\n entry.inflight?.controller.abort();\n }\n\n for (const [, timer] of gcTimers) {\n clearTimeout(timer);\n }\n\n gcTimers.clear();\n entries.clear();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n fetch: fetchQuery,\n\n fetchMany<T = unknown>(queries: QueryOptions<T>[]): Promise<T[]> {\n return Promise.all(queries.map((q) => fetchQuery(q)));\n },\n\n get<T>(key: QueryKey): T | undefined {\n const entry = entries.get(hashKey(key));\n\n return entry ? (entry.data as T | undefined) : undefined;\n },\n\n getState<T>(key: QueryKey): QueryState<T> | null {\n const entry = entries.get(hashKey(key)) as CacheEntry<T> | undefined;\n\n if (!entry) return null;\n\n return toBaseState(entry);\n },\n\n invalidate,\n\n keys(): QueryKey[] {\n return [...entries.values()].map((e) => e.key);\n },\n\n observe,\n\n observeMany<T = unknown>(keys: QueryKey[]): SyncStore<QueryState<T>[]> {\n const stores = keys.map((k) => watchInternal<T>(ctx, k));\n\n return {\n peek(): QueryState<T>[] {\n return stores.map((s) => s.peek());\n },\n\n subscribe(onStoreChange: () => void): Unsubscribe {\n const unsubs = stores.map((s) => s.subscribe(onStoreChange));\n\n return () => {\n for (const u of unsubs) u();\n };\n },\n };\n },\n\n refetchStale(): void {\n for (const entry of [...entries.values()]) {\n if (isStaleAndRevalidatable(entry)) {\n startFetch(ctx, entry, entry.lastConfig as FetchConfig<unknown>).catch(() => {});\n }\n }\n },\n\n remove(key: QueryKey): void {\n const entry = entries.get(hashKey(key));\n\n if (entry) evictEntry(ctx, entry);\n },\n\n set,\n\n get size(): number {\n return entries.size;\n },\n\n [Symbol.dispose](): void {\n this.dispose();\n },\n };\n}\n\nexport type QueryClient = ReturnType<typeof createQuery>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"query.cjs","names":[],"sources":["../src/query.ts"],"sourcesContent":["import type { AsyncState, QueryCache, QueryContext, QueryDefinition, QueryKey, Unsubscribe } from './types';\n\nimport { warn } from './_dev';\nimport { CourierDisposedError } from './errors';\nimport { hash } from './serialize';\n\nconst DEFAULT_STALE_TIME = 0;\n\ntype Entry = {\n controller: AbortController | undefined;\n definition: QueryDefinition<unknown> | undefined;\n key: QueryKey;\n promise: Promise<unknown> | undefined;\n snapshot: AsyncState<unknown>;\n};\n\ntype CancellableQueryCache = QueryCache & {\n cancelAll(): void;\n};\n\nfunction loading<T>(isFetching = false): AsyncState<T> {\n return { data: undefined, error: null, isFetching, status: 'loading', updatedAt: undefined };\n}\n\n/** Transport-agnostic cache. Queries are identified by explicit keys and fetch definitions. */\nexport function createQueryCache(options?: { signal?: AbortSignal; staleTime?: number }): CancellableQueryCache {\n const entries = new Map<string, Entry>();\n const listeners = new Map<string, Set<Unsubscribe>>();\n let disposed = options?.signal?.aborted ?? false;\n\n const notify = (key: QueryKey): void => {\n for (const listener of [...(listeners.get(hash(key)) ?? [])]) listener();\n };\n\n const cancelAll = (): void => {\n for (const entry of entries.values()) entry.controller?.abort();\n };\n\n const clear = (): void => {\n const keys = [...entries.values()].map((entry) => entry.key);\n\n cancelAll();\n entries.clear();\n\n for (const key of keys) notify(key);\n };\n\n options?.signal?.addEventListener(\n 'abort',\n () => {\n disposed = true;\n clear();\n },\n { once: true },\n );\n\n const entryFor = (key: QueryKey): Entry => {\n const id = hash(key);\n let entry = entries.get(id);\n\n if (!entry) {\n entry = {\n controller: undefined,\n definition: undefined,\n key,\n promise: undefined,\n snapshot: loading(),\n };\n entries.set(id, entry);\n }\n\n return entry;\n };\n\n const fetchEntry = <T>(entry: Entry, force: boolean): Promise<T> => {\n if (disposed) return Promise.reject(new CourierDisposedError('QueryCache'));\n\n if (!entry.definition)\n return Promise.reject(new Error(`No fetch function registered for query ${hash(entry.key)}.`));\n\n const staleTime = entry.definition.staleTime ?? options?.staleTime ?? DEFAULT_STALE_TIME;\n\n if (\n !force &&\n entry.snapshot.status === 'success' &&\n Date.now() - entry.snapshot.updatedAt < staleTime &&\n !entry.snapshot.isFetching\n ) {\n return Promise.resolve(entry.snapshot.data as T);\n }\n\n if (entry.promise) return entry.promise as Promise<T>;\n\n const controller = new AbortController();\n\n entry.controller = controller;\n entry.snapshot =\n entry.snapshot.status === 'success' ? { ...entry.snapshot, isFetching: true } : { ...loading<unknown>(true) };\n notify(entry.key);\n\n const promise = Promise.resolve()\n .then(() => entry.definition!.fetch({ key: entry.key, signal: controller.signal } as QueryContext))\n .then(\n (data) => {\n entry.snapshot = { data, error: null, isFetching: false, status: 'success', updatedAt: Date.now() };\n entry.controller = undefined;\n entry.promise = undefined;\n notify(entry.key);\n\n return data;\n },\n (cause: unknown) => {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n\n entry.snapshot = {\n data: entry.snapshot.status === 'success' ? entry.snapshot.data : undefined,\n error,\n isFetching: false,\n status: 'error',\n updatedAt: Date.now(),\n };\n entry.controller = undefined;\n entry.promise = undefined;\n notify(entry.key);\n\n throw error;\n },\n );\n\n entry.promise = promise;\n\n return promise as Promise<T>;\n };\n\n return {\n cancelAll,\n clear,\n fetch<T>(definition: QueryDefinition<T>, fetchOptions?: { force?: boolean }): Promise<T> {\n const entry = entryFor(definition.key);\n\n entry.definition = definition as QueryDefinition<unknown>;\n\n return fetchEntry<T>(entry, fetchOptions?.force ?? false);\n },\n get<T>(key: QueryKey): T | undefined {\n const entry = entries.get(hash(key));\n\n return entry?.snapshot.status === 'success' ? (entry.snapshot.data as T) : undefined;\n },\n getSnapshot<T>(key: QueryKey): AsyncState<T> | null {\n return (entries.get(hash(key))?.snapshot as AsyncState<T> | undefined) ?? null;\n },\n invalidate(key: QueryKey): void {\n for (const entry of entries.values()) {\n const matches =\n key.length <= entry.key.length && key.every((atom, index) => hash(atom) === hash(entry.key[index]));\n\n if (matches) {\n if (entry.snapshot.status === 'success') entry.snapshot = { ...entry.snapshot, updatedAt: 0 };\n\n notify(entry.key);\n }\n }\n },\n keys(): QueryKey[] {\n return [...entries.values()].map((entry) => entry.key);\n },\n refetchStale(): void {\n for (const entry of entries.values()) {\n if (!entry.definition || entry.snapshot.status !== 'success' || entry.snapshot.isFetching) continue;\n\n const staleTime = entry.definition.staleTime ?? options?.staleTime ?? DEFAULT_STALE_TIME;\n\n if (Date.now() - entry.snapshot.updatedAt >= staleTime) {\n void fetchEntry(entry, true).catch(() => {\n warn(`Failed to refetch stale query ${hash(entry.key)}.`);\n });\n }\n }\n },\n set<T>(key: QueryKey, data: T, setOptions?: { updatedAt?: number }): void {\n const entry = entryFor(key);\n\n entry.snapshot = {\n data,\n error: null,\n isFetching: false,\n status: 'success',\n updatedAt: setOptions?.updatedAt ?? Date.now(),\n };\n notify(key);\n },\n subscribe(key: QueryKey, listener: () => void): Unsubscribe {\n const id = hash(key);\n const keyListeners = listeners.get(id) ?? new Set<Unsubscribe>();\n\n keyListeners.add(listener);\n listeners.set(id, keyListeners);\n\n return () => {\n keyListeners.delete(listener);\n\n if (keyListeners.size === 0) listeners.delete(id);\n };\n },\n };\n}\n"],"mappings":"2HAMA,IAAM,EAAqB,EAc3B,SAAS,EAAW,EAAa,GAAsB,CACrD,MAAO,CAAE,KAAM,IAAA,GAAW,MAAO,KAAM,aAAY,OAAQ,UAAW,UAAW,IAAA,EAAU,CAC7F,CAGA,SAAgB,EAAiB,EAA+E,CAC9G,IAAM,EAAU,IAAI,IACd,EAAY,IAAI,IAClB,EAAW,GAAS,QAAQ,SAAW,GAErC,EAAU,GAAwB,CACtC,IAAK,IAAM,IAAY,CAAC,GAAI,EAAU,KAAA,EAAI,EAAA,KAAA,CAAK,CAAG,CAAC,GAAK,CAAC,CAAE,EAAG,EAAS,CACzE,EAEM,MAAwB,CAC5B,IAAK,IAAM,KAAS,EAAQ,OAAO,EAAG,EAAM,YAAY,MAAM,CAChE,EAEM,MAAoB,CACxB,IAAM,EAAO,CAAC,GAAG,EAAQ,OAAO,CAAC,CAAC,CAAC,IAAK,GAAU,EAAM,GAAG,EAE3D,EAAU,EACV,EAAQ,MAAM,EAEd,IAAK,IAAM,KAAO,EAAM,EAAO,CAAG,CACpC,EAEA,GAAS,QAAQ,iBACf,YACM,CACJ,EAAW,GACX,EAAM,CACR,EACA,CAAE,KAAM,EAAK,CACf,EAEA,IAAM,EAAY,GAAyB,CACzC,IAAM,GAAA,EAAK,EAAA,KAAA,CAAK,CAAG,EACf,EAAQ,EAAQ,IAAI,CAAE,EAa1B,OAXK,IACH,EAAQ,CACN,WAAY,IAAA,GACZ,WAAY,IAAA,GACZ,MACA,QAAS,IAAA,GACT,SAAU,EAAQ,CACpB,EACA,EAAQ,IAAI,EAAI,CAAK,GAGhB,CACT,EAEM,GAAiB,EAAc,IAA+B,CAClE,GAAI,EAAU,OAAO,QAAQ,OAAO,IAAI,EAAA,qBAAqB,YAAY,CAAC,EAE1E,GAAI,CAAC,EAAM,WACT,OAAO,QAAQ,OAAW,MAAM,2CAAA,EAA0C,EAAA,KAAA,CAAK,EAAM,GAAG,EAAE,EAAE,CAAC,EAE/F,IAAM,EAAY,EAAM,WAAW,WAAa,GAAS,WAAa,EAEtE,GACE,CAAC,GACD,EAAM,SAAS,SAAW,WAC1B,KAAK,IAAI,EAAI,EAAM,SAAS,UAAY,GACxC,CAAC,EAAM,SAAS,WAEhB,OAAO,QAAQ,QAAQ,EAAM,SAAS,IAAS,EAGjD,GAAI,EAAM,QAAS,OAAO,EAAM,QAEhC,IAAM,EAAa,IAAI,gBAEvB,EAAM,WAAa,EACnB,EAAM,SACJ,EAAM,SAAS,SAAW,UAAY,CAAE,GAAG,EAAM,SAAU,WAAY,EAAK,EAAI,CAAE,GAAG,EAAiB,EAAI,CAAE,EAC9G,EAAO,EAAM,GAAG,EAEhB,IAAM,EAAU,QAAQ,QAAQ,CAAC,CAC9B,SAAW,EAAM,WAAY,MAAM,CAAE,IAAK,EAAM,IAAK,OAAQ,EAAW,MAAO,CAAiB,CAAC,CAAC,CAClG,KACE,IACC,EAAM,SAAW,CAAE,OAAM,MAAO,KAAM,WAAY,GAAO,OAAQ,UAAW,UAAW,KAAK,IAAI,CAAE,EAClG,EAAM,WAAa,IAAA,GACnB,EAAM,QAAU,IAAA,GAChB,EAAO,EAAM,GAAG,EAET,GAER,GAAmB,CAClB,IAAM,EAAQ,aAAiB,MAAQ,EAAY,MAAM,OAAO,CAAK,CAAC,EAatE,KAXA,GAAM,SAAW,CACf,KAAM,EAAM,SAAS,SAAW,UAAY,EAAM,SAAS,KAAO,IAAA,GAClE,QACA,WAAY,GACZ,OAAQ,QACR,UAAW,KAAK,IAAI,CACtB,EACA,EAAM,WAAa,IAAA,GACnB,EAAM,QAAU,IAAA,GAChB,EAAO,EAAM,GAAG,EAEV,CACR,CACF,EAIF,MAFA,GAAM,QAAU,EAET,CACT,EAEA,MAAO,CACL,YACA,QACA,MAAS,EAAgC,EAAgD,CACvF,IAAM,EAAQ,EAAS,EAAW,GAAG,EAIrC,MAFA,GAAM,WAAa,EAEZ,EAAc,EAAO,GAAc,OAAS,EAAK,CAC1D,EACA,IAAO,EAA8B,CACnC,IAAM,EAAQ,EAAQ,KAAA,EAAI,EAAA,KAAA,CAAK,CAAG,CAAC,EAEnC,OAAO,GAAO,SAAS,SAAW,UAAa,EAAM,SAAS,KAAa,IAAA,EAC7E,EACA,YAAe,EAAqC,CAClD,OAAQ,EAAQ,KAAA,EAAI,EAAA,KAAA,CAAK,CAAG,CAAC,CAAC,EAAE,UAA0C,IAC5E,EACA,WAAW,EAAqB,CAC9B,IAAK,IAAM,KAAS,EAAQ,OAAO,EAE/B,EAAI,QAAU,EAAM,IAAI,QAAU,EAAI,OAAO,EAAM,KAAA,EAAU,EAAA,KAAA,CAAK,CAAI,KAAA,EAAM,EAAA,KAAA,CAAK,EAAM,IAAI,EAAM,CAAC,IAG9F,EAAM,SAAS,SAAW,YAAW,EAAM,SAAW,CAAE,GAAG,EAAM,SAAU,UAAW,CAAE,GAE5F,EAAO,EAAM,GAAG,EAGtB,EACA,MAAmB,CACjB,MAAO,CAAC,GAAG,EAAQ,OAAO,CAAC,CAAC,CAAC,IAAK,GAAU,EAAM,GAAG,CACvD,EACA,cAAqB,CACnB,IAAK,IAAM,KAAS,EAAQ,OAAO,EAAG,CACpC,GAAI,CAAC,EAAM,YAAc,EAAM,SAAS,SAAW,WAAa,EAAM,SAAS,WAAY,SAE3F,IAAM,EAAY,EAAM,WAAW,WAAa,GAAS,WAAa,EAElE,KAAK,IAAI,EAAI,EAAM,SAAS,WAAa,GAC3C,EAAgB,EAAO,EAAI,CAAC,CAAC,UAAY,CAClC,IAAA,EAAiC,EAAA,KAAA,CAAK,EAAM,GAAG,EAA/C,CACP,CAAC,CAEL,CACF,EACA,IAAO,EAAe,EAAS,EAA2C,CACxE,IAAM,EAAQ,EAAS,CAAG,EAE1B,EAAM,SAAW,CACf,OACA,MAAO,KACP,WAAY,GACZ,OAAQ,UACR,UAAW,GAAY,WAAa,KAAK,IAAI,CAC/C,EACA,EAAO,CAAG,CACZ,EACA,UAAU,EAAe,EAAmC,CAC1D,IAAM,GAAA,EAAK,EAAA,KAAA,CAAK,CAAG,EACb,EAAe,EAAU,IAAI,CAAE,GAAK,IAAI,IAK9C,OAHA,EAAa,IAAI,CAAQ,EACzB,EAAU,IAAI,EAAI,CAAY,MAEjB,CACX,EAAa,OAAO,CAAQ,EAExB,EAAa,OAAS,GAAG,EAAU,OAAO,CAAE,CAClD,CACF,CACF,CACF"}
package/dist/query.d.ts CHANGED
@@ -1,104 +1,11 @@
1
- import type { RetryOptions } from './retry';
2
- import type { QueryKey, QueryState, SyncStore } from './types';
3
- import { type QueryFn, type QueryFnContext } from './query-cache';
4
- export type { QueryFn, QueryFnContext };
5
- /**
6
- * Options for `qc.fetch()`. Always throws on error and returns `T`.
7
- * Use `observe()` for reactive subscriptions with select/placeholder support.
8
- */
9
- export type QueryOptions<T> = {
10
- /**
11
- * When `false` the fetch is skipped and the current cached value is returned.
12
- * If no cached data exists yet, the return value is `undefined` — use `getState()`
13
- * to inspect entry status in that case.
14
- * Defaults to `true`.
15
- */
16
- enabled?: boolean;
17
- fn: QueryFn<T>;
18
- gcTime?: number;
19
- /** Pre-seed the cache as a successful entry when no data exists. Subject to normal staleTime checks. */
20
- initialData?: T | (() => T | undefined);
21
- key: QueryKey;
22
- staleTime?: number;
23
- } & RetryOptions;
24
- /**
25
- * Shared reactive fields for `observe()`.
26
- */
27
- type ObserveExtras<T, S> = {
28
- /**
29
- * Temporary value shown while a fetch is in-flight and no cached data exists.
30
- * Does not affect cache state — only the value returned by `store.peek()`.
31
- */
32
- placeholderData?: S | (() => S | undefined);
33
- /** Transform the cached data before it is delivered to store subscribers. */
34
- select?: (data: T | undefined) => S | undefined;
35
- };
36
- /**
37
- * Options for `qc.observe()`. Two forms:
38
- *
39
- * - `fetch?: true` (default) — triggers a background fetch; `fn` is required.
40
- * - `fetch: false` — read-only store; `fn` is not required or called.
41
- *
42
- * Errors surface via `store.peek().status === 'error'`, not via Promise rejection.
43
- */
44
- export type ObserveOptions<T, S = T> = ({
45
- fetch?: true;
46
- } & QueryOptions<T> & ObserveExtras<T, S>) | ({
47
- fetch: false;
48
- key: QueryKey;
49
- } & Partial<QueryOptions<T>> & ObserveExtras<T, S>);
50
- export type QueryClientOptions = {
51
- gcTime?: number;
52
- staleTime?: number;
53
- } & RetryOptions;
54
- /**
55
- * Creates a key-based query cache with request deduplication, retries, stale-time/gc-time
56
- * eviction, and `observe()`-based reactive subscriptions (`SyncStore`-compatible).
57
- *
58
- * @example
59
- * ```ts
60
- * const qc = createQuery({ staleTime: 30_000 });
61
- *
62
- * // One-shot fetch, always resolves or throws
63
- * const user = await qc.fetch({ key: ['users', 1], fn: ({ signal }) => fetchUser(1, signal) });
64
- *
65
- * // Reactive subscription — errors surface via store.peek().status, not rejection
66
- * const store = qc.observe({ key: ['users', 1], fn: ({ signal }) => fetchUser(1, signal) });
67
- * const unsub = store.subscribe(() => console.log(store.peek()));
68
- *
69
- * // later:
70
- * qc.dispose();
71
- * ```
72
- */
73
- export declare function createQuery(opts?: QueryClientOptions): {
74
- cancel(key: QueryKey): void;
1
+ import type { QueryCache } from './types';
2
+ type CancellableQueryCache = QueryCache & {
75
3
  cancelAll(): void;
76
- clear(): void;
77
- readonly disposalSignal: AbortSignal;
78
- dispose(): void;
79
- readonly disposed: boolean;
80
- fetch: <T>(options: QueryOptions<T>) => Promise<T>;
81
- fetchMany<T = unknown>(queries: QueryOptions<T>[]): Promise<T[]>;
82
- get<T>(key: QueryKey): T | undefined;
83
- getState<T>(key: QueryKey): QueryState<T> | null;
84
- invalidate: (key: QueryKey) => void;
85
- keys(): QueryKey[];
86
- observe: <T = unknown, S = T>(options: ObserveOptions<T, S>) => SyncStore<QueryState<S>>;
87
- observeMany<T = unknown>(keys: QueryKey[]): SyncStore<QueryState<T>[]>;
88
- refetchStale(): void;
89
- remove(key: QueryKey): void;
90
- set: {
91
- <T>(key: QueryKey, data: T, opts?: {
92
- gcTime?: number;
93
- updatedAt?: number;
94
- }): void;
95
- <T>(key: QueryKey, updater: (old: T | undefined) => T, opts?: {
96
- gcTime?: number;
97
- updatedAt?: number;
98
- }): void;
99
- };
100
- readonly size: number;
101
- [Symbol.dispose](): void;
102
4
  };
103
- export type QueryClient = ReturnType<typeof createQuery>;
5
+ /** Transport-agnostic cache. Queries are identified by explicit keys and fetch definitions. */
6
+ export declare function createQueryCache(options?: {
7
+ signal?: AbortSignal;
8
+ staleTime?: number;
9
+ }): CancellableQueryCache;
10
+ export {};
104
11
  //# sourceMappingURL=query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAwD,MAAM,SAAS,CAAC;AAgB5G,KAAK,qBAAqB,GAAG,UAAU,GAAG;IACxC,SAAS,IAAI,IAAI,CAAC;CACnB,CAAC;AAMF,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,qBAAqB,CAqL9G"}
package/dist/query.js CHANGED
@@ -1,2 +1,2 @@
1
- import{CourierDisposedError as e}from"./errors.js";import{buildCacheContext as t,ensureEntry as n,evictEntry as r,hashAtom as i,hashKey as a,isKeyOrPrefix as o,makeFetchConfig as s,resolveValue as c,scheduleGc as l,startFetch as u}from"./query-cache.js";import{notify as d,toBaseState as f,watchInternal as p}from"./query-observe.js";function m(m){let h=!1,g=new AbortController,_=new Map,v=new Map,y=t({delay:m?.delay,gcTime:m?.gcTime,shouldRetry:m?.shouldRetry,staleTime:m?.staleTime,times:m?.times},_,v,d);async function b(t){if(h)throw new e(`QueryClient`);let{enabled:r=!0,fn:i,gcTime:o,initialData:l,key:d,staleTime:f,...p}=t;if(!r){let e=a(d);return _.get(e)?.data??void 0}let m=n(y,d),g=s(y,{fn:i,gcTime:o,staleTime:f,...p});if(l!==void 0&&m.status===`loading`&&m.data===void 0){let e=c(l);e!==void 0&&(m.data=e,m.error=null,m.status=`success`,m.updatedAt=Date.now())}return m.status===`success`&&m.updatedAt!==void 0&&Date.now()-m.updatedAt<g.staleTime&&!m.isFetching?(m.lastConfig=g,m.data):(m.lastConfig=g,m.inflight?m.inflight.promise:u(y,m,g))}function x(e){if(!e.lastConfig){r(y,e);return}e.isFetching||u(y,e,e.lastConfig).catch(()=>{})}function S(e){let t=e.map(e=>i(e));for(let e of[..._.values()])if(o(e,t)){if(e.observers.size>0){x(e);continue}r(y,e)}}function C(e,t,r){let i=n(y,e),a=r?.gcTime??i.lastConfig?.gcTime??y.gcTimeDefault;i.data=typeof t==`function`?t(i.data):t,i.error=null,i.status=`success`,i.updatedAt=r?.updatedAt??Date.now(),i.isFetching=!1,i.inflight=null,d(i),l(y,i,a)}function w(e){return e.observers.size===0||!e.lastConfig||e.isFetching?!1:e.status===`success`&&e.updatedAt!==void 0||e.status===`error`&&e.data!==void 0&&e.updatedAt!==void 0?Date.now()-e.updatedAt>=e.lastConfig.staleTime:!1}function T(e){let{fetch:t=!0,key:n,placeholderData:r,select:i}=e,a=p(y,n,{placeholderData:r,select:i});return t&&e.fn&&b({...e}).catch(()=>{}),a}return{cancel(e){let t=_.get(a(e));t?.inflight&&t.inflight.controller.abort()},cancelAll(){for(let e of _.values())e.inflight?.controller.abort()},clear(){for(let e of[..._.values()])r(y,e)},get disposalSignal(){return g.signal},dispose(){if(!h){h=!0,y.disposed=!0,g.abort();for(let[,e]of _)e.observers.clear(),e.inflight?.controller.abort();for(let[,e]of v)clearTimeout(e);v.clear(),_.clear()}},get disposed(){return h},fetch:b,fetchMany(e){return Promise.all(e.map(e=>b(e)))},get(e){let t=_.get(a(e));return t?t.data:void 0},getState(e){let t=_.get(a(e));return t?f(t):null},invalidate:S,keys(){return[..._.values()].map(e=>e.key)},observe:T,observeMany(e){let t=e.map(e=>p(y,e));return{peek(){return t.map(e=>e.peek())},subscribe(e){let n=t.map(t=>t.subscribe(e));return()=>{for(let e of n)e()}}}},refetchStale(){for(let e of[..._.values()])w(e)&&u(y,e,e.lastConfig).catch(()=>{})},remove(e){let t=_.get(a(e));t&&r(y,t)},set:C,get size(){return _.size},[Symbol.dispose](){this.dispose()}}}export{m as createQuery};
1
+ import{CourierDisposedError as e}from"./errors.js";import{hash as t}from"./serialize.js";import"./_dev.js";var n=0;function r(e=!1){return{data:void 0,error:null,isFetching:e,status:`loading`,updatedAt:void 0}}function i(i){let a=new Map,o=new Map,s=i?.signal?.aborted??!1,c=e=>{for(let n of[...o.get(t(e))??[]])n()},l=()=>{for(let e of a.values())e.controller?.abort()},u=()=>{let e=[...a.values()].map(e=>e.key);l(),a.clear();for(let t of e)c(t)};i?.signal?.addEventListener(`abort`,()=>{s=!0,u()},{once:!0});let d=e=>{let n=t(e),i=a.get(n);return i||(i={controller:void 0,definition:void 0,key:e,promise:void 0,snapshot:r()},a.set(n,i)),i},f=(a,o)=>{if(s)return Promise.reject(new e(`QueryCache`));if(!a.definition)return Promise.reject(Error(`No fetch function registered for query ${t(a.key)}.`));let l=a.definition.staleTime??i?.staleTime??n;if(!o&&a.snapshot.status===`success`&&Date.now()-a.snapshot.updatedAt<l&&!a.snapshot.isFetching)return Promise.resolve(a.snapshot.data);if(a.promise)return a.promise;let u=new AbortController;a.controller=u,a.snapshot=a.snapshot.status===`success`?{...a.snapshot,isFetching:!0}:{...r(!0)},c(a.key);let d=Promise.resolve().then(()=>a.definition.fetch({key:a.key,signal:u.signal})).then(e=>(a.snapshot={data:e,error:null,isFetching:!1,status:`success`,updatedAt:Date.now()},a.controller=void 0,a.promise=void 0,c(a.key),e),e=>{let t=e instanceof Error?e:Error(String(e));throw a.snapshot={data:a.snapshot.status===`success`?a.snapshot.data:void 0,error:t,isFetching:!1,status:`error`,updatedAt:Date.now()},a.controller=void 0,a.promise=void 0,c(a.key),t});return a.promise=d,d};return{cancelAll:l,clear:u,fetch(e,t){let n=d(e.key);return n.definition=e,f(n,t?.force??!1)},get(e){let n=a.get(t(e));return n?.snapshot.status===`success`?n.snapshot.data:void 0},getSnapshot(e){return a.get(t(e))?.snapshot??null},invalidate(e){for(let n of a.values())e.length<=n.key.length&&e.every((e,r)=>t(e)===t(n.key[r]))&&(n.snapshot.status===`success`&&(n.snapshot={...n.snapshot,updatedAt:0}),c(n.key))},keys(){return[...a.values()].map(e=>e.key)},refetchStale(){for(let e of a.values()){if(!e.definition||e.snapshot.status!==`success`||e.snapshot.isFetching)continue;let r=e.definition.staleTime??i?.staleTime??n;Date.now()-e.snapshot.updatedAt>=r&&f(e,!0).catch(()=>{`${t(e.key)}`})}},set(e,t,n){let r=d(e);r.snapshot={data:t,error:null,isFetching:!1,status:`success`,updatedAt:n?.updatedAt??Date.now()},c(e)},subscribe(e,n){let r=t(e),i=o.get(r)??new Set;return i.add(n),o.set(r,i),()=>{i.delete(n),i.size===0&&o.delete(r)}}}}export{i as createQueryCache};
2
2
  //# sourceMappingURL=query.js.map