enlace 0.0.1-beta.17 → 0.0.1-beta.18
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 +35 -5
- package/dist/hook/index.d.mts +36 -7
- package/dist/hook/index.d.ts +36 -7
- package/dist/hook/index.js +14 -3
- package/dist/hook/index.mjs +14 -3
- package/dist/index.d.mts +36 -7
- package/dist/index.d.ts +36 -7
- package/dist/index.js +27 -2
- package/dist/index.mjs +27 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -523,16 +523,44 @@ const useAPI = enlaceHookReact<ApiSchema>(
|
|
|
523
523
|
Override auto-generated tags when needed:
|
|
524
524
|
|
|
525
525
|
```typescript
|
|
526
|
-
// Custom cache tags
|
|
526
|
+
// Custom cache tags (replaces auto-generated)
|
|
527
527
|
const { data } = useAPI((api) => api.posts.$get({ tags: ["my-custom-tag"] }));
|
|
528
528
|
|
|
529
|
-
// Custom revalidation tags
|
|
529
|
+
// Custom revalidation tags (replaces auto-generated)
|
|
530
530
|
trigger({
|
|
531
531
|
body: { title: "New" },
|
|
532
|
-
revalidateTags: ["posts", "dashboard"],
|
|
532
|
+
revalidateTags: ["posts", "dashboard"],
|
|
533
533
|
});
|
|
534
534
|
```
|
|
535
535
|
|
|
536
|
+
### Extending Auto-Generated Tags
|
|
537
|
+
|
|
538
|
+
Use `additionalTags` and `additionalRevalidateTags` to **merge** with auto-generated tags instead of replacing them:
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
// Extend cache tags (merges with auto-generated)
|
|
542
|
+
const { data } = useAPI((api) =>
|
|
543
|
+
api.posts.$get({ additionalTags: ["custom-tag"] })
|
|
544
|
+
);
|
|
545
|
+
// If autoGenerateTags produces ['posts'], final tags: ['posts', 'custom-tag']
|
|
546
|
+
|
|
547
|
+
// Extend revalidation tags (merges with auto-generated)
|
|
548
|
+
trigger({
|
|
549
|
+
body: { title: "New" },
|
|
550
|
+
additionalRevalidateTags: ["dashboard", "stats"],
|
|
551
|
+
});
|
|
552
|
+
// If autoRevalidateTags produces ['posts'], final tags: ['posts', 'dashboard', 'stats']
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
**Behavior:**
|
|
556
|
+
|
|
557
|
+
| Scenario | `tags` / `revalidateTags` | `additionalTags` / `additionalRevalidateTags` | Final Tags |
|
|
558
|
+
|----------|---------------------------|-----------------------------------------------|------------|
|
|
559
|
+
| Override | `['custom']` | - | `['custom']` |
|
|
560
|
+
| Extend auto | - | `['extra']` | `['posts', 'extra']` |
|
|
561
|
+
| Both | `['custom']` | `['extra']` | `['custom', 'extra']` |
|
|
562
|
+
| Neither | - | - | `['posts']` (auto) |
|
|
563
|
+
|
|
536
564
|
### Disable Auto-Revalidation
|
|
537
565
|
|
|
538
566
|
```typescript
|
|
@@ -710,8 +738,10 @@ type RequestOptions = {
|
|
|
710
738
|
body?: TBody; // Request body (JSON)
|
|
711
739
|
formData?: TFormData; // FormData fields (auto-converted, for file uploads)
|
|
712
740
|
headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>); // Request headers
|
|
713
|
-
tags?: string[]; // Cache tags (GET only)
|
|
714
|
-
|
|
741
|
+
tags?: string[]; // Cache tags - replaces auto-generated (GET only)
|
|
742
|
+
additionalTags?: string[]; // Cache tags - merges with auto-generated (GET only)
|
|
743
|
+
revalidateTags?: string[]; // Revalidation tags - replaces auto-generated
|
|
744
|
+
additionalRevalidateTags?: string[]; // Revalidation tags - merges with auto-generated
|
|
715
745
|
params?: Record<string, string | number>; // Dynamic path parameters
|
|
716
746
|
};
|
|
717
747
|
```
|
package/dist/hook/index.d.mts
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { EnlaceCallbackPayload, EnlaceErrorCallbackPayload, EnlaceResponse, WildcardClient, EnlaceClient, EnlaceOptions, EnlaceCallbacks } from 'enlace-core';
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Dynamic params option - only available when accessing dynamic URL segments.
|
|
5
|
+
* Used internally by the type system to conditionally show params option.
|
|
6
|
+
*/
|
|
7
|
+
type DynamicParamsOption = {
|
|
8
|
+
/**
|
|
9
|
+
* Path parameters for dynamic URL segments.
|
|
10
|
+
* Used to replace :paramName placeholders in the URL path.
|
|
11
|
+
* @example
|
|
12
|
+
* // With path api.products[':id'].delete
|
|
13
|
+
* trigger({ params: { id: '123' } }) // → DELETE /products/123
|
|
14
|
+
*/
|
|
15
|
+
params?: Record<string, string | number>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Per-request options for React hooks.
|
|
19
|
+
* The params option is only available when accessing dynamic URL segments (via _ or index access).
|
|
20
|
+
*/
|
|
4
21
|
type ReactRequestOptionsBase = {
|
|
5
22
|
/**
|
|
6
23
|
* Cache tags for caching (GET requests only)
|
|
@@ -8,17 +25,29 @@ type ReactRequestOptionsBase = {
|
|
|
8
25
|
* But can be manually specified to override auto-generation.
|
|
9
26
|
* */
|
|
10
27
|
tags?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Additional cache tags to merge with auto-generated tags.
|
|
30
|
+
* Use this when you want to extend (not replace) the auto-generated tags.
|
|
31
|
+
* @example
|
|
32
|
+
* api.posts.$get({ additionalTags: ['custom-tag'] })
|
|
33
|
+
* // If autoGenerateTags produces ['posts'], final tags: ['posts', 'custom-tag']
|
|
34
|
+
*/
|
|
35
|
+
additionalTags?: string[];
|
|
11
36
|
/** Tags to invalidate after mutation (triggers refetch in matching queries) */
|
|
12
37
|
revalidateTags?: string[];
|
|
13
38
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
39
|
+
* Additional revalidation tags to merge with auto-generated tags.
|
|
40
|
+
* Use this when you want to extend (not replace) the auto-generated revalidation tags.
|
|
16
41
|
* @example
|
|
17
|
-
*
|
|
18
|
-
*
|
|
42
|
+
* api.posts.$post({ body: {...}, additionalRevalidateTags: ['other-tag'] })
|
|
43
|
+
* // If autoRevalidateTags produces ['posts'], final tags: ['posts', 'other-tag']
|
|
19
44
|
*/
|
|
20
|
-
|
|
45
|
+
additionalRevalidateTags?: string[];
|
|
46
|
+
/** @internal Used by type system to conditionally include params */
|
|
47
|
+
__hasDynamicParams?: DynamicParamsOption;
|
|
21
48
|
};
|
|
49
|
+
/** Runtime request options that includes all possible properties */
|
|
50
|
+
type AnyReactRequestOptions = ReactRequestOptionsBase & DynamicParamsOption;
|
|
22
51
|
/** Polling interval value: milliseconds to wait, or false to stop polling */
|
|
23
52
|
type PollingIntervalValue = number | false;
|
|
24
53
|
/** Function that determines polling interval based on current data/error state */
|
|
@@ -201,4 +230,4 @@ type NextEnlaceHook<TSchema, TDefaultError = unknown> = {
|
|
|
201
230
|
*/
|
|
202
231
|
declare function enlaceHookNext<TSchema = unknown, TDefaultError = unknown>(baseUrl: string, defaultOptions?: EnlaceOptions, hookOptions?: NextHookOptions): NextEnlaceHook<TSchema, TDefaultError>;
|
|
203
232
|
|
|
204
|
-
export { type ApiClient, type EnlaceHook, type EnlaceHookOptions, HTTP_METHODS, type HookState, type NextEnlaceHook, type NextHookOptions, type PollingInterval, type PollingIntervalFn, type PollingIntervalValue, type QueryFn, type ReactRequestOptionsBase, type SelectorFn, type TrackedCall, type UseEnlaceQueryOptions, type UseEnlaceQueryResult, type UseEnlaceSelectorResult, enlaceHookNext, enlaceHookReact };
|
|
233
|
+
export { type AnyReactRequestOptions, type ApiClient, type EnlaceHook, type EnlaceHookOptions, HTTP_METHODS, type HookState, type NextEnlaceHook, type NextHookOptions, type PollingInterval, type PollingIntervalFn, type PollingIntervalValue, type QueryFn, type ReactRequestOptionsBase, type SelectorFn, type TrackedCall, type UseEnlaceQueryOptions, type UseEnlaceQueryResult, type UseEnlaceSelectorResult, enlaceHookNext, enlaceHookReact };
|
package/dist/hook/index.d.ts
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { EnlaceCallbackPayload, EnlaceErrorCallbackPayload, EnlaceResponse, WildcardClient, EnlaceClient, EnlaceOptions, EnlaceCallbacks } from 'enlace-core';
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Dynamic params option - only available when accessing dynamic URL segments.
|
|
5
|
+
* Used internally by the type system to conditionally show params option.
|
|
6
|
+
*/
|
|
7
|
+
type DynamicParamsOption = {
|
|
8
|
+
/**
|
|
9
|
+
* Path parameters for dynamic URL segments.
|
|
10
|
+
* Used to replace :paramName placeholders in the URL path.
|
|
11
|
+
* @example
|
|
12
|
+
* // With path api.products[':id'].delete
|
|
13
|
+
* trigger({ params: { id: '123' } }) // → DELETE /products/123
|
|
14
|
+
*/
|
|
15
|
+
params?: Record<string, string | number>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Per-request options for React hooks.
|
|
19
|
+
* The params option is only available when accessing dynamic URL segments (via _ or index access).
|
|
20
|
+
*/
|
|
4
21
|
type ReactRequestOptionsBase = {
|
|
5
22
|
/**
|
|
6
23
|
* Cache tags for caching (GET requests only)
|
|
@@ -8,17 +25,29 @@ type ReactRequestOptionsBase = {
|
|
|
8
25
|
* But can be manually specified to override auto-generation.
|
|
9
26
|
* */
|
|
10
27
|
tags?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Additional cache tags to merge with auto-generated tags.
|
|
30
|
+
* Use this when you want to extend (not replace) the auto-generated tags.
|
|
31
|
+
* @example
|
|
32
|
+
* api.posts.$get({ additionalTags: ['custom-tag'] })
|
|
33
|
+
* // If autoGenerateTags produces ['posts'], final tags: ['posts', 'custom-tag']
|
|
34
|
+
*/
|
|
35
|
+
additionalTags?: string[];
|
|
11
36
|
/** Tags to invalidate after mutation (triggers refetch in matching queries) */
|
|
12
37
|
revalidateTags?: string[];
|
|
13
38
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
39
|
+
* Additional revalidation tags to merge with auto-generated tags.
|
|
40
|
+
* Use this when you want to extend (not replace) the auto-generated revalidation tags.
|
|
16
41
|
* @example
|
|
17
|
-
*
|
|
18
|
-
*
|
|
42
|
+
* api.posts.$post({ body: {...}, additionalRevalidateTags: ['other-tag'] })
|
|
43
|
+
* // If autoRevalidateTags produces ['posts'], final tags: ['posts', 'other-tag']
|
|
19
44
|
*/
|
|
20
|
-
|
|
45
|
+
additionalRevalidateTags?: string[];
|
|
46
|
+
/** @internal Used by type system to conditionally include params */
|
|
47
|
+
__hasDynamicParams?: DynamicParamsOption;
|
|
21
48
|
};
|
|
49
|
+
/** Runtime request options that includes all possible properties */
|
|
50
|
+
type AnyReactRequestOptions = ReactRequestOptionsBase & DynamicParamsOption;
|
|
22
51
|
/** Polling interval value: milliseconds to wait, or false to stop polling */
|
|
23
52
|
type PollingIntervalValue = number | false;
|
|
24
53
|
/** Function that determines polling interval based on current data/error state */
|
|
@@ -201,4 +230,4 @@ type NextEnlaceHook<TSchema, TDefaultError = unknown> = {
|
|
|
201
230
|
*/
|
|
202
231
|
declare function enlaceHookNext<TSchema = unknown, TDefaultError = unknown>(baseUrl: string, defaultOptions?: EnlaceOptions, hookOptions?: NextHookOptions): NextEnlaceHook<TSchema, TDefaultError>;
|
|
203
232
|
|
|
204
|
-
export { type ApiClient, type EnlaceHook, type EnlaceHookOptions, HTTP_METHODS, type HookState, type NextEnlaceHook, type NextHookOptions, type PollingInterval, type PollingIntervalFn, type PollingIntervalValue, type QueryFn, type ReactRequestOptionsBase, type SelectorFn, type TrackedCall, type UseEnlaceQueryOptions, type UseEnlaceQueryResult, type UseEnlaceSelectorResult, enlaceHookNext, enlaceHookReact };
|
|
233
|
+
export { type AnyReactRequestOptions, type ApiClient, type EnlaceHook, type EnlaceHookOptions, HTTP_METHODS, type HookState, type NextEnlaceHook, type NextHookOptions, type PollingInterval, type PollingIntervalFn, type PollingIntervalValue, type QueryFn, type ReactRequestOptionsBase, type SelectorFn, type TrackedCall, type UseEnlaceQueryOptions, type UseEnlaceQueryResult, type UseEnlaceSelectorResult, enlaceHookNext, enlaceHookReact };
|
package/dist/hook/index.js
CHANGED
|
@@ -204,7 +204,8 @@ function useQueryMode(api, trackedCall, options) {
|
|
|
204
204
|
const queryKey = createQueryKey(trackedCall);
|
|
205
205
|
const requestOptions = trackedCall.options;
|
|
206
206
|
const resolvedPath = resolvePath(trackedCall.path, requestOptions?.params);
|
|
207
|
-
const
|
|
207
|
+
const baseTags = requestOptions?.tags ?? (autoGenerateTags ? generateTags(resolvedPath) : []);
|
|
208
|
+
const queryTags = [...baseTags, ...requestOptions?.additionalTags ?? []];
|
|
208
209
|
const getCacheState = (includeNeedsFetch = false) => {
|
|
209
210
|
const cached = getCache(queryKey);
|
|
210
211
|
const hasCachedData = cached?.data !== void 0;
|
|
@@ -329,7 +330,13 @@ function useQueryMode(api, trackedCall, options) {
|
|
|
329
330
|
}
|
|
330
331
|
|
|
331
332
|
// src/react/types.ts
|
|
332
|
-
var HTTP_METHODS = [
|
|
333
|
+
var HTTP_METHODS = [
|
|
334
|
+
"$get",
|
|
335
|
+
"$post",
|
|
336
|
+
"$put",
|
|
337
|
+
"$patch",
|
|
338
|
+
"$delete"
|
|
339
|
+
];
|
|
333
340
|
|
|
334
341
|
// src/react/trackingProxy.ts
|
|
335
342
|
function createTrackingProxy(onTrack) {
|
|
@@ -499,7 +506,11 @@ async function executeNextFetch(baseUrl, path, method, combinedOptions, requestO
|
|
|
499
506
|
if (!isGet) {
|
|
500
507
|
const shouldRevalidateServer = requestOptions?.serverRevalidate ?? !skipServerRevalidation;
|
|
501
508
|
if (shouldRevalidateServer) {
|
|
502
|
-
const
|
|
509
|
+
const baseRevalidateTags = requestOptions?.revalidateTags ?? (autoRevalidateTags ? autoTags : []);
|
|
510
|
+
const revalidateTags = [
|
|
511
|
+
...baseRevalidateTags,
|
|
512
|
+
...requestOptions?.additionalRevalidateTags ?? []
|
|
513
|
+
];
|
|
503
514
|
const revalidatePaths = requestOptions?.revalidatePaths ?? [];
|
|
504
515
|
if (revalidateTags.length || revalidatePaths.length) {
|
|
505
516
|
serverRevalidator?.(revalidateTags, revalidatePaths);
|
package/dist/hook/index.mjs
CHANGED
|
@@ -179,7 +179,8 @@ function useQueryMode(api, trackedCall, options) {
|
|
|
179
179
|
const queryKey = createQueryKey(trackedCall);
|
|
180
180
|
const requestOptions = trackedCall.options;
|
|
181
181
|
const resolvedPath = resolvePath(trackedCall.path, requestOptions?.params);
|
|
182
|
-
const
|
|
182
|
+
const baseTags = requestOptions?.tags ?? (autoGenerateTags ? generateTags(resolvedPath) : []);
|
|
183
|
+
const queryTags = [...baseTags, ...requestOptions?.additionalTags ?? []];
|
|
183
184
|
const getCacheState = (includeNeedsFetch = false) => {
|
|
184
185
|
const cached = getCache(queryKey);
|
|
185
186
|
const hasCachedData = cached?.data !== void 0;
|
|
@@ -304,7 +305,13 @@ function useQueryMode(api, trackedCall, options) {
|
|
|
304
305
|
}
|
|
305
306
|
|
|
306
307
|
// src/react/types.ts
|
|
307
|
-
var HTTP_METHODS = [
|
|
308
|
+
var HTTP_METHODS = [
|
|
309
|
+
"$get",
|
|
310
|
+
"$post",
|
|
311
|
+
"$put",
|
|
312
|
+
"$patch",
|
|
313
|
+
"$delete"
|
|
314
|
+
];
|
|
308
315
|
|
|
309
316
|
// src/react/trackingProxy.ts
|
|
310
317
|
function createTrackingProxy(onTrack) {
|
|
@@ -478,7 +485,11 @@ async function executeNextFetch(baseUrl, path, method, combinedOptions, requestO
|
|
|
478
485
|
if (!isGet) {
|
|
479
486
|
const shouldRevalidateServer = requestOptions?.serverRevalidate ?? !skipServerRevalidation;
|
|
480
487
|
if (shouldRevalidateServer) {
|
|
481
|
-
const
|
|
488
|
+
const baseRevalidateTags = requestOptions?.revalidateTags ?? (autoRevalidateTags ? autoTags : []);
|
|
489
|
+
const revalidateTags = [
|
|
490
|
+
...baseRevalidateTags,
|
|
491
|
+
...requestOptions?.additionalRevalidateTags ?? []
|
|
492
|
+
];
|
|
482
493
|
const revalidatePaths = requestOptions?.revalidatePaths ?? [];
|
|
483
494
|
if (revalidateTags.length || revalidatePaths.length) {
|
|
484
495
|
serverRevalidator?.(revalidateTags, revalidatePaths);
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import { EnlaceCallbackPayload, EnlaceErrorCallbackPayload, EnlaceCallbacks, EnlaceOptions, WildcardClient, EnlaceClient } from 'enlace-core';
|
|
2
2
|
export * from 'enlace-core';
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Dynamic params option - only available when accessing dynamic URL segments.
|
|
6
|
+
* Used internally by the type system to conditionally show params option.
|
|
7
|
+
*/
|
|
8
|
+
type DynamicParamsOption = {
|
|
9
|
+
/**
|
|
10
|
+
* Path parameters for dynamic URL segments.
|
|
11
|
+
* Used to replace :paramName placeholders in the URL path.
|
|
12
|
+
* @example
|
|
13
|
+
* // With path api.products[':id'].delete
|
|
14
|
+
* trigger({ params: { id: '123' } }) // → DELETE /products/123
|
|
15
|
+
*/
|
|
16
|
+
params?: Record<string, string | number>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Per-request options for React hooks.
|
|
20
|
+
* The params option is only available when accessing dynamic URL segments (via _ or index access).
|
|
21
|
+
*/
|
|
5
22
|
type ReactRequestOptionsBase = {
|
|
6
23
|
/**
|
|
7
24
|
* Cache tags for caching (GET requests only)
|
|
@@ -9,16 +26,26 @@ type ReactRequestOptionsBase = {
|
|
|
9
26
|
* But can be manually specified to override auto-generation.
|
|
10
27
|
* */
|
|
11
28
|
tags?: string[];
|
|
29
|
+
/**
|
|
30
|
+
* Additional cache tags to merge with auto-generated tags.
|
|
31
|
+
* Use this when you want to extend (not replace) the auto-generated tags.
|
|
32
|
+
* @example
|
|
33
|
+
* api.posts.$get({ additionalTags: ['custom-tag'] })
|
|
34
|
+
* // If autoGenerateTags produces ['posts'], final tags: ['posts', 'custom-tag']
|
|
35
|
+
*/
|
|
36
|
+
additionalTags?: string[];
|
|
12
37
|
/** Tags to invalidate after mutation (triggers refetch in matching queries) */
|
|
13
38
|
revalidateTags?: string[];
|
|
14
39
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
40
|
+
* Additional revalidation tags to merge with auto-generated tags.
|
|
41
|
+
* Use this when you want to extend (not replace) the auto-generated revalidation tags.
|
|
17
42
|
* @example
|
|
18
|
-
*
|
|
19
|
-
*
|
|
43
|
+
* api.posts.$post({ body: {...}, additionalRevalidateTags: ['other-tag'] })
|
|
44
|
+
* // If autoRevalidateTags produces ['posts'], final tags: ['posts', 'other-tag']
|
|
20
45
|
*/
|
|
21
|
-
|
|
46
|
+
additionalRevalidateTags?: string[];
|
|
47
|
+
/** @internal Used by type system to conditionally include params */
|
|
48
|
+
__hasDynamicParams?: DynamicParamsOption;
|
|
22
49
|
};
|
|
23
50
|
/** Options for enlaceHookReact factory */
|
|
24
51
|
type EnlaceHookOptions = {
|
|
@@ -85,4 +112,6 @@ type NextRequestOptionsBase = ReactRequestOptionsBase & {
|
|
|
85
112
|
|
|
86
113
|
declare function enlaceNext<TSchema = unknown, TDefaultError = unknown>(baseUrl: string, defaultOptions?: EnlaceOptions | null, nextOptions?: NextOptions): unknown extends TSchema ? WildcardClient<NextRequestOptionsBase> : EnlaceClient<TSchema, TDefaultError, NextRequestOptionsBase>;
|
|
87
114
|
|
|
88
|
-
|
|
115
|
+
declare function invalidateTags(tags: string[]): void;
|
|
116
|
+
|
|
117
|
+
export { type NextOptions, type NextRequestOptionsBase, enlaceNext, invalidateTags };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import { EnlaceCallbackPayload, EnlaceErrorCallbackPayload, EnlaceCallbacks, EnlaceOptions, WildcardClient, EnlaceClient } from 'enlace-core';
|
|
2
2
|
export * from 'enlace-core';
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Dynamic params option - only available when accessing dynamic URL segments.
|
|
6
|
+
* Used internally by the type system to conditionally show params option.
|
|
7
|
+
*/
|
|
8
|
+
type DynamicParamsOption = {
|
|
9
|
+
/**
|
|
10
|
+
* Path parameters for dynamic URL segments.
|
|
11
|
+
* Used to replace :paramName placeholders in the URL path.
|
|
12
|
+
* @example
|
|
13
|
+
* // With path api.products[':id'].delete
|
|
14
|
+
* trigger({ params: { id: '123' } }) // → DELETE /products/123
|
|
15
|
+
*/
|
|
16
|
+
params?: Record<string, string | number>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Per-request options for React hooks.
|
|
20
|
+
* The params option is only available when accessing dynamic URL segments (via _ or index access).
|
|
21
|
+
*/
|
|
5
22
|
type ReactRequestOptionsBase = {
|
|
6
23
|
/**
|
|
7
24
|
* Cache tags for caching (GET requests only)
|
|
@@ -9,16 +26,26 @@ type ReactRequestOptionsBase = {
|
|
|
9
26
|
* But can be manually specified to override auto-generation.
|
|
10
27
|
* */
|
|
11
28
|
tags?: string[];
|
|
29
|
+
/**
|
|
30
|
+
* Additional cache tags to merge with auto-generated tags.
|
|
31
|
+
* Use this when you want to extend (not replace) the auto-generated tags.
|
|
32
|
+
* @example
|
|
33
|
+
* api.posts.$get({ additionalTags: ['custom-tag'] })
|
|
34
|
+
* // If autoGenerateTags produces ['posts'], final tags: ['posts', 'custom-tag']
|
|
35
|
+
*/
|
|
36
|
+
additionalTags?: string[];
|
|
12
37
|
/** Tags to invalidate after mutation (triggers refetch in matching queries) */
|
|
13
38
|
revalidateTags?: string[];
|
|
14
39
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
40
|
+
* Additional revalidation tags to merge with auto-generated tags.
|
|
41
|
+
* Use this when you want to extend (not replace) the auto-generated revalidation tags.
|
|
17
42
|
* @example
|
|
18
|
-
*
|
|
19
|
-
*
|
|
43
|
+
* api.posts.$post({ body: {...}, additionalRevalidateTags: ['other-tag'] })
|
|
44
|
+
* // If autoRevalidateTags produces ['posts'], final tags: ['posts', 'other-tag']
|
|
20
45
|
*/
|
|
21
|
-
|
|
46
|
+
additionalRevalidateTags?: string[];
|
|
47
|
+
/** @internal Used by type system to conditionally include params */
|
|
48
|
+
__hasDynamicParams?: DynamicParamsOption;
|
|
22
49
|
};
|
|
23
50
|
/** Options for enlaceHookReact factory */
|
|
24
51
|
type EnlaceHookOptions = {
|
|
@@ -85,4 +112,6 @@ type NextRequestOptionsBase = ReactRequestOptionsBase & {
|
|
|
85
112
|
|
|
86
113
|
declare function enlaceNext<TSchema = unknown, TDefaultError = unknown>(baseUrl: string, defaultOptions?: EnlaceOptions | null, nextOptions?: NextOptions): unknown extends TSchema ? WildcardClient<NextRequestOptionsBase> : EnlaceClient<TSchema, TDefaultError, NextRequestOptionsBase>;
|
|
87
114
|
|
|
88
|
-
|
|
115
|
+
declare function invalidateTags(tags: string[]): void;
|
|
116
|
+
|
|
117
|
+
export { type NextOptions, type NextRequestOptionsBase, enlaceNext, invalidateTags };
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var src_exports = {};
|
|
23
23
|
__export(src_exports, {
|
|
24
|
-
enlaceNext: () => enlaceNext
|
|
24
|
+
enlaceNext: () => enlaceNext,
|
|
25
|
+
invalidateTags: () => invalidateTags
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(src_exports);
|
|
27
28
|
__reExport(src_exports, require("enlace-core"), module.exports);
|
|
@@ -53,7 +54,11 @@ async function executeNextFetch(baseUrl, path, method, combinedOptions, requestO
|
|
|
53
54
|
if (!isGet) {
|
|
54
55
|
const shouldRevalidateServer = requestOptions?.serverRevalidate ?? !skipServerRevalidation;
|
|
55
56
|
if (shouldRevalidateServer) {
|
|
56
|
-
const
|
|
57
|
+
const baseRevalidateTags = requestOptions?.revalidateTags ?? (autoRevalidateTags ? autoTags : []);
|
|
58
|
+
const revalidateTags = [
|
|
59
|
+
...baseRevalidateTags,
|
|
60
|
+
...requestOptions?.additionalRevalidateTags ?? []
|
|
61
|
+
];
|
|
57
62
|
const revalidatePaths = requestOptions?.revalidatePaths ?? [];
|
|
58
63
|
if (revalidateTags.length || revalidatePaths.length) {
|
|
59
64
|
serverRevalidator?.(revalidateTags, revalidatePaths);
|
|
@@ -93,3 +98,23 @@ function enlaceNext(baseUrl, defaultOptions = {}, nextOptions = {}) {
|
|
|
93
98
|
executeNextFetch
|
|
94
99
|
);
|
|
95
100
|
}
|
|
101
|
+
|
|
102
|
+
// src/react/cache.ts
|
|
103
|
+
var cache = /* @__PURE__ */ new Map();
|
|
104
|
+
function clearCacheByTags(tags) {
|
|
105
|
+
cache.forEach((entry) => {
|
|
106
|
+
const hasMatch = entry.tags.some((tag) => tags.includes(tag));
|
|
107
|
+
if (hasMatch) {
|
|
108
|
+
entry.timestamp = 0;
|
|
109
|
+
delete entry.promise;
|
|
110
|
+
entry.subscribers.forEach((cb) => cb());
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// src/react/revalidator.ts
|
|
116
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
117
|
+
function invalidateTags(tags) {
|
|
118
|
+
clearCacheByTags(tags);
|
|
119
|
+
listeners.forEach((listener) => listener(tags));
|
|
120
|
+
}
|
package/dist/index.mjs
CHANGED
|
@@ -32,7 +32,11 @@ async function executeNextFetch(baseUrl, path, method, combinedOptions, requestO
|
|
|
32
32
|
if (!isGet) {
|
|
33
33
|
const shouldRevalidateServer = requestOptions?.serverRevalidate ?? !skipServerRevalidation;
|
|
34
34
|
if (shouldRevalidateServer) {
|
|
35
|
-
const
|
|
35
|
+
const baseRevalidateTags = requestOptions?.revalidateTags ?? (autoRevalidateTags ? autoTags : []);
|
|
36
|
+
const revalidateTags = [
|
|
37
|
+
...baseRevalidateTags,
|
|
38
|
+
...requestOptions?.additionalRevalidateTags ?? []
|
|
39
|
+
];
|
|
36
40
|
const revalidatePaths = requestOptions?.revalidatePaths ?? [];
|
|
37
41
|
if (revalidateTags.length || revalidatePaths.length) {
|
|
38
42
|
serverRevalidator?.(revalidateTags, revalidatePaths);
|
|
@@ -72,6 +76,27 @@ function enlaceNext(baseUrl, defaultOptions = {}, nextOptions = {}) {
|
|
|
72
76
|
executeNextFetch
|
|
73
77
|
);
|
|
74
78
|
}
|
|
79
|
+
|
|
80
|
+
// src/react/cache.ts
|
|
81
|
+
var cache = /* @__PURE__ */ new Map();
|
|
82
|
+
function clearCacheByTags(tags) {
|
|
83
|
+
cache.forEach((entry) => {
|
|
84
|
+
const hasMatch = entry.tags.some((tag) => tags.includes(tag));
|
|
85
|
+
if (hasMatch) {
|
|
86
|
+
entry.timestamp = 0;
|
|
87
|
+
delete entry.promise;
|
|
88
|
+
entry.subscribers.forEach((cb) => cb());
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// src/react/revalidator.ts
|
|
94
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
95
|
+
function invalidateTags(tags) {
|
|
96
|
+
clearCacheByTags(tags);
|
|
97
|
+
listeners.forEach((listener) => listener(tags));
|
|
98
|
+
}
|
|
75
99
|
export {
|
|
76
|
-
enlaceNext
|
|
100
|
+
enlaceNext,
|
|
101
|
+
invalidateTags
|
|
77
102
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enlace",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.18",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"enlace-core": "0.0.1-beta.
|
|
21
|
+
"enlace-core": "0.0.1-beta.11"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"react": "^19"
|