@mmstack/resource 19.2.0 → 20.0.1

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.
@@ -1,92 +0,0 @@
1
- import { type HttpResourceOptions, type HttpResourceRef, type HttpResourceRequest } from '@angular/common/http';
2
- import { Signal } from '@angular/core';
3
- import { CircuitBreakerOptions, type RetryOptions } from './util';
4
- /**
5
- * Options for configuring caching behavior of a `queryResource`.
6
- * - `true`: Enables caching with default settings.
7
- * - `{ ttl?: number; staleTime?: number; hash?: (req: HttpResourceRequest) => string; }`: Configures caching with custom settings.
8
- */
9
- type ResourceCacheOptions = true | {
10
- /**
11
- * The Time To Live (TTL) for the cached data, in milliseconds. After this time, the cached data is
12
- * considered expired and will be refetched.
13
- */
14
- ttl?: number;
15
- /**
16
- * The duration, in milliseconds, during which stale data can be served while a revalidation request
17
- * is made in the background.
18
- */
19
- staleTime?: number;
20
- /**
21
- * A custom function to generate the cache key. Defaults to using the request URL with parameters.
22
- * Provide a custom hash function if you need more control over how cache keys are generated,
23
- * for instance, to ignore certain query parameters or to use request body for the cache key.
24
- */
25
- hash?: (req: HttpResourceRequest) => string;
26
- };
27
- /**
28
- * Options for configuring a `queryResource`.
29
- */
30
- export type QueryResourceOptions<TResult, TRaw = TResult> = HttpResourceOptions<TResult, TRaw> & {
31
- /**
32
- * Whether to keep the previous value of the resource while a refresh is in progress.
33
- * Defaults to `false`. Also keeps status & headers while refreshing.
34
- */
35
- keepPrevious?: boolean;
36
- /**
37
- * The refresh interval, in milliseconds. If provided, the resource will automatically
38
- * refresh its data at the specified interval.
39
- */
40
- refresh?: number;
41
- /**
42
- * Options for retrying failed requests.
43
- */
44
- retry?: RetryOptions;
45
- /**
46
- * An optional error handler callback. This function will be called whenever the
47
- * underlying HTTP request fails. Useful for displaying toasts or other error messages.
48
- */
49
- onError?: (err: unknown) => void;
50
- /**
51
- * Options for configuring a circuit breaker for the resource.
52
- */
53
- circuitBreaker?: CircuitBreakerOptions | true;
54
- /**
55
- * Options for enabling and configuring caching for the resource.
56
- */
57
- cache?: ResourceCacheOptions;
58
- };
59
- /**
60
- * Represents a resource created by `queryResource`. Extends `HttpResourceRef` with additional properties.
61
- */
62
- export type QueryResourceRef<TResult> = HttpResourceRef<TResult> & {
63
- /**
64
- * A signal indicating whether the resource is currently disabled (due to circuit breaker or undefined request).
65
- */
66
- disabled: Signal<boolean>;
67
- /**
68
- * Prefetches data for the resource, populating the cache if caching is enabled. This can be
69
- * used to proactively load data before it's needed. If a slow connection is detected, prefetching is skipped.
70
- *
71
- * @param req - Optional partial request parameters to use for the prefetch. This allows you
72
- * to prefetch data with different parameters than the main resource request.
73
- */
74
- prefetch: (req?: Partial<HttpResourceRequest>) => Promise<void>;
75
- };
76
- export declare function queryResource<TResult, TRaw = TResult>(request: () => HttpResourceRequest | undefined | void, options: QueryResourceOptions<TResult, TRaw> & {
77
- defaultValue: NoInfer<TResult>;
78
- }): QueryResourceRef<TResult>;
79
- /**
80
- * Creates an extended HTTP resource with features like caching, retries, refresh intervals,
81
- * circuit breaker, and optimistic updates. Without additional options it is equivalent to simply calling `httpResource`.
82
- *
83
- * @param request A function that returns the `HttpResourceRequest` to be made. This function
84
- * is called reactively, so the request can change over time. If the function
85
- * returns `undefined`, the resource is considered "disabled" and no request will be made.
86
- * @param options Configuration options for the resource. These options extend the basic
87
- * `HttpResourceOptions` and add features like `keepPrevious`, `refresh`, `retry`,
88
- * `onError`, `circuitBreaker`, and `cache`.
89
- * @returns An `QueryResourceRef` instance, which extends the basic `HttpResourceRef` with additional features.
90
- */
91
- export declare function queryResource<TResult, TRaw = TResult>(request: () => HttpResourceRequest | undefined | void, options?: QueryResourceOptions<TResult, TRaw>): QueryResourceRef<TResult | undefined>;
92
- export {};
@@ -1,177 +0,0 @@
1
- import type { HttpResponse } from '@angular/common/http';
2
- import { Injector, type Provider, type Signal } from '@angular/core';
3
- /**
4
- * Options for configuring the Least Recently Used (LRU) cache cleanup strategy.
5
- * @internal
6
- */
7
- type LRUCleanupType = {
8
- type: 'lru';
9
- /**
10
- * How often to check for expired or excess entries, in milliseconds.
11
- */
12
- checkInterval: number;
13
- /**
14
- * The maximum number of entries to keep in the cache. When the cache exceeds this size,
15
- * the least recently used entries will be removed.
16
- */
17
- maxSize: number;
18
- };
19
- /**
20
- * Options for configuring the "oldest first" cache cleanup strategy.
21
- * @internal
22
- */
23
- type OldsetCleanupType = {
24
- type: 'oldest';
25
- /**
26
- * How often to check for expired or excess entries, in milliseconds.
27
- */
28
- checkInterval: number;
29
- /**
30
- * The maximum number of entries to keep in the cache. When the cache exceeds this size,
31
- * the oldest entries will be removed.
32
- */
33
- maxSize: number;
34
- };
35
- /**
36
- * Represents an entry in the cache.
37
- * @internal
38
- */
39
- type CacheEntry<T> = {
40
- value: T;
41
- created: number;
42
- stale: number;
43
- useCount: number;
44
- expiresAt: number;
45
- timeout: ReturnType<typeof setTimeout>;
46
- };
47
- /**
48
- * Defines the types of cleanup strategies available for the cache.
49
- * - `lru`: Least Recently Used. Removes the least recently accessed entries when the cache is full.
50
- * - `oldest`: Removes the oldest entries when the cache is full.
51
- */
52
- export type CleanupType = LRUCleanupType | OldsetCleanupType;
53
- /**
54
- * A generic cache implementation that stores data with time-to-live (TTL) and stale-while-revalidate capabilities.
55
- *
56
- * @typeParam T - The type of data to be stored in the cache.
57
- */
58
- export declare class Cache<T> {
59
- protected readonly ttl: number;
60
- protected readonly staleTime: number;
61
- private readonly internal;
62
- private readonly cleanupOpt;
63
- /**
64
- * Creates a new `Cache` instance.
65
- *
66
- * @param ttl - The default Time To Live (TTL) for cache entries, in milliseconds. Defaults to one day.
67
- * @param staleTime - The default duration, in milliseconds, during which a cache entry is considered
68
- * stale but can still be used while revalidation occurs in the background. Defaults to 1 hour.
69
- * @param cleanupOpt - Options for configuring the cache cleanup strategy. Defaults to LRU with a
70
- * `maxSize` of 200 and a `checkInterval` of one hour.
71
- */
72
- constructor(ttl?: number, staleTime?: number, cleanupOpt?: Partial<CleanupType>);
73
- /** @internal */
74
- private getInternal;
75
- /**
76
- * Retrieves a cache entry without affecting its usage count (for LRU). This is primarily
77
- * for internal use or debugging.
78
- * @internal
79
- * @param key - The key of the entry to retrieve.
80
- * @returns The cache entry, or `null` if not found or expired.
81
- */
82
- getUntracked(key: string): (CacheEntry<T> & {
83
- isStale: boolean;
84
- }) | null;
85
- /**
86
- * Retrieves a cache entry as a signal.
87
- *
88
- * @param key - A function that returns the cache key. The key is a signal, allowing for dynamic keys. If the function returns null the value is also null.
89
- * @returns A signal that holds the cache entry, or `null` if not found or expired. The signal
90
- * updates whenever the cache entry changes (e.g., due to revalidation or expiration).
91
- */
92
- get(key: () => string | null): Signal<(CacheEntry<T> & {
93
- isStale: boolean;
94
- }) | null>;
95
- /**
96
- * Stores a value in the cache.
97
- *
98
- * @param key - The key under which to store the value.
99
- * @param value - The value to store.
100
- * @param staleTime - (Optional) The stale time for this entry, in milliseconds. Overrides the default `staleTime`.
101
- * @param ttl - (Optional) The TTL for this entry, in milliseconds. Overrides the default `ttl`.
102
- */
103
- store(key: string, value: T, staleTime?: number, ttl?: number): void;
104
- /**
105
- * Invalidates (removes) a cache entry.
106
- *
107
- * @param key - The key of the entry to invalidate.
108
- */
109
- invalidate(key: string): void;
110
- /** @internal */
111
- private cleanup;
112
- }
113
- /**
114
- * Options for configuring the cache.
115
- */
116
- type CacheOptions = {
117
- /**
118
- * The default Time To Live (TTL) for cache entries, in milliseconds.
119
- */
120
- ttl?: number;
121
- /**
122
- * The default duration, in milliseconds, during which a cache entry is considered
123
- * stale but can still be used while revalidation occurs in the background.
124
- */
125
- staleTime?: number;
126
- /**
127
- * Options for configuring the cache cleanup strategy.
128
- */
129
- cleanup?: Partial<CleanupType>;
130
- };
131
- /**
132
- * Provides the instance of the QueryCache for queryResource. This should probably be called
133
- * in your application's root configuration, but can also be overriden with component/module providers.
134
- *
135
- * @param options - Optional configuration options for the cache.
136
- * @returns An Angular `Provider` for the cache.
137
- *
138
- * @example
139
- * // In your app.config.ts or AppModule providers:
140
- *
141
- * import { provideQueryCache } from './your-cache';
142
- *
143
- * export const appConfig: ApplicationConfig = {
144
- * providers: [
145
- * provideQueryCache({
146
- * ttl: 60000, // Default TTL of 60 seconds
147
- * staleTime: 30000, // Default staleTime of 30 seconds
148
- * }),
149
- * // ... other providers
150
- * ]
151
- * };
152
- */
153
- export declare function provideQueryCache(opt?: CacheOptions): Provider;
154
- /**
155
- * Injects the `QueryCache` instance that is used within queryResource.
156
- * Allows for direct modification of cached data, but is mostly meant for internal use.
157
- *
158
- * @param injector - (Optional) The injector to use. If not provided, the current
159
- * injection context is used.
160
- * @returns The `QueryCache` instance.
161
- *
162
- * @example
163
- * // In your component or service:
164
- *
165
- * import { injectQueryCache } from './your-cache';
166
- *
167
- * constructor() {
168
- * const cache = injectQueryCache();
169
- *
170
- * const myData = cache.get(() => 'my-data-key');
171
- * if (myData() !== null) {
172
- * // ... use cached data ...
173
- * }
174
- * }
175
- */
176
- export declare function injectQueryCache(injector?: Injector): Cache<HttpResponse<unknown>>;
177
- export {};
@@ -1,39 +0,0 @@
1
- import { HttpContext, type HttpInterceptorFn } from '@angular/common/http';
2
- type CacheEntryOptions = {
3
- key?: string;
4
- ttl?: number;
5
- staleTime?: number;
6
- cache: boolean;
7
- };
8
- export declare function setCacheContext(ctx: HttpContext | undefined, opt: Omit<CacheEntryOptions, 'cache' | 'key'> & {
9
- key: Required<CacheEntryOptions>['key'];
10
- }): HttpContext;
11
- /**
12
- * Creates an `HttpInterceptorFn` that implements caching for HTTP requests. This interceptor
13
- * checks for a caching configuration in the request's `HttpContext` (internally set by the queryResource).
14
- * If caching is enabled, it attempts to retrieve responses from the cache. If a cached response
15
- * is found and is not stale, it's returned directly. If the cached response is stale, it's returned,
16
- * and a background revalidation request is made. If no cached response is found, the request
17
- * is made to the server, and the response is cached according to the configured TTL and staleness.
18
- * The interceptor also respects `Cache-Control` headers from the server.
19
- *
20
- * @param allowedMethods - An array of HTTP methods for which caching should be enabled.
21
- * Defaults to `['GET', 'HEAD', 'OPTIONS']`.
22
- *
23
- * @returns An `HttpInterceptorFn` that implements the caching logic.
24
- *
25
- * @example
26
- * // In your app.config.ts or module providers:
27
- *
28
- * import { provideHttpClient, withInterceptors } from '@angular/common/http';
29
- * import { createCacheInterceptor } from '@mmstack/resource';
30
- *
31
- * export const appConfig: ApplicationConfig = {
32
- * providers: [
33
- * provideHttpClient(withInterceptors([createCacheInterceptor()])),
34
- * // ... other providers
35
- * ],
36
- * };
37
- */
38
- export declare function createCacheInterceptor(allowedMethods?: string[]): HttpInterceptorFn;
39
- export {};
@@ -1,2 +0,0 @@
1
- export { Cache, injectQueryCache, provideQueryCache } from './cache';
2
- export * from './cache.interceptor';
@@ -1,2 +0,0 @@
1
- export { Cache, injectQueryCache, provideQueryCache } from './cache';
2
- export { createCacheInterceptor } from './cache.interceptor';
@@ -1,74 +0,0 @@
1
- import { Signal } from '@angular/core';
2
- /**
3
- * Represents the possible states of a circuit breaker.
4
- * - `CLOSED`: The circuit breaker is closed, and operations are allowed to proceed.
5
- * - `OPEN`: The circuit breaker is open, and operations are blocked.
6
- * - `HALF_OPEN`: The circuit breaker is in a half-open state, allowing a limited number of operations to test if the underlying issue is resolved.
7
- */
8
- type CircuitBreakerState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
9
- /**
10
- * Represents a circuit breaker, which monitors operations and prevents failures from cascading.
11
- */
12
- export type CircuitBreaker = {
13
- /**
14
- * A signal indicating whether the circuit breaker is currently closed (allowing operations).
15
- */
16
- isClosed: Signal<boolean>;
17
- /**
18
- * A signal representing the current state of the circuit breaker.
19
- */
20
- status: Signal<CircuitBreakerState>;
21
- /**
22
- * Signals a failure to the circuit breaker. This may cause the circuit breaker to open.
23
- */
24
- fail: () => void;
25
- /**
26
- * Signals a success to the circuit breaker. This may cause the circuit breaker to close.
27
- */
28
- success: () => void;
29
- /**
30
- * Attempts to transition the circuit breaker to the half-open state. This is typically used
31
- * to test if the underlying issue has been resolved after the circuit breaker has been open.
32
- */
33
- halfOpen: () => void;
34
- /**
35
- * Destroys the circuit breaker & initiates related cleanup
36
- */
37
- destroy: () => void;
38
- };
39
- /**
40
- * Options for creating a circuit breaker.
41
- * - `false`: Disables circuit breaker functionality (always open).
42
- * - true: Creates a new circuit breaker with default options.
43
- * - `CircuitBreaker`: Provides an existing `CircuitBreaker` instance to use.
44
- * - `{ treshold?: number; timeout?: number; }`: Creates a new circuit breaker with the specified options.
45
- */
46
- export type CircuitBreakerOptions = false | CircuitBreaker | {
47
- treshold?: number;
48
- timeout?: number;
49
- };
50
- /**
51
- * Creates a circuit breaker instance.
52
- *
53
- * @param options - Configuration options for the circuit breaker. Can be:
54
- * - `undefined`: Creates a "no-op" circuit breaker that is always open (never trips).
55
- * - `true`: Creates a circuit breaker with default settings (threshold: 5, timeout: 30000ms).
56
- * - `CircuitBreaker`: Reuses an existing `CircuitBreaker` instance.
57
- * - `{ threshold?: number; timeout?: number; }`: Creates a circuit breaker with the specified threshold and timeout.
58
- *
59
- * @returns A `CircuitBreaker` instance.
60
- *
61
- * @example
62
- * // Create a circuit breaker with default settings:
63
- * const breaker = createCircuitBreaker();
64
- *
65
- * // Create a circuit breaker with custom settings:
66
- * const customBreaker = createCircuitBreaker({ threshold: 10, timeout: 60000 });
67
- *
68
- * // Share a single circuit breaker instance across multiple resources:
69
- * const sharedBreaker = createCircuitBreaker();
70
- * const resource1 = queryResource(..., { circuitBreaker: sharedBreaker });
71
- * const resource2 = mutationResource(..., { circuitBreaker: sharedBreaker });
72
- */
73
- export declare function createCircuitBreaker(opt?: CircuitBreakerOptions): CircuitBreaker;
74
- export {};
@@ -1,50 +0,0 @@
1
- import { HttpContext, HttpInterceptorFn } from '@angular/common/http';
2
- /**
3
- * Disables request deduplication for a specific HTTP request.
4
- *
5
- * @param ctx - The `HttpContext` to modify. If not provided, a new `HttpContext` is created.
6
- * @returns The modified `HttpContext` with the `NO_DEDUPE` token set to `true`.
7
- *
8
- * @example
9
- * // Disable deduplication for a specific POST request:
10
- * const context = noDedupe();
11
- * this.http.post('/api/data', payload, { context }).subscribe(...);
12
- *
13
- * // Disable deduplication, modifying an existing context:
14
- * let context = new HttpContext();
15
- * context = noDedupe(context);
16
- * this.http.post('/api/data', payload, { context }).subscribe(...);
17
- */
18
- export declare function noDedupe(ctx?: HttpContext): HttpContext;
19
- /**
20
- * Creates an `HttpInterceptorFn` that deduplicates identical HTTP requests.
21
- * If multiple identical requests (same URL and parameters) are made concurrently,
22
- * only the first request will be sent to the server. Subsequent requests will
23
- * receive the response from the first request.
24
- *
25
- * @param allowed - An array of HTTP methods for which deduplication should be enabled.
26
- * Defaults to `['GET', 'DELETE', 'HEAD', 'OPTIONS']`.
27
- *
28
- * @returns An `HttpInterceptorFn` that implements the request deduplication logic.
29
- *
30
- * @example
31
- * // In your app.config.ts or module providers:
32
- * import { provideHttpClient, withInterceptors } from '@angular/common/http';
33
- * import { createDedupeRequestsInterceptor } from './your-dedupe-interceptor';
34
- *
35
- * export const appConfig: ApplicationConfig = {
36
- * providers: [
37
- * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor()])),
38
- * // ... other providers
39
- * ],
40
- * };
41
- *
42
- * // You can also specify which methods should be deduped
43
- * export const appConfig: ApplicationConfig = {
44
- * providers: [
45
- * provideHttpClient(withInterceptors([createDedupeRequestsInterceptor(['GET'])])), // only dedupe GET calls
46
- * // ... other providers
47
- * ],
48
- * };
49
- */
50
- export declare function createDedupeRequestsInterceptor(allowed?: string[]): HttpInterceptorFn;
@@ -1,3 +0,0 @@
1
- import { HttpResourceRequest } from '@angular/common/http';
2
- import { type ValueEqualityFn } from '@angular/core';
3
- export declare function createEqualRequest<TResult>(equalResult?: ValueEqualityFn<TResult>): (a: Partial<HttpResourceRequest> | undefined, b: Partial<HttpResourceRequest> | undefined) => boolean;
@@ -1 +0,0 @@
1
- export declare function hasSlowConnection(): boolean;
@@ -1,9 +0,0 @@
1
- export * from './cache';
2
- export * from './circuit-breaker';
3
- export * from './dedupe.interceptor';
4
- export * from './equality';
5
- export * from './has-slow-connection';
6
- export * from './persist';
7
- export * from './refresh';
8
- export * from './retry-on-error';
9
- export * from './url-with-params';
@@ -1,3 +0,0 @@
1
- import { type HttpResourceRef } from '@angular/common/http';
2
- import { type ValueEqualityFn } from '@angular/core';
3
- export declare function persistResourceValues<T>(resource: HttpResourceRef<T>, persist?: boolean, equal?: ValueEqualityFn<T>): HttpResourceRef<T>;
@@ -1,3 +0,0 @@
1
- export * from './cache/public_api';
2
- export { createCircuitBreaker } from './circuit-breaker';
3
- export { createDedupeRequestsInterceptor, noDedupe, } from './dedupe.interceptor';
@@ -1,3 +0,0 @@
1
- import { HttpResourceRef } from '@angular/common/http';
2
- import { DestroyRef } from '@angular/core';
3
- export declare function refresh<T>(resource: HttpResourceRef<T>, destroyRef: DestroyRef, refresh?: number): HttpResourceRef<T>;
@@ -1,6 +0,0 @@
1
- import { type HttpResourceRef } from '@angular/common/http';
2
- export type RetryOptions = number | {
3
- max?: number;
4
- backoff?: number;
5
- };
6
- export declare function retryOnError<T>(res: HttpResourceRef<T>, opt?: RetryOptions): HttpResourceRef<T>;
@@ -1,2 +0,0 @@
1
- import { HttpResourceRequest } from '@angular/common/http';
2
- export declare function urlWithParams(req: HttpResourceRequest): string;