lifecycleion 0.0.8 → 0.0.10

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 (48) hide show
  1. package/README.md +45 -36
  2. package/dist/lib/domain-utils/domain-utils.cjs +1154 -0
  3. package/dist/lib/domain-utils/domain-utils.cjs.map +1 -0
  4. package/dist/lib/domain-utils/domain-utils.d.cts +210 -0
  5. package/dist/lib/domain-utils/domain-utils.d.ts +210 -0
  6. package/dist/lib/domain-utils/domain-utils.js +1112 -0
  7. package/dist/lib/domain-utils/domain-utils.js.map +1 -0
  8. package/dist/lib/http-client/index.cjs +5254 -0
  9. package/dist/lib/http-client/index.cjs.map +1 -0
  10. package/dist/lib/http-client/index.d.cts +372 -0
  11. package/dist/lib/http-client/index.d.ts +372 -0
  12. package/dist/lib/http-client/index.js +5207 -0
  13. package/dist/lib/http-client/index.js.map +1 -0
  14. package/dist/lib/http-client-mock/index.cjs +525 -0
  15. package/dist/lib/http-client-mock/index.cjs.map +1 -0
  16. package/dist/lib/http-client-mock/index.d.cts +129 -0
  17. package/dist/lib/http-client-mock/index.d.ts +129 -0
  18. package/dist/lib/http-client-mock/index.js +488 -0
  19. package/dist/lib/http-client-mock/index.js.map +1 -0
  20. package/dist/lib/http-client-node/index.cjs +1112 -0
  21. package/dist/lib/http-client-node/index.cjs.map +1 -0
  22. package/dist/lib/http-client-node/index.d.cts +43 -0
  23. package/dist/lib/http-client-node/index.d.ts +43 -0
  24. package/dist/lib/http-client-node/index.js +1075 -0
  25. package/dist/lib/http-client-node/index.js.map +1 -0
  26. package/dist/lib/http-client-xhr/index.cjs +323 -0
  27. package/dist/lib/http-client-xhr/index.cjs.map +1 -0
  28. package/dist/lib/http-client-xhr/index.d.cts +23 -0
  29. package/dist/lib/http-client-xhr/index.d.ts +23 -0
  30. package/dist/lib/http-client-xhr/index.js +286 -0
  31. package/dist/lib/http-client-xhr/index.js.map +1 -0
  32. package/dist/lib/lifecycle-manager/index.cjs +118 -61
  33. package/dist/lib/lifecycle-manager/index.cjs.map +1 -1
  34. package/dist/lib/lifecycle-manager/index.js +118 -61
  35. package/dist/lib/lifecycle-manager/index.js.map +1 -1
  36. package/dist/lib/lru-cache/index.cjs +274 -0
  37. package/dist/lib/lru-cache/index.cjs.map +1 -0
  38. package/dist/lib/lru-cache/index.d.cts +84 -0
  39. package/dist/lib/lru-cache/index.d.ts +84 -0
  40. package/dist/lib/lru-cache/index.js +249 -0
  41. package/dist/lib/lru-cache/index.js.map +1 -0
  42. package/dist/lib/retry-utils/index.d.cts +3 -23
  43. package/dist/lib/retry-utils/index.d.ts +3 -23
  44. package/dist/types-CUPvmYQ8.d.cts +868 -0
  45. package/dist/types-D_MywcG0.d.cts +23 -0
  46. package/dist/types-D_MywcG0.d.ts +23 -0
  47. package/dist/types-Hw2PUTIT.d.ts +868 -0
  48. package/package.json +45 -3
@@ -0,0 +1,372 @@
1
+ import { R as RequestState, c as HTTPMethod, d as HTTPRequestOptions, e as HTTPResponse, f as HTTPClientError, g as HTTPProgressEvent, h as AttemptStartEvent, i as AttemptEndEvent, S as StreamResponseFactory, j as HTTPClientConfig, A as AdapterType, k as RequestInterceptor, l as RequestInterceptorFilter, m as ResponseObserver, n as ResponseObserverFilter, E as ErrorObserver, o as ErrorObserverFilter, p as SubClientConfig, H as HTTPAdapter, a as AdapterRequest, b as AdapterResponse } from '../../types-CUPvmYQ8.cjs';
2
+ export { v as AttemptRequest, C as ContentType, N as Cookie, O as CookieInput, q as CookieJar, P as CookieJarJSON, s as ErrorCode, G as ErrorObserverPhase, B as ErrorObserverPhaseName, u as InterceptedRequest, I as InterceptorCancel, D as InterceptorPhase, y as InterceptorPhaseName, Q as QueryObject, r as QueryValue, J as RedirectHopInfo, t as RequestInterceptorContext, w as RequestPhase, x as RequestPhaseName, F as ResponseObserverPhase, z as ResponseObserverPhaseName, M as StreamResponseCancel, L as StreamResponseContext, K as StreamResponseInfo, W as WritableLike } from '../../types-CUPvmYQ8.cjs';
3
+ import { R as RetryPolicyOptions } from '../../types-D_MywcG0.cjs';
4
+
5
+ interface TrackedRequest {
6
+ requestID: string;
7
+ clientID: string;
8
+ label?: string;
9
+ state: RequestState;
10
+ abortController: AbortController;
11
+ }
12
+ /**
13
+ * Shared in-flight request map. One instance is shared between a root HTTPClient and
14
+ * all its sub-clients so that cancelAll() cancels across all of them.
15
+ */
16
+ declare class RequestTracker {
17
+ private requests;
18
+ add(entry: TrackedRequest): void;
19
+ remove(requestID: string): void;
20
+ get(requestID: string): TrackedRequest | undefined;
21
+ updateState(requestID: string, state: RequestState): void;
22
+ /**
23
+ * Cancels a single request by ID. Returns 1 if cancelled, 0 if not found.
24
+ */
25
+ cancel(requestID: string, reason?: string): number;
26
+ /**
27
+ * Cancels ALL in-flight requests across the shared tracker (all clients).
28
+ * Returns the number of requests cancelled.
29
+ */
30
+ cancelAll(reason?: string): number;
31
+ /**
32
+ * Cancels all requests owned by a specific client.
33
+ * Returns the number of requests cancelled.
34
+ */
35
+ cancelOwn(clientID: string, reason?: string): number;
36
+ /**
37
+ * Cancels all requests that have the given label (across all clients in the shared tracker).
38
+ * Returns the number of requests cancelled.
39
+ */
40
+ cancelAllWithLabel(label: string, reason?: string): number;
41
+ /**
42
+ * Cancels requests owned by a specific client that also have the given label.
43
+ * Returns the number of requests cancelled.
44
+ */
45
+ cancelOwnWithLabel(clientID: string, label: string, reason?: string): number;
46
+ /**
47
+ * Returns a read-only view of tracked requests.
48
+ *
49
+ * Intentionally omits abortController,
50
+ * callers cancel via cancel()/cancelAll()/etc. so that
51
+ * the tracker remains the sole owner of state mutations.
52
+ */
53
+ list(filter?: {
54
+ clientID?: string;
55
+ label?: string;
56
+ }): {
57
+ count: number;
58
+ requests: RequestInfo[];
59
+ };
60
+ }
61
+ interface RequestInfo {
62
+ requestID: string;
63
+ clientID: string;
64
+ label?: string;
65
+ state: RequestState;
66
+ }
67
+
68
+ interface BuilderCallbacks<T> {
69
+ setState: (state: RequestState) => void;
70
+ setResponse: (response: HTTPResponse<T>) => void;
71
+ setError: (error: HTTPClientError) => void;
72
+ setAttemptCount: (count: number) => void;
73
+ setNextRetryDelayMS: (delayMS: number | null) => void;
74
+ setNextRetryAt: (timestampMS: number | null) => void;
75
+ setStartedAt: (timestampMS: number) => void;
76
+ setCancelFn: (fn: (reason?: string) => void) => void;
77
+ }
78
+ interface BuilderSendContext<T = unknown> {
79
+ method: HTTPMethod;
80
+ path: string;
81
+ requestID: string;
82
+ options: ResolvedBuilderOptions;
83
+ callbacks: BuilderCallbacks<T>;
84
+ }
85
+ interface ResolvedBuilderOptions extends HTTPRequestOptions {
86
+ headers: Record<string, string | string[]>;
87
+ }
88
+ type SendFn<T> = (context: BuilderSendContext<T>) => Promise<HTTPResponse<T>>;
89
+ /**
90
+ * Fluent, single-use request builder. Returned by HTTPClient methods.
91
+ * Call .send() to execute the request.
92
+ */
93
+ declare class HTTPRequestBuilder<T = unknown> {
94
+ private _method;
95
+ private _path;
96
+ private _headers;
97
+ private _params?;
98
+ private _body?;
99
+ private _timeout?;
100
+ private _signal?;
101
+ private _retryPolicy?;
102
+ private _label?;
103
+ private _onUploadProgress?;
104
+ private _onDownloadProgress?;
105
+ private _onAttemptStart?;
106
+ private _onAttemptEnd?;
107
+ private _streamResponse?;
108
+ private _sendFn;
109
+ private _sent;
110
+ private _requestID;
111
+ private _state;
112
+ private _response;
113
+ private _error;
114
+ private _attemptCount;
115
+ private _nextRetryDelayMS;
116
+ private _nextRetryAt;
117
+ private _startedAt;
118
+ private _completedAt;
119
+ private _cancelFn;
120
+ private _preSendCancelReason;
121
+ constructor(method: HTTPMethod, path: string, sendFn: SendFn<T>, options?: HTTPRequestOptions);
122
+ headers(headers: Record<string, string | string[]>): this;
123
+ params(params: Record<string, unknown>): this;
124
+ json(data: unknown): this;
125
+ formData(data: FormData): this;
126
+ text(data: string): this;
127
+ body(data: unknown): this;
128
+ timeout(ms: number): this;
129
+ signal(abortSignal: AbortSignal): this;
130
+ label(label: string): this;
131
+ retryPolicy(options: RetryPolicyOptions | null): this;
132
+ onUploadProgress(fn: (event: HTTPProgressEvent) => void): this;
133
+ onDownloadProgress(fn: (event: HTTPProgressEvent) => void): this;
134
+ onAttemptStart(fn: (event: AttemptStartEvent) => void): this;
135
+ onAttemptEnd(fn: (event: AttemptEndEvent) => void): this;
136
+ /**
137
+ * NodeAdapter only. Called after response headers arrive on a 200 response,
138
+ * before any body bytes are read. Return a WritableLike to pipe the body into
139
+ * it, or null to cancel the request entirely.
140
+ *
141
+ * The context provides an attempt-scoped AbortSignal that fires on cancel,
142
+ * timeout, or stream write failure — useful for co-locating cleanup with setup:
143
+ *
144
+ * .streamResponse((_info, { signal }) => {
145
+ * const stream = createWriteStream('/tmp/file.bin');
146
+ *
147
+ * signal.addEventListener('abort', () => {
148
+ * stream.destroy();
149
+ * fs.unlinkSync('/tmp/file.bin'); // clean up partial file
150
+ * });
151
+ * return stream;
152
+ * })
153
+ *
154
+ * HTTPClient rejects non-node adapters before dispatch if this is set.
155
+ */
156
+ streamResponse(fn: StreamResponseFactory): this;
157
+ get requestID(): string;
158
+ get state(): RequestState;
159
+ get response(): HTTPResponse<T> | null;
160
+ get error(): HTTPClientError | null;
161
+ get attemptCount(): number | null;
162
+ get nextRetryDelayMS(): number | null;
163
+ get nextRetryAt(): number | null;
164
+ /** Epoch ms when the first attempt was dispatched. null before send(). */
165
+ get startedAt(): number | null;
166
+ /** Total wall-clock ms since the first attempt, including retry waits. null before send().
167
+ * Freezes once the request completes.
168
+ */
169
+ get elapsedMS(): number | null;
170
+ /**
171
+ * Cancels the request. Returns true if the cancel was applied, false if it
172
+ * was a no-op (already completed, cancelled, or failed).
173
+ *
174
+ * Calling cancel() before send() marks the builder as cancelled so that
175
+ * send() throws instead of dispatching the request.
176
+ */
177
+ cancel(reason?: string): boolean;
178
+ send<U = T>(): Promise<HTTPResponse<U>>;
179
+ private _applyOptions;
180
+ private _assertNotSent;
181
+ }
182
+
183
+ type RemoveFn = () => void;
184
+ interface InternalClientState {
185
+ tracker?: RequestTracker;
186
+ parentClient?: BaseHTTPClient | null;
187
+ }
188
+ declare class BaseHTTPClient {
189
+ protected _clientID: string;
190
+ protected _config: Required<Pick<HTTPClientConfig, 'timeout' | 'includeRequestID' | 'includeAttemptHeader' | 'followRedirects' | 'maxRedirects'>> & HTTPClientConfig;
191
+ protected _adapter: NonNullable<HTTPClientConfig['adapter']>;
192
+ protected _tracker: RequestTracker;
193
+ protected _parentClient: BaseHTTPClient | null;
194
+ protected _isBrowserRuntime: boolean;
195
+ private _requestInterceptors;
196
+ private _responseObservers;
197
+ private _errorObservers;
198
+ private _disabled;
199
+ constructor(config?: HTTPClientConfig, internal?: InternalClientState);
200
+ get clientID(): string;
201
+ get adapterType(): AdapterType;
202
+ addRequestInterceptor(fn: RequestInterceptor, filter?: RequestInterceptorFilter): RemoveFn;
203
+ addResponseObserver(fn: ResponseObserver, filter?: ResponseObserverFilter): RemoveFn;
204
+ addErrorObserver(fn: ErrorObserver, filter?: ErrorObserverFilter): RemoveFn;
205
+ /**
206
+ * Start a request. `path` is usually **relative** to {@link HTTPClientConfig.baseURL}
207
+ * when `baseURL` is set (e.g. `/v1/users`, `v1/users`).
208
+ *
209
+ * You may also pass a full **`http:` / `https:`** URL or a **protocol-relative**
210
+ * `//host/...` string; those are **not** concatenated onto `baseURL`, so one
211
+ * client can occasionally target another origin without a sub-client. The
212
+ * final string is still run through `resolveAbsoluteURL` with `baseURL` so
213
+ * `//…` picks up the right scheme. See `buildURL` in `./utils`.
214
+ */
215
+ request<T = unknown>(method: HTTPMethod, path: string, options?: HTTPRequestOptions): HTTPRequestBuilder<T>;
216
+ get<T = unknown>(path: string, options?: HTTPRequestOptions): HTTPRequestBuilder<T>;
217
+ post<T = unknown>(path: string, options?: HTTPRequestOptions): HTTPRequestBuilder<T>;
218
+ put<T = unknown>(path: string, options?: HTTPRequestOptions): HTTPRequestBuilder<T>;
219
+ patch<T = unknown>(path: string, options?: HTTPRequestOptions): HTTPRequestBuilder<T>;
220
+ delete<T = unknown>(path: string, options?: HTTPRequestOptions): HTTPRequestBuilder<T>;
221
+ head<T = unknown>(path: string, options?: HTTPRequestOptions): HTTPRequestBuilder<T>;
222
+ cancel(requestID: string, reason?: string): void;
223
+ cancelAll(reason?: string): void;
224
+ cancelOwn(reason?: string): void;
225
+ cancelAllWithLabel(label: string, reason?: string): void;
226
+ cancelOwnWithLabel(label: string, reason?: string): void;
227
+ listRequests(filter?: {
228
+ scope?: 'own' | 'all';
229
+ label?: string;
230
+ }): {
231
+ count: number;
232
+ requests: RequestInfo[];
233
+ };
234
+ disable(): void;
235
+ enable(): void;
236
+ get isDisabled(): boolean;
237
+ protected _buildSubClientConfig(overrides?: SubClientConfig): HTTPClientConfig;
238
+ private _execute;
239
+ private _sanitizeRedirectRequest;
240
+ private _isCrossOriginRedirect;
241
+ /**
242
+ * Core retry loop — sends the request through the adapter and retries on
243
+ * retryable status codes (503, 429, etc.) or network errors, up to the
244
+ * policy's max attempts. Each attempt gets its own independent timeout.
245
+ *
246
+ * Cancellation (via cancelSignal) is checked after every retry delay so
247
+ * the caller doesn't have to wait for the full delay to finish.
248
+ *
249
+ * The same RetryPolicy instance is shared across the redirect loop in
250
+ * _execute, so retries during redirect hops eat into the same budget.
251
+ */
252
+ private _dispatchRequestAttempts;
253
+ /**
254
+ * Delay that resolves early when the cancel signal fires.
255
+ * Only wired to cancelSignal (user cancel / cancelAll) — the per-attempt
256
+ * timeout does NOT cancel retry delays.
257
+ * Cleans up both the timer and the abort listener to avoid leaks.
258
+ */
259
+ private _cancellableDelay;
260
+ private _buildResponse;
261
+ /**
262
+ * Build an HTTPClientError from a failed response.
263
+ *
264
+ * Error code priority:
265
+ * 1. Explicit codeOverride (redirect_disabled, redirect_loop, request_setup_error, adapter_error, stream_write_error, stream_response_error, stream_setup_error)
266
+ * 2. Response flags (isCancelled → cancelled, isTimeout → timeout),
267
+ * except streamed-body failures preserve their specific stream_* code while
268
+ * still surfacing `isTimeout: true`
269
+ * 3. Default fallback → network_error
270
+ *
271
+ * Key distinction:
272
+ * - `adapter_error`: Adapter threw an exception (DNS failure, connection refused, etc.)
273
+ * The adapter failed to handle the error gracefully.
274
+ * - `network_error`: Adapter reported a transport-level failure cleanly via
275
+ * `isTransportError`, or returned `status: 0` to indicate a transport
276
+ * failure.
277
+ *
278
+ * Well-behaved adapters should catch their own transport failures and return
279
+ * an AdapterResponse instead of throwing. Prefer `isTransportError: true`
280
+ * when reporting adapter-originated transport failures. If an adapter
281
+ * throws, that's an adapter implementation problem.
282
+ */
283
+ private _makeError;
284
+ /**
285
+ * Runs parent + own interceptor chains in order.
286
+ * Returns the (possibly modified) request, or an InterceptorCancel signal.
287
+ */
288
+ private _runInterceptors;
289
+ /**
290
+ * Phase for an attempt outcome that will be retried (before the retry delay).
291
+ * `attempt` matches `onAttemptEnd.attemptNumber` for that outcome.
292
+ */
293
+ private _retryOutcomePhase;
294
+ private _withInternalRequestHeaders;
295
+ private _buildAttemptRequest;
296
+ private _bestEffortAttemptRequestFromPending;
297
+ private _runResponseObservers;
298
+ private _runErrorObservers;
299
+ private _composeSignals;
300
+ private _assertRequestIsSupported;
301
+ private _assertInterceptorResolvedURL;
302
+ private _isSupportedRequestURL;
303
+ }
304
+ declare class HTTPClient extends BaseHTTPClient {
305
+ constructor(config?: HTTPClientConfig);
306
+ /**
307
+ * Creates a sub-client that inherits this client's config, request tracker,
308
+ * and interceptor/observer chain integration.
309
+ *
310
+ * `defaultHeaders` use `'replace'` behavior by default. Set
311
+ * `defaultHeadersStrategy: 'merge'` to preserve inherited defaults and
312
+ * layer new headers on top.
313
+ *
314
+ * If no new `defaultHeaders` are provided, `'merge'` keeps the inherited defaults as-is,
315
+ * which is useful for sub-clients that only swap adapters or other non-header config.
316
+ */
317
+ createSubClient(overrides?: SubClientConfig): HTTPSubClient;
318
+ }
319
+ /**
320
+ * Public type for sub-clients returned by {@link HTTPClient.createSubClient}.
321
+ *
322
+ * Identical to {@link HTTPClient} except `createSubClient` is not available —
323
+ * sub-clients share the parent's tracker and observer chain but cannot spawn
324
+ * further sub-clients.
325
+ */
326
+ type HTTPSubClient = Omit<HTTPClient, 'createSubClient'>;
327
+
328
+ declare class FetchAdapter implements HTTPAdapter {
329
+ getType(): AdapterType;
330
+ send(request: AdapterRequest): Promise<AdapterResponse>;
331
+ }
332
+
333
+ /**
334
+ * HTTP responses that are plausibly transient and worth retrying when a retry
335
+ * policy is explicitly enabled.
336
+ *
337
+ * `status === 0` is included on purpose because browser/XHR-style adapters can
338
+ * surface "no real HTTP response" that way when the network is unavailable or
339
+ * the request otherwise fails before a normal status code is received.
340
+ */
341
+ declare const RETRYABLE_STATUS_CODES: ReadonlySet<number>;
342
+ declare const DEFAULT_TIMEOUT_MS = 30000;
343
+ declare const DEFAULT_REQUEST_ID_HEADER = "x-local-client-request-id";
344
+ declare const DEFAULT_REQUEST_ATTEMPT_HEADER = "x-local-client-request-attempt";
345
+ declare const DEFAULT_USER_AGENT = "lifecycleion-http-client";
346
+ declare const HTTP_METHODS: ReadonlyArray<HTTPMethod>;
347
+ /**
348
+ * Exact-match request headers that browsers either forbid outright or do not
349
+ * let this client set reliably via plain Fetch/XHR headers.
350
+ *
351
+ * Prefix-based rules like `proxy-*` and `sec-*` are handled in `header-utils.ts`.
352
+ */
353
+ declare const BROWSER_RESTRICTED_HEADERS: ReadonlySet<string>;
354
+ declare const BROWSER_RESTRICTED_HEADER_PREFIXES: ReadonlyArray<string>;
355
+ /**
356
+ * Headers that can tunnel the real method through POST. Browsers block these
357
+ * when they try to smuggle forbidden transport methods.
358
+ */
359
+ declare const BROWSER_METHOD_OVERRIDE_HEADER_NAMES: ReadonlySet<string>;
360
+ /**
361
+ * Methods that browsers do not allow request headers to tunnel via the
362
+ * override headers above.
363
+ */
364
+ declare const BROWSER_FORBIDDEN_METHOD_OVERRIDE_VALUES: ReadonlySet<string>;
365
+ declare const DEFAULT_MAX_REDIRECTS = 5;
366
+ /**
367
+ * Redirect responses that carry a follow-up `Location` hop. `300` and `304`
368
+ * are excluded because they do not represent an automatic redirect here.
369
+ */
370
+ declare const REDIRECT_STATUS_CODES: ReadonlySet<number>;
371
+
372
+ export { AdapterRequest, AdapterResponse, AdapterType, AttemptEndEvent, AttemptStartEvent, BROWSER_FORBIDDEN_METHOD_OVERRIDE_VALUES, BROWSER_METHOD_OVERRIDE_HEADER_NAMES, BROWSER_RESTRICTED_HEADERS, BROWSER_RESTRICTED_HEADER_PREFIXES, DEFAULT_MAX_REDIRECTS, DEFAULT_REQUEST_ATTEMPT_HEADER, DEFAULT_REQUEST_ID_HEADER, DEFAULT_TIMEOUT_MS, DEFAULT_USER_AGENT, ErrorObserver, ErrorObserverFilter, FetchAdapter, HTTPAdapter, HTTPClient, HTTPClientConfig, HTTPClientError, HTTPMethod, HTTPProgressEvent, HTTPRequestBuilder, HTTPRequestOptions, HTTPResponse, type HTTPSubClient, HTTP_METHODS, REDIRECT_STATUS_CODES, RETRYABLE_STATUS_CODES, type RequestInfo, RequestInterceptor, RequestInterceptorFilter, RequestState, ResponseObserver, ResponseObserverFilter, StreamResponseFactory, SubClientConfig };