hazo_core 1.2.1 → 1.3.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.
- package/README.md +8 -0
- package/dist/http/list_params.d.ts +30 -0
- package/dist/http/list_params.d.ts.map +1 -0
- package/dist/http/list_params.js +53 -0
- package/dist/http/list_params.js.map +1 -0
- package/dist/index.client.d.ts +3 -2
- package/dist/index.client.d.ts.map +1 -1
- package/dist/index.client.js +2 -1
- package/dist/index.client.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/debounced_saver.d.ts +52 -0
- package/dist/utils/debounced_saver.d.ts.map +1 -0
- package/dist/utils/debounced_saver.js +80 -0
- package/dist/utils/debounced_saver.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +12 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/retry.d.ts +34 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +56 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/uuid.d.ts +9 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/dist/utils/uuid.js +22 -0
- package/dist/utils/uuid.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -66,6 +66,14 @@ import { loadConfig, defineConfig, createLogger, createDebug,
|
|
|
66
66
|
fetchWithRequestId, createRequestIdMiddleware, REQUEST_ID_HEADER } from 'hazo_core';
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
### Utilities
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { withRetry, isUuid, parseListLimit, parseListOffset,
|
|
73
|
+
createDebouncedSaver } from 'hazo_core';
|
|
74
|
+
// all five are env-agnostic and also available from 'hazo_core/client'
|
|
75
|
+
```
|
|
76
|
+
|
|
69
77
|
### Browser-safe subset
|
|
70
78
|
|
|
71
79
|
```ts
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a limit query-string param.
|
|
3
|
+
*
|
|
4
|
+
* @param raw The raw string from `searchParams.get('limit')` (may be null).
|
|
5
|
+
* @param opts `default` — value used when raw is absent/invalid.
|
|
6
|
+
* `max` — upper clamp applied after parsing.
|
|
7
|
+
* @returns An integer in [1, max].
|
|
8
|
+
* @example parseListLimit('50', { default: 20, max: 100 }) // 50
|
|
9
|
+
* @example parseListLimit(null, { default: 20, max: 100 }) // 20
|
|
10
|
+
* @example parseListLimit('abc', { default: 20, max: 100 }) // 20
|
|
11
|
+
* @example parseListLimit('9999', { default: 20, max: 100 }) // 100
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseListLimit(raw: string | null, opts: {
|
|
14
|
+
default: number;
|
|
15
|
+
max: number;
|
|
16
|
+
}): number;
|
|
17
|
+
/**
|
|
18
|
+
* Parse an offset query-string param.
|
|
19
|
+
*
|
|
20
|
+
* @param raw The raw string from `searchParams.get('offset')` (may be null).
|
|
21
|
+
* @param opts Optional `default` — value used when raw is absent/invalid (default 0).
|
|
22
|
+
* @returns An integer >= 0.
|
|
23
|
+
* @example parseListOffset('40', {}) // 40
|
|
24
|
+
* @example parseListOffset(null, {}) // 0
|
|
25
|
+
* @example parseListOffset('-5', {}) // 0
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseListOffset(raw: string | null, opts?: {
|
|
28
|
+
default?: number;
|
|
29
|
+
}): number;
|
|
30
|
+
//# sourceMappingURL=list_params.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_params.d.ts","sourceRoot":"","sources":["../../src/http/list_params.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACrC,MAAM,CAMR;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1B,MAAM,CAMR"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// file_description: Safe pagination parameter parsers for list API routes.
|
|
2
|
+
//
|
|
3
|
+
// `parseInt` without a radix is not safe — callers may pass garbage or omit the
|
|
4
|
+
// param entirely, which causes parseInt to return NaN. Math.min/max propagate NaN
|
|
5
|
+
// silently, resulting in e.g. `limit=NaN` being sent downstream (PostgREST, an ORM,
|
|
6
|
+
// etc). These helpers use `parseInt(raw, 10)` with an explicit radix, check for
|
|
7
|
+
// non-finite/negative results, and fall back to caller-supplied defaults.
|
|
8
|
+
//
|
|
9
|
+
// Promoted from taxclientdocs' lib/api/list-params.ts into hazo_core — pure string
|
|
10
|
+
// parsing with no app- or framework-specific behaviour. Browser-safe (no Node
|
|
11
|
+
// deps), so also exported from the client entry point.
|
|
12
|
+
/**
|
|
13
|
+
* Parse a limit query-string param.
|
|
14
|
+
*
|
|
15
|
+
* @param raw The raw string from `searchParams.get('limit')` (may be null).
|
|
16
|
+
* @param opts `default` — value used when raw is absent/invalid.
|
|
17
|
+
* `max` — upper clamp applied after parsing.
|
|
18
|
+
* @returns An integer in [1, max].
|
|
19
|
+
* @example parseListLimit('50', { default: 20, max: 100 }) // 50
|
|
20
|
+
* @example parseListLimit(null, { default: 20, max: 100 }) // 20
|
|
21
|
+
* @example parseListLimit('abc', { default: 20, max: 100 }) // 20
|
|
22
|
+
* @example parseListLimit('9999', { default: 20, max: 100 }) // 100
|
|
23
|
+
*/
|
|
24
|
+
export function parseListLimit(raw, opts) {
|
|
25
|
+
if (raw === null || raw === '')
|
|
26
|
+
return opts.default;
|
|
27
|
+
const parsed = parseInt(raw, 10);
|
|
28
|
+
if (!isFinite(parsed))
|
|
29
|
+
return opts.default;
|
|
30
|
+
if (parsed < 1)
|
|
31
|
+
return 1;
|
|
32
|
+
return Math.min(parsed, opts.max);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Parse an offset query-string param.
|
|
36
|
+
*
|
|
37
|
+
* @param raw The raw string from `searchParams.get('offset')` (may be null).
|
|
38
|
+
* @param opts Optional `default` — value used when raw is absent/invalid (default 0).
|
|
39
|
+
* @returns An integer >= 0.
|
|
40
|
+
* @example parseListOffset('40', {}) // 40
|
|
41
|
+
* @example parseListOffset(null, {}) // 0
|
|
42
|
+
* @example parseListOffset('-5', {}) // 0
|
|
43
|
+
*/
|
|
44
|
+
export function parseListOffset(raw, opts) {
|
|
45
|
+
const fallback = opts?.default ?? 0;
|
|
46
|
+
if (raw === null || raw === '')
|
|
47
|
+
return fallback;
|
|
48
|
+
const parsed = parseInt(raw, 10);
|
|
49
|
+
if (!isFinite(parsed) || parsed < 0)
|
|
50
|
+
return fallback;
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=list_params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_params.js","sourceRoot":"","sources":["../../src/http/list_params.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,gFAAgF;AAChF,kFAAkF;AAClF,oFAAoF;AACpF,gFAAgF;AAChF,0EAA0E;AAC1E,EAAE;AACF,mFAAmF;AACnF,8EAA8E;AAC9E,uDAAuD;AAEvD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAkB,EAClB,IAAsC;IAEtC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC;IACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC;IAC3C,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAkB,EAClB,IAA2B;IAE3B,MAAM,QAAQ,GAAG,IAAI,EAAE,OAAO,IAAI,CAAC,CAAC;IACpC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/index.client.d.ts
CHANGED
|
@@ -12,10 +12,11 @@ export { HazoError, HazoValidationError, HazoAuthError, HazoNotFoundError, HazoC
|
|
|
12
12
|
export type { HazoErrorOptions, HazoValidationErrorOptions, ValidationIssue, HazoAuthErrorOptions, HazoNotFoundErrorOptions, HazoConflictErrorOptions, HazoConfigErrorOptions, HazoExternalErrorOptions, HazoRateLimitErrorOptions, HazoUnavailableErrorOptions, HazoInternalErrorOptions, } from './errors/index.js';
|
|
13
13
|
export { setBrowserCorrelationId, getContext, getCorrelationId, withContext, } from './context/client.js';
|
|
14
14
|
export type { HazoContext } from './context/types.js';
|
|
15
|
-
export { generateRequestId, generateId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, getCurrentEnv, } from './utils/index.js';
|
|
16
|
-
export type { DateFormat } from './utils/index.js';
|
|
15
|
+
export { generateRequestId, generateId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, getCurrentEnv, withRetry, isUuid, createDebouncedSaver, } from './utils/index.js';
|
|
16
|
+
export type { DateFormat, RetryOptions, DebouncedSaveContext, CreateDebouncedSaverOptions, DebouncedSaver, } from './utils/index.js';
|
|
17
17
|
export { fetchWithRequestId } from './http/fetch_with_request_id.client.js';
|
|
18
18
|
export { get_origin_url, create_redirect_url } from './http/get_origin_url.js';
|
|
19
|
+
export { parseListLimit, parseListOffset } from './http/list_params.js';
|
|
19
20
|
export { createLogger } from './logger/index.client.js';
|
|
20
21
|
export type { HazoCoreLogger } from './logger/index.js';
|
|
21
22
|
//# sourceMappingURL=index.client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG3F,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGvE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,
|
|
1
|
+
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG3F,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGvE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,MAAM,EACN,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,2BAA2B,EAC3B,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIxE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.client.js
CHANGED
|
@@ -15,10 +15,11 @@ export { HazoError, HazoValidationError, HazoAuthError, HazoNotFoundError, HazoC
|
|
|
15
15
|
// Context (browser — mutable ref, NOT AsyncLocalStorage)
|
|
16
16
|
export { setBrowserCorrelationId, getContext, getCorrelationId, withContext, } from './context/client.js';
|
|
17
17
|
// Safe utils (no Node deps)
|
|
18
|
-
export { generateRequestId, generateId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, getCurrentEnv, } from './utils/index.js';
|
|
18
|
+
export { generateRequestId, generateId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, getCurrentEnv, withRetry, isUuid, createDebouncedSaver, } from './utils/index.js';
|
|
19
19
|
// HTTP — browser-safe variants (Fetch API, no AsyncLocalStorage)
|
|
20
20
|
export { fetchWithRequestId } from './http/fetch_with_request_id.client.js';
|
|
21
21
|
export { get_origin_url, create_redirect_url } from './http/get_origin_url.js';
|
|
22
|
+
export { parseListLimit, parseListOffset } from './http/list_params.js';
|
|
22
23
|
// Logger — client-side stub emits to the browser console (server version
|
|
23
24
|
// requires node:module + process.stderr, neither available in browsers/edge)
|
|
24
25
|
export { createLogger } from './logger/index.client.js';
|
package/dist/index.client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.client.js","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE3F,sDAAsD;AACtD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEvE,4DAA4D;AAC5D,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAe3B,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAG7B,4BAA4B;AAC5B,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,
|
|
1
|
+
{"version":3,"file":"index.client.js","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE3F,sDAAsD;AACtD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEvE,4DAA4D;AAC5D,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAe3B,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAG7B,4BAA4B;AAC5B,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,MAAM,EACN,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAS1B,iEAAiE;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExE,yEAAyE;AACzE,6EAA6E;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { REQUEST_ID_HEADER, HAZO_ERROR_SYMBOL, HAZO_SINGLETONS_KEY } from './constants.js';
|
|
8
8
|
export { registerSingleton, getSingleton, globalSingleton, resetGlobalSingleton } from './singleton/index.js';
|
|
9
|
-
export { getCurrentEnv, generateRequestId, generateId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, } from './utils/index.js';
|
|
10
|
-
export type { DateFormat } from './utils/index.js';
|
|
9
|
+
export { getCurrentEnv, generateRequestId, generateId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, withRetry, isUuid, createDebouncedSaver, } from './utils/index.js';
|
|
10
|
+
export type { DateFormat, RetryOptions, DebouncedSaveContext, CreateDebouncedSaverOptions, DebouncedSaver, } from './utils/index.js';
|
|
11
11
|
export { HazoError, HazoValidationError, HazoAuthError, HazoNotFoundError, HazoConflictError, HazoConfigError, HazoExternalError, HazoRateLimitError, HazoUnavailableError, HazoInternalError, fromZodValidation, fromZodConfig, } from './errors/index.js';
|
|
12
12
|
export type { HazoErrorOptions, HazoValidationErrorOptions, ValidationIssue, HazoAuthErrorOptions, HazoNotFoundErrorOptions, HazoConflictErrorOptions, HazoConfigErrorOptions, HazoExternalErrorOptions, HazoRateLimitErrorOptions, HazoUnavailableErrorOptions, HazoInternalErrorOptions, } from './errors/index.js';
|
|
13
13
|
export { withContext, getContext, getCorrelationId, } from './context/index.js';
|
|
@@ -21,4 +21,5 @@ export type { HazoCoreDebug } from './debug/index.js';
|
|
|
21
21
|
export { createRequestIdMiddleware, withRequestIdRouteHandler, } from './http/request_id_middleware.js';
|
|
22
22
|
export { fetchWithRequestId } from './http/fetch_with_request_id.js';
|
|
23
23
|
export { get_origin_url, create_redirect_url } from './http/get_origin_url.js';
|
|
24
|
+
export { parseListLimit, parseListOffset } from './http/list_params.js';
|
|
24
25
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG3F,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG9G,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG3F,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG9G,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,EACT,MAAM,EACN,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,2BAA2B,EAC3B,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,WAAW,EACX,UAAU,EACV,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACjH,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EACL,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { REQUEST_ID_HEADER, HAZO_ERROR_SYMBOL, HAZO_SINGLETONS_KEY } from './con
|
|
|
9
9
|
// Singleton registry
|
|
10
10
|
export { registerSingleton, getSingleton, globalSingleton, resetGlobalSingleton } from './singleton/index.js';
|
|
11
11
|
// Utilities
|
|
12
|
-
export { getCurrentEnv, generateRequestId, generateId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, } from './utils/index.js';
|
|
12
|
+
export { getCurrentEnv, generateRequestId, generateId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, withRetry, isUuid, createDebouncedSaver, } from './utils/index.js';
|
|
13
13
|
// Errors
|
|
14
14
|
export { HazoError, HazoValidationError, HazoAuthError, HazoNotFoundError, HazoConflictError, HazoConfigError, HazoExternalError, HazoRateLimitError, HazoUnavailableError, HazoInternalError, fromZodValidation, fromZodConfig, } from './errors/index.js';
|
|
15
15
|
// Context (server — AsyncLocalStorage)
|
|
@@ -24,4 +24,5 @@ export { createDebug } from './debug/index.js';
|
|
|
24
24
|
export { createRequestIdMiddleware, withRequestIdRouteHandler, } from './http/request_id_middleware.js';
|
|
25
25
|
export { fetchWithRequestId } from './http/fetch_with_request_id.js';
|
|
26
26
|
export { get_origin_url, create_redirect_url } from './http/get_origin_url.js';
|
|
27
|
+
export { parseListLimit, parseListOffset } from './http/list_params.js';
|
|
27
28
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE3F,qBAAqB;AACrB,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE9G,YAAY;AACZ,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE3F,qBAAqB;AACrB,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE9G,YAAY;AACZ,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,EACT,MAAM,EACN,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAS1B,SAAS;AACT,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAe3B,uCAAuC;AACvC,OAAO,EACL,WAAW,EACX,UAAU,EACV,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,SAAS;AACT,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGjH,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO;AACP,OAAO,EACL,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Context passed to the `save` callback describing which path triggered it. */
|
|
2
|
+
export interface DebouncedSaveContext {
|
|
3
|
+
/**
|
|
4
|
+
* True only for the `flush()` path (unmount/navigation). Callers should issue a
|
|
5
|
+
* `keepalive` request in that case so it outlives the page; false for the normal
|
|
6
|
+
* debounced path.
|
|
7
|
+
*/
|
|
8
|
+
keepalive: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Options for {@link createDebouncedSaver}. */
|
|
11
|
+
export interface CreateDebouncedSaverOptions<T> {
|
|
12
|
+
/** Debounce window in milliseconds. */
|
|
13
|
+
delayMs: number;
|
|
14
|
+
/** Persist the data. Called at most once per queued change. */
|
|
15
|
+
save: (data: T, ctx: DebouncedSaveContext) => void;
|
|
16
|
+
}
|
|
17
|
+
/** Handle returned by {@link createDebouncedSaver}. */
|
|
18
|
+
export interface DebouncedSaver<T> {
|
|
19
|
+
/** Queue `data` to be saved after the debounce delay, replacing any pending save. */
|
|
20
|
+
schedule(data: T): void;
|
|
21
|
+
/** Fire the pending save immediately (keepalive) and cancel the timer. No-op if nothing is pending. */
|
|
22
|
+
flush(): void;
|
|
23
|
+
/** Drop the pending save without firing it. */
|
|
24
|
+
cancel(): void;
|
|
25
|
+
/** True while a save is queued and not yet fired. */
|
|
26
|
+
hasPending(): boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a debounced saver: `schedule()` queues a save after `delayMs` of
|
|
30
|
+
* inactivity, collapsing rapid successive calls into a single save of the latest
|
|
31
|
+
* data. `flush()` fires any pending save immediately (marked `keepalive: true`) —
|
|
32
|
+
* call it on unmount/navigation instead of just cancelling the timer, so in-flight
|
|
33
|
+
* changes are not lost.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const saver = createDebouncedSaver<FormData>({
|
|
38
|
+
* delayMs: 2000,
|
|
39
|
+
* save: (data, { keepalive }) => fetch('/api/save', {
|
|
40
|
+
* method: 'POST',
|
|
41
|
+
* body: JSON.stringify(data),
|
|
42
|
+
* keepalive,
|
|
43
|
+
* }),
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* saver.schedule(formData); // fires after 2s of inactivity
|
|
47
|
+
* // on unmount:
|
|
48
|
+
* saver.flush(); // fires immediately with keepalive: true
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function createDebouncedSaver<T>(opts: CreateDebouncedSaverOptions<T>): DebouncedSaver<T>;
|
|
52
|
+
//# sourceMappingURL=debounced_saver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debounced_saver.d.ts","sourceRoot":"","sources":["../../src/utils/debounced_saver.ts"],"names":[],"mappings":"AAmBA,gFAAgF;AAChF,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,gDAAgD;AAChD,MAAM,WAAW,2BAA2B,CAAC,CAAC;IAC5C,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACpD;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACxB,uGAAuG;IACvG,KAAK,IAAI,IAAI,CAAC;IACd,+CAA+C;IAC/C,MAAM,IAAI,IAAI,CAAC;IACf,qDAAqD;IACrD,UAAU,IAAI,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACnC,cAAc,CAAC,CAAC,CAAC,CAyCnB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// file_description: Framework-agnostic debounced saver with an explicit `flush()`.
|
|
2
|
+
//
|
|
3
|
+
// Built to fix a lost-write bug on a client-survey autosave: the page used a bare
|
|
4
|
+
// debounce timer that was *cancelled* on unmount, so any change made within the
|
|
5
|
+
// debounce window (notably an async result landing shortly before navigation) was
|
|
6
|
+
// silently discarded when the user navigated away.
|
|
7
|
+
//
|
|
8
|
+
// The fix is `flush()`: instead of cancelling the pending timer on unmount, the
|
|
9
|
+
// caller flushes it, firing the queued save immediately. The flush path is flagged
|
|
10
|
+
// `keepalive: true` in the callback context so the caller can issue a `keepalive`
|
|
11
|
+
// fetch that survives page teardown.
|
|
12
|
+
//
|
|
13
|
+
// Pure and IO-free: the actual persistence is the injected `save` callback, so this
|
|
14
|
+
// is unit-testable in a node environment with fake timers (no DOM/fetch required).
|
|
15
|
+
// Uses only `setTimeout`/`clearTimeout`, so it is browser-safe and exported from
|
|
16
|
+
// both the server and client entry points.
|
|
17
|
+
//
|
|
18
|
+
// Promoted from taxclientdocs' lib/debounced-save.ts into hazo_core.
|
|
19
|
+
/**
|
|
20
|
+
* Create a debounced saver: `schedule()` queues a save after `delayMs` of
|
|
21
|
+
* inactivity, collapsing rapid successive calls into a single save of the latest
|
|
22
|
+
* data. `flush()` fires any pending save immediately (marked `keepalive: true`) —
|
|
23
|
+
* call it on unmount/navigation instead of just cancelling the timer, so in-flight
|
|
24
|
+
* changes are not lost.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const saver = createDebouncedSaver<FormData>({
|
|
29
|
+
* delayMs: 2000,
|
|
30
|
+
* save: (data, { keepalive }) => fetch('/api/save', {
|
|
31
|
+
* method: 'POST',
|
|
32
|
+
* body: JSON.stringify(data),
|
|
33
|
+
* keepalive,
|
|
34
|
+
* }),
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* saver.schedule(formData); // fires after 2s of inactivity
|
|
38
|
+
* // on unmount:
|
|
39
|
+
* saver.flush(); // fires immediately with keepalive: true
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function createDebouncedSaver(opts) {
|
|
43
|
+
const { delayMs, save } = opts;
|
|
44
|
+
let timer = null;
|
|
45
|
+
let pending = null;
|
|
46
|
+
const clearTimer = () => {
|
|
47
|
+
if (timer !== null) {
|
|
48
|
+
clearTimeout(timer);
|
|
49
|
+
timer = null;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
schedule(data) {
|
|
54
|
+
pending = { data };
|
|
55
|
+
clearTimer();
|
|
56
|
+
timer = setTimeout(() => {
|
|
57
|
+
timer = null;
|
|
58
|
+
const queued = pending;
|
|
59
|
+
pending = null;
|
|
60
|
+
if (queued)
|
|
61
|
+
save(queued.data, { keepalive: false });
|
|
62
|
+
}, delayMs);
|
|
63
|
+
},
|
|
64
|
+
flush() {
|
|
65
|
+
clearTimer();
|
|
66
|
+
const queued = pending;
|
|
67
|
+
pending = null;
|
|
68
|
+
if (queued)
|
|
69
|
+
save(queued.data, { keepalive: true });
|
|
70
|
+
},
|
|
71
|
+
cancel() {
|
|
72
|
+
clearTimer();
|
|
73
|
+
pending = null;
|
|
74
|
+
},
|
|
75
|
+
hasPending() {
|
|
76
|
+
return pending !== null;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=debounced_saver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debounced_saver.js","sourceRoot":"","sources":["../../src/utils/debounced_saver.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,kFAAkF;AAClF,gFAAgF;AAChF,kFAAkF;AAClF,mDAAmD;AACnD,EAAE;AACF,gFAAgF;AAChF,mFAAmF;AACnF,kFAAkF;AAClF,qCAAqC;AACrC,EAAE;AACF,oFAAoF;AACpF,mFAAmF;AACnF,iFAAiF;AACjF,2CAA2C;AAC3C,EAAE;AACF,qEAAqE;AAgCrE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAoC;IAEpC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAE/B,IAAI,KAAK,GAAyC,IAAI,CAAC;IACvD,IAAI,OAAO,GAAuB,IAAI,CAAC;IAEvC,MAAM,UAAU,GAAG,GAAS,EAAE;QAC5B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ,CAAC,IAAO;YACd,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC;YACnB,UAAU,EAAE,CAAC;YACb,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBACtB,KAAK,GAAG,IAAI,CAAC;gBACb,MAAM,MAAM,GAAG,OAAO,CAAC;gBACvB,OAAO,GAAG,IAAI,CAAC;gBACf,IAAI,MAAM;oBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YACtD,CAAC,EAAE,OAAO,CAAC,CAAC;QACd,CAAC;QAED,KAAK;YACH,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,OAAO,CAAC;YACvB,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,MAAM;gBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,MAAM;YACJ,UAAU,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QAED,UAAU;YACR,OAAO,OAAO,KAAK,IAAI,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -34,6 +34,11 @@ export declare function sleep(ms: number): Promise<void>;
|
|
|
34
34
|
export declare function formatBytes(bytes: number, decimals?: number): string;
|
|
35
35
|
export { format_date, format_date_range, DEFAULT_DATE_FORMAT, } from './dates.js';
|
|
36
36
|
export type { DateFormat } from './dates.js';
|
|
37
|
+
export { withRetry } from './retry.js';
|
|
38
|
+
export type { RetryOptions } from './retry.js';
|
|
39
|
+
export { isUuid } from './uuid.js';
|
|
40
|
+
export { createDebouncedSaver } from './debounced_saver.js';
|
|
41
|
+
export type { DebouncedSaveContext, CreateDebouncedSaverOptions, DebouncedSaver, } from './debounced_saver.js';
|
|
37
42
|
/**
|
|
38
43
|
* Format a date as "28 May 2026"
|
|
39
44
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAMzC;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAMD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CASvE;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAMjE;AAMD;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAMD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAW/D;AAMD,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAMzC;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAMD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CASvE;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAMjE;AAMD;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAMD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAW/D;AAMD,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAMnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EACV,oBAAoB,EACpB,2BAA2B,EAC3B,cAAc,GACf,MAAM,sBAAsB,CAAC;AAU9B;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAO3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAQ1D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAM3D;AAMD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAQ,GAAG,MAAM,CAOvE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAKjE;AAMD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAElD;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOhD"}
|
package/dist/utils/index.js
CHANGED
|
@@ -88,6 +88,18 @@ export function formatBytes(bytes, decimals = 2) {
|
|
|
88
88
|
// ---------------------------------------------------------------------------
|
|
89
89
|
export { format_date, format_date_range, DEFAULT_DATE_FORMAT, } from './dates.js';
|
|
90
90
|
// ---------------------------------------------------------------------------
|
|
91
|
+
// Retry with backoff
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
export { withRetry } from './retry.js';
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// UUID validation
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
export { isUuid } from './uuid.js';
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Debounced saver
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
export { createDebouncedSaver } from './debounced_saver.js';
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
91
103
|
// Date formatters
|
|
92
104
|
// ---------------------------------------------------------------------------
|
|
93
105
|
function toDate(date) {
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Options for {@link withRetry}. */
|
|
2
|
+
export interface RetryOptions {
|
|
3
|
+
/** Total number of attempts. Default 3. */
|
|
4
|
+
attempts?: number;
|
|
5
|
+
/** Base backoff delay in ms for the first wait. Default 500. */
|
|
6
|
+
baseDelayMs?: number;
|
|
7
|
+
/** Cap on backoff delay in ms. Default 2000. */
|
|
8
|
+
maxDelayMs?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Run `fn` up to `attempts` times. Returns the first non-null/non-undefined result.
|
|
12
|
+
*
|
|
13
|
+
* A thrown error OR a null/undefined return is treated as a failed attempt and
|
|
14
|
+
* triggers a retry. Between attempts, waits with exponential backoff:
|
|
15
|
+
* `baseDelayMs`, `baseDelayMs * 2`, … capped at `maxDelayMs`. No wait after the
|
|
16
|
+
* final attempt. If every attempt fails (throws or returns null/undefined),
|
|
17
|
+
* resolves to `null`.
|
|
18
|
+
*
|
|
19
|
+
* @param fn Async function to execute on each attempt.
|
|
20
|
+
* @param opts Retry configuration (attempts, baseDelayMs, maxDelayMs).
|
|
21
|
+
* @param sleep Injectable sleep for tests; defaults to a setTimeout-based sleep.
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const result = await withRetry(
|
|
25
|
+
* () => fetchFlakyThing(),
|
|
26
|
+
* { attempts: 3, baseDelayMs: 500, maxDelayMs: 2000 },
|
|
27
|
+
* );
|
|
28
|
+
* if (result === null) {
|
|
29
|
+
* // every attempt failed
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function withRetry<T>(fn: () => Promise<T | null>, opts?: RetryOptions, sleep?: (ms: number) => Promise<void>): Promise<T | null>;
|
|
34
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAQA,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,EAC3B,IAAI,CAAC,EAAE,YAAY,EACnB,KAAK,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAgB,GAClD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAyBnB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// file_description: Generic retry-with-exponential-backoff helper for transient,
|
|
2
|
+
// idempotent async calls (LLM calls, flaky external APIs, etc). Pure; no IO beyond
|
|
3
|
+
// the injectable `sleep` function, so it is unit-testable with fake timers.
|
|
4
|
+
//
|
|
5
|
+
// Promoted from taxclientdocs' lib/classification/retry.ts (withClassificationRetry)
|
|
6
|
+
// into hazo_core as a general-purpose helper — the retry/backoff shape has no
|
|
7
|
+
// classification-specific behaviour.
|
|
8
|
+
/** Default real sleep implementation. */
|
|
9
|
+
const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
|
+
/**
|
|
11
|
+
* Run `fn` up to `attempts` times. Returns the first non-null/non-undefined result.
|
|
12
|
+
*
|
|
13
|
+
* A thrown error OR a null/undefined return is treated as a failed attempt and
|
|
14
|
+
* triggers a retry. Between attempts, waits with exponential backoff:
|
|
15
|
+
* `baseDelayMs`, `baseDelayMs * 2`, … capped at `maxDelayMs`. No wait after the
|
|
16
|
+
* final attempt. If every attempt fails (throws or returns null/undefined),
|
|
17
|
+
* resolves to `null`.
|
|
18
|
+
*
|
|
19
|
+
* @param fn Async function to execute on each attempt.
|
|
20
|
+
* @param opts Retry configuration (attempts, baseDelayMs, maxDelayMs).
|
|
21
|
+
* @param sleep Injectable sleep for tests; defaults to a setTimeout-based sleep.
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const result = await withRetry(
|
|
25
|
+
* () => fetchFlakyThing(),
|
|
26
|
+
* { attempts: 3, baseDelayMs: 500, maxDelayMs: 2000 },
|
|
27
|
+
* );
|
|
28
|
+
* if (result === null) {
|
|
29
|
+
* // every attempt failed
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export async function withRetry(fn, opts, sleep = defaultSleep) {
|
|
34
|
+
const attempts = opts?.attempts ?? 3;
|
|
35
|
+
const baseDelayMs = opts?.baseDelayMs ?? 500;
|
|
36
|
+
const maxDelayMs = opts?.maxDelayMs ?? 2000;
|
|
37
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
38
|
+
let result = null;
|
|
39
|
+
try {
|
|
40
|
+
result = await fn();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Swallow transient errors and treat as a failed attempt.
|
|
44
|
+
}
|
|
45
|
+
if (result != null) {
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
// Wait before the next attempt, but not after the last one.
|
|
49
|
+
if (attempt < attempts) {
|
|
50
|
+
const delay = Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
|
|
51
|
+
await sleep(delay);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,mFAAmF;AACnF,4EAA4E;AAC5E,EAAE;AACF,qFAAqF;AACrF,8EAA8E;AAC9E,qCAAqC;AAYrC,yCAAyC;AACzC,MAAM,YAAY,GAAG,CAAC,EAAU,EAAiB,EAAE,CACjD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAA2B,EAC3B,IAAmB,EACnB,QAAuC,YAAY;IAEnD,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,CAAC,CAAC;IACrC,MAAM,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,GAAG,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,IAAI,CAAC;IAE5C,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;QACrD,IAAI,MAAM,GAAa,IAAI,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,0DAA0D;QAC5D,CAAC;QAED,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,4DAA4D;QAC5D,IAAI,OAAO,GAAG,QAAQ,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YAC3E,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True iff `value` is a canonical 8-4-4-4-12 hex UUID (case-insensitive).
|
|
3
|
+
*
|
|
4
|
+
* @param value The candidate string; `null`/`undefined` return `false`.
|
|
5
|
+
* @example isUuid('f47ac10b-58cc-4372-a567-0e02b2c3d479') // true
|
|
6
|
+
* @example isUuid('f_1779965617794_qqz9a') // false
|
|
7
|
+
*/
|
|
8
|
+
export declare function isUuid(value: string | null | undefined): boolean;
|
|
9
|
+
//# sourceMappingURL=uuid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../src/utils/uuid.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEhE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// file_description: UUID validation for API route parameters.
|
|
2
|
+
//
|
|
3
|
+
// Postgres/PostgREST-backed apps frequently accept a path/query id that must be a
|
|
4
|
+
// UUID before it's safe to send to `id=eq.<value>` — a non-UUID value (e.g. a
|
|
5
|
+
// synthetic client-generated id) causes an opaque "invalid input syntax for type
|
|
6
|
+
// uuid" 400 from PostgREST. Validating up front with `isUuid` lets routes return a
|
|
7
|
+
// clear, actionable error instead.
|
|
8
|
+
//
|
|
9
|
+
// Promoted from taxclientdocs' lib/api/uuid.ts into hazo_core — the check itself
|
|
10
|
+
// has no app-specific behaviour.
|
|
11
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
12
|
+
/**
|
|
13
|
+
* True iff `value` is a canonical 8-4-4-4-12 hex UUID (case-insensitive).
|
|
14
|
+
*
|
|
15
|
+
* @param value The candidate string; `null`/`undefined` return `false`.
|
|
16
|
+
* @example isUuid('f47ac10b-58cc-4372-a567-0e02b2c3d479') // true
|
|
17
|
+
* @example isUuid('f_1779965617794_qqz9a') // false
|
|
18
|
+
*/
|
|
19
|
+
export function isUuid(value) {
|
|
20
|
+
return typeof value === 'string' && UUID_RE.test(value);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=uuid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/utils/uuid.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,kFAAkF;AAClF,8EAA8E;AAC9E,iFAAiF;AACjF,mFAAmF;AACnF,mCAAmC;AACnC,EAAE;AACF,iFAAiF;AACjF,iCAAiC;AAEjC,MAAM,OAAO,GACX,iEAAiE,CAAC;AAEpE;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,KAAgC;IACrD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hazo_core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Foundation package for all hazo_* packages — errors, correlation ID, config, logger, debug, singletons, utils",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
72
|
"hazo_debug": "^3.1.1",
|
|
73
|
-
"hazo_logs": "^2.
|
|
73
|
+
"hazo_logs": "^2.1.1"
|
|
74
74
|
},
|
|
75
75
|
"peerDependenciesMeta": {
|
|
76
76
|
"hazo_logs": {
|