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 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"], // Override auto-generated
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
- revalidateTags?: string[]; // Tags to invalidate after mutation
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
  ```
@@ -1,6 +1,23 @@
1
1
  import { EnlaceCallbackPayload, EnlaceErrorCallbackPayload, EnlaceResponse, WildcardClient, EnlaceClient, EnlaceOptions, EnlaceCallbacks } from 'enlace-core';
2
2
 
3
- /** Per-request options for React hooks */
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
- * Path parameters for dynamic URL segments.
15
- * Used to replace :paramName placeholders in the URL path.
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
- * // With path api.products[':id'].delete
18
- * trigger({ params: { id: '123' } }) // → DELETE /products/123
42
+ * api.posts.$post({ body: {...}, additionalRevalidateTags: ['other-tag'] })
43
+ * // If autoRevalidateTags produces ['posts'], final tags: ['posts', 'other-tag']
19
44
  */
20
- params?: Record<string, string | number>;
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 };
@@ -1,6 +1,23 @@
1
1
  import { EnlaceCallbackPayload, EnlaceErrorCallbackPayload, EnlaceResponse, WildcardClient, EnlaceClient, EnlaceOptions, EnlaceCallbacks } from 'enlace-core';
2
2
 
3
- /** Per-request options for React hooks */
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
- * Path parameters for dynamic URL segments.
15
- * Used to replace :paramName placeholders in the URL path.
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
- * // With path api.products[':id'].delete
18
- * trigger({ params: { id: '123' } }) // → DELETE /products/123
42
+ * api.posts.$post({ body: {...}, additionalRevalidateTags: ['other-tag'] })
43
+ * // If autoRevalidateTags produces ['posts'], final tags: ['posts', 'other-tag']
19
44
  */
20
- params?: Record<string, string | number>;
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 };
@@ -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 queryTags = requestOptions?.tags ?? (autoGenerateTags ? generateTags(resolvedPath) : []);
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 = ["$get", "$post", "$put", "$patch", "$delete"];
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 revalidateTags = requestOptions?.revalidateTags ?? (autoRevalidateTags ? autoTags : []);
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);
@@ -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 queryTags = requestOptions?.tags ?? (autoGenerateTags ? generateTags(resolvedPath) : []);
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 = ["$get", "$post", "$put", "$patch", "$delete"];
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 revalidateTags = requestOptions?.revalidateTags ?? (autoRevalidateTags ? autoTags : []);
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
- /** Per-request options for React hooks */
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
- * Path parameters for dynamic URL segments.
16
- * Used to replace :paramName placeholders in the URL path.
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
- * // With path api.products[':id'].delete
19
- * trigger({ params: { id: '123' } }) // → DELETE /products/123
43
+ * api.posts.$post({ body: {...}, additionalRevalidateTags: ['other-tag'] })
44
+ * // If autoRevalidateTags produces ['posts'], final tags: ['posts', 'other-tag']
20
45
  */
21
- params?: Record<string, string | number>;
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
- export { type NextOptions, type NextRequestOptionsBase, enlaceNext };
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
- /** Per-request options for React hooks */
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
- * Path parameters for dynamic URL segments.
16
- * Used to replace :paramName placeholders in the URL path.
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
- * // With path api.products[':id'].delete
19
- * trigger({ params: { id: '123' } }) // → DELETE /products/123
43
+ * api.posts.$post({ body: {...}, additionalRevalidateTags: ['other-tag'] })
44
+ * // If autoRevalidateTags produces ['posts'], final tags: ['posts', 'other-tag']
20
45
  */
21
- params?: Record<string, string | number>;
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
- export { type NextOptions, type NextRequestOptionsBase, enlaceNext };
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 revalidateTags = requestOptions?.revalidateTags ?? (autoRevalidateTags ? autoTags : []);
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 revalidateTags = requestOptions?.revalidateTags ?? (autoRevalidateTags ? autoTags : []);
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.17",
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.10"
21
+ "enlace-core": "0.0.1-beta.11"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": "^19"