@spoosh/plugin-invalidation 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +34 -18
- package/dist/index.mjs +34 -18
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -113,3 +113,28 @@ await trigger({
|
|
|
113
113
|
| `"all"` | Invalidate all tags from path hierarchy | `users/123/posts` → `users`, `users/123`, `users/123/posts` |
|
|
114
114
|
| `"self"` | Only invalidate the exact endpoint tag | `users/123/posts` → `users/123/posts` |
|
|
115
115
|
| `"none"` | Disable auto-invalidation (manual only) | No automatic invalidation |
|
|
116
|
+
|
|
117
|
+
## Instance API
|
|
118
|
+
|
|
119
|
+
The plugin exposes `invalidate` for manually triggering cache invalidation outside of mutations:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { createReactSpoosh } from "@spoosh/react";
|
|
123
|
+
|
|
124
|
+
const { useRead, invalidate } = createReactSpoosh(client);
|
|
125
|
+
|
|
126
|
+
// Invalidate with string array
|
|
127
|
+
invalidate(["users", "posts"]);
|
|
128
|
+
|
|
129
|
+
// Invalidate with callback (type-safe API selector)
|
|
130
|
+
invalidate((api) => [api.users.$get, api.posts.$get, "custom-tag"]);
|
|
131
|
+
|
|
132
|
+
// Useful for external events like WebSocket messages
|
|
133
|
+
socket.on("data-changed", (tags) => {
|
|
134
|
+
invalidate(tags);
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
| Method | Description |
|
|
139
|
+
| ---------------- | ------------------------------------------------------------------ |
|
|
140
|
+
| `invalidate` | Manually invalidate cache entries by tags or API selector callback |
|
package/dist/index.d.mts
CHANGED
|
@@ -17,6 +17,11 @@ type InvalidationReadOptions = object;
|
|
|
17
17
|
type InvalidationInfiniteReadOptions = object;
|
|
18
18
|
type InvalidationReadResult = object;
|
|
19
19
|
type InvalidationWriteResult = object;
|
|
20
|
+
type InvalidateFn<TSchema> = (tags: InvalidateOption<TSchema>) => void;
|
|
21
|
+
interface InvalidationInstanceApi {
|
|
22
|
+
/** Manually invalidate cache entries by tags. Useful for external events like WebSocket messages. */
|
|
23
|
+
invalidate: InvalidateFn<unknown>;
|
|
24
|
+
}
|
|
20
25
|
interface InvalidationPluginExports {
|
|
21
26
|
/** Set the default autoInvalidate behavior for this mutation */
|
|
22
27
|
setAutoInvalidateDefault: (value: AutoInvalidate) => void;
|
|
@@ -28,6 +33,9 @@ declare module "@spoosh/core" {
|
|
|
28
33
|
interface PluginResolvers<TContext> {
|
|
29
34
|
invalidate: InvalidateOption<TContext["schema"]> | undefined;
|
|
30
35
|
}
|
|
36
|
+
interface InstanceApiResolvers<TSchema> {
|
|
37
|
+
invalidate: InvalidateFn<TSchema>;
|
|
38
|
+
}
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
/**
|
|
@@ -62,6 +70,7 @@ declare function invalidationPlugin(config?: InvalidationPluginConfig): SpooshPl
|
|
|
62
70
|
infiniteReadOptions: InvalidationInfiniteReadOptions;
|
|
63
71
|
readResult: InvalidationReadResult;
|
|
64
72
|
writeResult: InvalidationWriteResult;
|
|
73
|
+
instanceApi: InvalidationInstanceApi;
|
|
65
74
|
}>;
|
|
66
75
|
|
|
67
76
|
export { type AutoInvalidate, type InvalidateOption, type InvalidationInfiniteReadOptions, type InvalidationPluginConfig, type InvalidationPluginExports, type InvalidationReadOptions, type InvalidationReadResult, type InvalidationWriteOptions, type InvalidationWriteResult, invalidationPlugin };
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,11 @@ type InvalidationReadOptions = object;
|
|
|
17
17
|
type InvalidationInfiniteReadOptions = object;
|
|
18
18
|
type InvalidationReadResult = object;
|
|
19
19
|
type InvalidationWriteResult = object;
|
|
20
|
+
type InvalidateFn<TSchema> = (tags: InvalidateOption<TSchema>) => void;
|
|
21
|
+
interface InvalidationInstanceApi {
|
|
22
|
+
/** Manually invalidate cache entries by tags. Useful for external events like WebSocket messages. */
|
|
23
|
+
invalidate: InvalidateFn<unknown>;
|
|
24
|
+
}
|
|
20
25
|
interface InvalidationPluginExports {
|
|
21
26
|
/** Set the default autoInvalidate behavior for this mutation */
|
|
22
27
|
setAutoInvalidateDefault: (value: AutoInvalidate) => void;
|
|
@@ -28,6 +33,9 @@ declare module "@spoosh/core" {
|
|
|
28
33
|
interface PluginResolvers<TContext> {
|
|
29
34
|
invalidate: InvalidateOption<TContext["schema"]> | undefined;
|
|
30
35
|
}
|
|
36
|
+
interface InstanceApiResolvers<TSchema> {
|
|
37
|
+
invalidate: InvalidateFn<TSchema>;
|
|
38
|
+
}
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
/**
|
|
@@ -62,6 +70,7 @@ declare function invalidationPlugin(config?: InvalidationPluginConfig): SpooshPl
|
|
|
62
70
|
infiniteReadOptions: InvalidationInfiniteReadOptions;
|
|
63
71
|
readResult: InvalidationReadResult;
|
|
64
72
|
writeResult: InvalidationWriteResult;
|
|
73
|
+
instanceApi: InvalidationInstanceApi;
|
|
65
74
|
}>;
|
|
66
75
|
|
|
67
76
|
export { type AutoInvalidate, type InvalidateOption, type InvalidationInfiniteReadOptions, type InvalidationPluginConfig, type InvalidationPluginExports, type InvalidationReadOptions, type InvalidationReadResult, type InvalidationWriteOptions, type InvalidationWriteResult, invalidationPlugin };
|
package/dist/index.js
CHANGED
|
@@ -27,29 +27,34 @@ module.exports = __toCommonJS(src_exports);
|
|
|
27
27
|
// src/plugin.ts
|
|
28
28
|
var import_core = require("@spoosh/core");
|
|
29
29
|
var INVALIDATION_DEFAULT_KEY = "invalidation:autoInvalidateDefault";
|
|
30
|
-
function
|
|
31
|
-
const pluginOptions = context.pluginOptions;
|
|
30
|
+
function resolveTagsFromOption(invalidate) {
|
|
32
31
|
const tags = [];
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
tags.push(exactTag);
|
|
48
|
-
}
|
|
32
|
+
if (Array.isArray(invalidate)) {
|
|
33
|
+
tags.push(...invalidate);
|
|
34
|
+
} else {
|
|
35
|
+
const proxy = (0, import_core.createSelectorProxy)();
|
|
36
|
+
const invalidationTargets = invalidate(proxy);
|
|
37
|
+
for (const target of invalidationTargets) {
|
|
38
|
+
if (typeof target === "string") {
|
|
39
|
+
tags.push(target);
|
|
40
|
+
} else {
|
|
41
|
+
const path = (0, import_core.extractPathFromSelector)(target);
|
|
42
|
+
const derivedTags = (0, import_core.generateTags)(path);
|
|
43
|
+
const exactTag = derivedTags[derivedTags.length - 1];
|
|
44
|
+
if (exactTag) {
|
|
45
|
+
tags.push(exactTag);
|
|
49
46
|
}
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
49
|
}
|
|
50
|
+
return tags;
|
|
51
|
+
}
|
|
52
|
+
function resolveInvalidateTags(context, defaultAutoInvalidate) {
|
|
53
|
+
const pluginOptions = context.pluginOptions;
|
|
54
|
+
const tags = [];
|
|
55
|
+
if (pluginOptions?.invalidate) {
|
|
56
|
+
tags.push(...resolveTagsFromOption(pluginOptions.invalidate));
|
|
57
|
+
}
|
|
53
58
|
const overrideDefault = context.metadata.get(INVALIDATION_DEFAULT_KEY);
|
|
54
59
|
const effectiveDefault = overrideDefault ?? defaultAutoInvalidate;
|
|
55
60
|
const autoInvalidate = pluginOptions?.autoInvalidate ?? effectiveDefault;
|
|
@@ -81,6 +86,17 @@ function invalidationPlugin(config = {}) {
|
|
|
81
86
|
context.eventEmitter.emit("invalidate", tags);
|
|
82
87
|
}
|
|
83
88
|
}
|
|
89
|
+
},
|
|
90
|
+
instanceApi(context) {
|
|
91
|
+
const { stateManager, eventEmitter } = context;
|
|
92
|
+
const invalidate = (input) => {
|
|
93
|
+
const tags = resolveTagsFromOption(input);
|
|
94
|
+
if (tags.length > 0) {
|
|
95
|
+
stateManager.markStale(tags);
|
|
96
|
+
eventEmitter.emit("invalidate", tags);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
return { invalidate };
|
|
84
100
|
}
|
|
85
101
|
};
|
|
86
102
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -5,29 +5,34 @@ import {
|
|
|
5
5
|
generateTags
|
|
6
6
|
} from "@spoosh/core";
|
|
7
7
|
var INVALIDATION_DEFAULT_KEY = "invalidation:autoInvalidateDefault";
|
|
8
|
-
function
|
|
9
|
-
const pluginOptions = context.pluginOptions;
|
|
8
|
+
function resolveTagsFromOption(invalidate) {
|
|
10
9
|
const tags = [];
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
tags.push(exactTag);
|
|
26
|
-
}
|
|
10
|
+
if (Array.isArray(invalidate)) {
|
|
11
|
+
tags.push(...invalidate);
|
|
12
|
+
} else {
|
|
13
|
+
const proxy = createSelectorProxy();
|
|
14
|
+
const invalidationTargets = invalidate(proxy);
|
|
15
|
+
for (const target of invalidationTargets) {
|
|
16
|
+
if (typeof target === "string") {
|
|
17
|
+
tags.push(target);
|
|
18
|
+
} else {
|
|
19
|
+
const path = extractPathFromSelector(target);
|
|
20
|
+
const derivedTags = generateTags(path);
|
|
21
|
+
const exactTag = derivedTags[derivedTags.length - 1];
|
|
22
|
+
if (exactTag) {
|
|
23
|
+
tags.push(exactTag);
|
|
27
24
|
}
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
27
|
}
|
|
28
|
+
return tags;
|
|
29
|
+
}
|
|
30
|
+
function resolveInvalidateTags(context, defaultAutoInvalidate) {
|
|
31
|
+
const pluginOptions = context.pluginOptions;
|
|
32
|
+
const tags = [];
|
|
33
|
+
if (pluginOptions?.invalidate) {
|
|
34
|
+
tags.push(...resolveTagsFromOption(pluginOptions.invalidate));
|
|
35
|
+
}
|
|
31
36
|
const overrideDefault = context.metadata.get(INVALIDATION_DEFAULT_KEY);
|
|
32
37
|
const effectiveDefault = overrideDefault ?? defaultAutoInvalidate;
|
|
33
38
|
const autoInvalidate = pluginOptions?.autoInvalidate ?? effectiveDefault;
|
|
@@ -59,6 +64,17 @@ function invalidationPlugin(config = {}) {
|
|
|
59
64
|
context.eventEmitter.emit("invalidate", tags);
|
|
60
65
|
}
|
|
61
66
|
}
|
|
67
|
+
},
|
|
68
|
+
instanceApi(context) {
|
|
69
|
+
const { stateManager, eventEmitter } = context;
|
|
70
|
+
const invalidate = (input) => {
|
|
71
|
+
const tags = resolveTagsFromOption(input);
|
|
72
|
+
if (tags.length > 0) {
|
|
73
|
+
stateManager.markStale(tags);
|
|
74
|
+
eventEmitter.emit("invalidate", tags);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
return { invalidate };
|
|
62
78
|
}
|
|
63
79
|
};
|
|
64
80
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spoosh/plugin-invalidation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Cache invalidation plugin for Spoosh - auto-invalidates after mutations",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@spoosh/core": ">=0.4.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@spoosh/core": "0.
|
|
39
|
+
"@spoosh/core": "0.5.0",
|
|
40
40
|
"@spoosh/test-utils": "0.1.5"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|