@spoosh/plugin-debounce 0.2.5 → 0.3.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 +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +29 -1
- package/dist/index.mjs +29 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npm install @spoosh/plugin-debounce
|
|
|
16
16
|
import { Spoosh } from "@spoosh/core";
|
|
17
17
|
import { debouncePlugin } from "@spoosh/plugin-debounce";
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const spoosh = new Spoosh<ApiSchema, Error>("/api").use([debouncePlugin()]);
|
|
20
20
|
|
|
21
21
|
// Wait 300ms after typing stops before fetching
|
|
22
22
|
const { data } = useRead(
|
package/dist/index.d.mts
CHANGED
|
@@ -39,7 +39,7 @@ declare module "@spoosh/core" {
|
|
|
39
39
|
* ```ts
|
|
40
40
|
* import { Spoosh } from "@spoosh/core";
|
|
41
41
|
*
|
|
42
|
-
* const
|
|
42
|
+
* const spoosh = new Spoosh<ApiSchema, Error>("/api")
|
|
43
43
|
* .use([
|
|
44
44
|
* // ... other plugins
|
|
45
45
|
* debouncePlugin(),
|
package/dist/index.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ declare module "@spoosh/core" {
|
|
|
39
39
|
* ```ts
|
|
40
40
|
* import { Spoosh } from "@spoosh/core";
|
|
41
41
|
*
|
|
42
|
-
* const
|
|
42
|
+
* const spoosh = new Spoosh<ApiSchema, Error>("/api")
|
|
43
43
|
* .use([
|
|
44
44
|
* // ... other plugins
|
|
45
45
|
* debouncePlugin(),
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(src_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(src_exports);
|
|
26
26
|
|
|
27
27
|
// src/plugin.ts
|
|
28
|
+
var PLUGIN_NAME = "spoosh:debounce";
|
|
28
29
|
function resolveDebounceMs(debounce, context) {
|
|
29
30
|
if (debounce === void 0) return 0;
|
|
30
31
|
if (typeof debounce === "number") return debounce;
|
|
@@ -34,8 +35,9 @@ function debouncePlugin() {
|
|
|
34
35
|
const timers = /* @__PURE__ */ new Map();
|
|
35
36
|
const latestQueryKeys = /* @__PURE__ */ new Map();
|
|
36
37
|
const prevRequests = /* @__PURE__ */ new Map();
|
|
38
|
+
const eventTracers = /* @__PURE__ */ new Map();
|
|
37
39
|
return {
|
|
38
|
-
name:
|
|
40
|
+
name: PLUGIN_NAME,
|
|
39
41
|
operations: ["read", "infiniteRead"],
|
|
40
42
|
lifecycle: {
|
|
41
43
|
onUnmount: (context) => {
|
|
@@ -51,9 +53,12 @@ function debouncePlugin() {
|
|
|
51
53
|
}
|
|
52
54
|
},
|
|
53
55
|
middleware: async (context, next) => {
|
|
56
|
+
const t = context.tracer?.(PLUGIN_NAME);
|
|
57
|
+
const et = context.eventTracer?.(PLUGIN_NAME);
|
|
54
58
|
const pluginOptions = context.pluginOptions;
|
|
55
59
|
const debounceOption = pluginOptions?.debounce;
|
|
56
60
|
if (debounceOption === void 0 || context.forceRefetch) {
|
|
61
|
+
t?.skip("No debounce configured");
|
|
57
62
|
return next();
|
|
58
63
|
}
|
|
59
64
|
const { queryKey, request, path, method } = context;
|
|
@@ -74,26 +79,47 @@ function debouncePlugin() {
|
|
|
74
79
|
const debounceMs = resolveDebounceMs(debounceOption, prevContext);
|
|
75
80
|
prevRequests.set(stableKey, currentRequest);
|
|
76
81
|
if (!debounceMs || debounceMs <= 0) {
|
|
82
|
+
t?.skip("Debounce resolved to 0");
|
|
77
83
|
return next();
|
|
78
84
|
}
|
|
79
85
|
const existingQueryKey = latestQueryKeys.get(stableKey);
|
|
80
86
|
if (existingQueryKey === queryKey) {
|
|
81
87
|
const cached2 = context.stateManager.getCache(queryKey);
|
|
82
88
|
if (cached2?.state?.data !== void 0) {
|
|
89
|
+
t?.return("Already debouncing, returning cached", { color: "muted" });
|
|
83
90
|
return { data: cached2.state.data, status: 200 };
|
|
84
91
|
}
|
|
92
|
+
t?.return("Already debouncing", { color: "muted" });
|
|
85
93
|
return { data: void 0, status: 0 };
|
|
86
94
|
}
|
|
87
95
|
const existingTimer = timers.get(stableKey);
|
|
88
96
|
if (existingTimer) {
|
|
89
97
|
clearTimeout(existingTimer);
|
|
98
|
+
const prevEventTracer = eventTracers.get(stableKey);
|
|
99
|
+
prevEventTracer?.emit("Request cancelled (new input)", {
|
|
100
|
+
queryKey: existingQueryKey,
|
|
101
|
+
color: "warning"
|
|
102
|
+
});
|
|
90
103
|
}
|
|
91
104
|
latestQueryKeys.set(stableKey, queryKey);
|
|
105
|
+
if (et) {
|
|
106
|
+
eventTracers.set(stableKey, et);
|
|
107
|
+
}
|
|
108
|
+
et?.emit(`Request debounced (${debounceMs}ms)`, {
|
|
109
|
+
queryKey,
|
|
110
|
+
color: "info",
|
|
111
|
+
meta: { delay: debounceMs }
|
|
112
|
+
});
|
|
92
113
|
const cached = context.stateManager.getCache(queryKey);
|
|
93
114
|
const timer = setTimeout(() => {
|
|
94
115
|
timers.delete(stableKey);
|
|
95
116
|
const latestKey = latestQueryKeys.get(stableKey);
|
|
96
117
|
if (latestKey) {
|
|
118
|
+
const storedEventTracer = eventTracers.get(stableKey);
|
|
119
|
+
storedEventTracer?.emit("Debounce complete, triggering request", {
|
|
120
|
+
queryKey: latestKey,
|
|
121
|
+
color: "success"
|
|
122
|
+
});
|
|
97
123
|
context.eventEmitter.emit("refetch", {
|
|
98
124
|
queryKey: latestKey,
|
|
99
125
|
reason: "invalidate"
|
|
@@ -102,8 +128,10 @@ function debouncePlugin() {
|
|
|
102
128
|
}, debounceMs);
|
|
103
129
|
timers.set(stableKey, timer);
|
|
104
130
|
if (cached?.state?.data !== void 0) {
|
|
131
|
+
t?.return("Debounced, returning cached", { color: "info" });
|
|
105
132
|
return { data: cached.state.data, status: 200 };
|
|
106
133
|
}
|
|
134
|
+
t?.return("Debounced, no cached data", { color: "info" });
|
|
107
135
|
return { data: void 0, status: 0 };
|
|
108
136
|
}
|
|
109
137
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/plugin.ts
|
|
2
|
+
var PLUGIN_NAME = "spoosh:debounce";
|
|
2
3
|
function resolveDebounceMs(debounce, context) {
|
|
3
4
|
if (debounce === void 0) return 0;
|
|
4
5
|
if (typeof debounce === "number") return debounce;
|
|
@@ -8,8 +9,9 @@ function debouncePlugin() {
|
|
|
8
9
|
const timers = /* @__PURE__ */ new Map();
|
|
9
10
|
const latestQueryKeys = /* @__PURE__ */ new Map();
|
|
10
11
|
const prevRequests = /* @__PURE__ */ new Map();
|
|
12
|
+
const eventTracers = /* @__PURE__ */ new Map();
|
|
11
13
|
return {
|
|
12
|
-
name:
|
|
14
|
+
name: PLUGIN_NAME,
|
|
13
15
|
operations: ["read", "infiniteRead"],
|
|
14
16
|
lifecycle: {
|
|
15
17
|
onUnmount: (context) => {
|
|
@@ -25,9 +27,12 @@ function debouncePlugin() {
|
|
|
25
27
|
}
|
|
26
28
|
},
|
|
27
29
|
middleware: async (context, next) => {
|
|
30
|
+
const t = context.tracer?.(PLUGIN_NAME);
|
|
31
|
+
const et = context.eventTracer?.(PLUGIN_NAME);
|
|
28
32
|
const pluginOptions = context.pluginOptions;
|
|
29
33
|
const debounceOption = pluginOptions?.debounce;
|
|
30
34
|
if (debounceOption === void 0 || context.forceRefetch) {
|
|
35
|
+
t?.skip("No debounce configured");
|
|
31
36
|
return next();
|
|
32
37
|
}
|
|
33
38
|
const { queryKey, request, path, method } = context;
|
|
@@ -48,26 +53,47 @@ function debouncePlugin() {
|
|
|
48
53
|
const debounceMs = resolveDebounceMs(debounceOption, prevContext);
|
|
49
54
|
prevRequests.set(stableKey, currentRequest);
|
|
50
55
|
if (!debounceMs || debounceMs <= 0) {
|
|
56
|
+
t?.skip("Debounce resolved to 0");
|
|
51
57
|
return next();
|
|
52
58
|
}
|
|
53
59
|
const existingQueryKey = latestQueryKeys.get(stableKey);
|
|
54
60
|
if (existingQueryKey === queryKey) {
|
|
55
61
|
const cached2 = context.stateManager.getCache(queryKey);
|
|
56
62
|
if (cached2?.state?.data !== void 0) {
|
|
63
|
+
t?.return("Already debouncing, returning cached", { color: "muted" });
|
|
57
64
|
return { data: cached2.state.data, status: 200 };
|
|
58
65
|
}
|
|
66
|
+
t?.return("Already debouncing", { color: "muted" });
|
|
59
67
|
return { data: void 0, status: 0 };
|
|
60
68
|
}
|
|
61
69
|
const existingTimer = timers.get(stableKey);
|
|
62
70
|
if (existingTimer) {
|
|
63
71
|
clearTimeout(existingTimer);
|
|
72
|
+
const prevEventTracer = eventTracers.get(stableKey);
|
|
73
|
+
prevEventTracer?.emit("Request cancelled (new input)", {
|
|
74
|
+
queryKey: existingQueryKey,
|
|
75
|
+
color: "warning"
|
|
76
|
+
});
|
|
64
77
|
}
|
|
65
78
|
latestQueryKeys.set(stableKey, queryKey);
|
|
79
|
+
if (et) {
|
|
80
|
+
eventTracers.set(stableKey, et);
|
|
81
|
+
}
|
|
82
|
+
et?.emit(`Request debounced (${debounceMs}ms)`, {
|
|
83
|
+
queryKey,
|
|
84
|
+
color: "info",
|
|
85
|
+
meta: { delay: debounceMs }
|
|
86
|
+
});
|
|
66
87
|
const cached = context.stateManager.getCache(queryKey);
|
|
67
88
|
const timer = setTimeout(() => {
|
|
68
89
|
timers.delete(stableKey);
|
|
69
90
|
const latestKey = latestQueryKeys.get(stableKey);
|
|
70
91
|
if (latestKey) {
|
|
92
|
+
const storedEventTracer = eventTracers.get(stableKey);
|
|
93
|
+
storedEventTracer?.emit("Debounce complete, triggering request", {
|
|
94
|
+
queryKey: latestKey,
|
|
95
|
+
color: "success"
|
|
96
|
+
});
|
|
71
97
|
context.eventEmitter.emit("refetch", {
|
|
72
98
|
queryKey: latestKey,
|
|
73
99
|
reason: "invalidate"
|
|
@@ -76,8 +102,10 @@ function debouncePlugin() {
|
|
|
76
102
|
}, debounceMs);
|
|
77
103
|
timers.set(stableKey, timer);
|
|
78
104
|
if (cached?.state?.data !== void 0) {
|
|
105
|
+
t?.return("Debounced, returning cached", { color: "info" });
|
|
79
106
|
return { data: cached.state.data, status: 200 };
|
|
80
107
|
}
|
|
108
|
+
t?.return("Debounced, no cached data", { color: "info" });
|
|
81
109
|
return { data: void 0, status: 0 };
|
|
82
110
|
}
|
|
83
111
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spoosh/plugin-debounce",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Request debouncing plugin for Spoosh - waits for inactivity before fetching",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@spoosh/core": ">=0.
|
|
36
|
+
"@spoosh/core": ">=0.13.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@spoosh/core": "0.
|
|
40
|
-
"@spoosh/test-utils": "0.
|
|
39
|
+
"@spoosh/core": "0.13.0",
|
|
40
|
+
"@spoosh/test-utils": "0.2.0"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"dev": "tsup --watch",
|