@spoosh/plugin-optimistic 0.4.3 → 0.5.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 +0 -55
- package/dist/index.d.ts +0 -55
- package/dist/index.js +70 -15
- package/dist/index.mjs +70 -15
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ import { Spoosh } from "@spoosh/core";
|
|
|
22
22
|
import { optimisticPlugin } from "@spoosh/plugin-optimistic";
|
|
23
23
|
import { invalidationPlugin } from "@spoosh/plugin-invalidation";
|
|
24
24
|
|
|
25
|
-
const
|
|
25
|
+
const spoosh = new Spoosh<ApiSchema, Error>("/api").use([
|
|
26
26
|
invalidationPlugin(),
|
|
27
27
|
optimisticPlugin(),
|
|
28
28
|
]);
|
package/dist/index.d.mts
CHANGED
|
@@ -215,61 +215,6 @@ declare module "@spoosh/core" {
|
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
/**
|
|
219
|
-
* Enables optimistic updates for mutations.
|
|
220
|
-
*
|
|
221
|
-
* Immediately updates cached data before the mutation completes,
|
|
222
|
-
* with automatic rollback on error.
|
|
223
|
-
*
|
|
224
|
-
* When using optimistic updates, invalidation mode defaults to `"none"` to prevent
|
|
225
|
-
* unnecessary refetches that would override the optimistic data. You can override
|
|
226
|
-
* this by explicitly setting the `invalidate` option with a mode string or array.
|
|
227
|
-
*
|
|
228
|
-
* @see {@link https://spoosh.dev/docs/react/plugins/optimistic | Optimistic Plugin Documentation}
|
|
229
|
-
*
|
|
230
|
-
* @returns Optimistic plugin instance
|
|
231
|
-
*
|
|
232
|
-
* @example
|
|
233
|
-
* ```ts
|
|
234
|
-
* import { Spoosh } from "@spoosh/core";
|
|
235
|
-
*
|
|
236
|
-
* const client = new Spoosh<ApiSchema, Error>("/api")
|
|
237
|
-
* .use([
|
|
238
|
-
* // ... other plugins
|
|
239
|
-
* optimisticPlugin(),
|
|
240
|
-
* ]);
|
|
241
|
-
*
|
|
242
|
-
* // Methods can be chained in any order
|
|
243
|
-
* trigger({
|
|
244
|
-
* optimistic: (api) => api("posts")
|
|
245
|
-
* .GET()
|
|
246
|
-
* .UPDATE_CACHE(posts => posts.filter(p => p.id !== deletedId)),
|
|
247
|
-
* });
|
|
248
|
-
* ```
|
|
249
|
-
*
|
|
250
|
-
* @example
|
|
251
|
-
* ```ts
|
|
252
|
-
* // With WHERE filter and disable rollback
|
|
253
|
-
* trigger({
|
|
254
|
-
* optimistic: (api) => api("posts")
|
|
255
|
-
* .GET()
|
|
256
|
-
* .NO_ROLLBACK()
|
|
257
|
-
* .WHERE(entry => entry.query.page === 1)
|
|
258
|
-
* .UPDATE_CACHE(posts => [newPost, ...posts]),
|
|
259
|
-
* });
|
|
260
|
-
* ```
|
|
261
|
-
*
|
|
262
|
-
* @example
|
|
263
|
-
* ```ts
|
|
264
|
-
* // Apply after success with typed response
|
|
265
|
-
* trigger({
|
|
266
|
-
* optimistic: (api) => api("posts")
|
|
267
|
-
* .GET()
|
|
268
|
-
* .ON_SUCCESS()
|
|
269
|
-
* .UPDATE_CACHE((posts, newPost) => [...posts, newPost]),
|
|
270
|
-
* });
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
218
|
declare function optimisticPlugin(): SpooshPlugin<{
|
|
274
219
|
readOptions: OptimisticReadOptions;
|
|
275
220
|
writeOptions: OptimisticWriteOptions;
|
package/dist/index.d.ts
CHANGED
|
@@ -215,61 +215,6 @@ declare module "@spoosh/core" {
|
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
/**
|
|
219
|
-
* Enables optimistic updates for mutations.
|
|
220
|
-
*
|
|
221
|
-
* Immediately updates cached data before the mutation completes,
|
|
222
|
-
* with automatic rollback on error.
|
|
223
|
-
*
|
|
224
|
-
* When using optimistic updates, invalidation mode defaults to `"none"` to prevent
|
|
225
|
-
* unnecessary refetches that would override the optimistic data. You can override
|
|
226
|
-
* this by explicitly setting the `invalidate` option with a mode string or array.
|
|
227
|
-
*
|
|
228
|
-
* @see {@link https://spoosh.dev/docs/react/plugins/optimistic | Optimistic Plugin Documentation}
|
|
229
|
-
*
|
|
230
|
-
* @returns Optimistic plugin instance
|
|
231
|
-
*
|
|
232
|
-
* @example
|
|
233
|
-
* ```ts
|
|
234
|
-
* import { Spoosh } from "@spoosh/core";
|
|
235
|
-
*
|
|
236
|
-
* const client = new Spoosh<ApiSchema, Error>("/api")
|
|
237
|
-
* .use([
|
|
238
|
-
* // ... other plugins
|
|
239
|
-
* optimisticPlugin(),
|
|
240
|
-
* ]);
|
|
241
|
-
*
|
|
242
|
-
* // Methods can be chained in any order
|
|
243
|
-
* trigger({
|
|
244
|
-
* optimistic: (api) => api("posts")
|
|
245
|
-
* .GET()
|
|
246
|
-
* .UPDATE_CACHE(posts => posts.filter(p => p.id !== deletedId)),
|
|
247
|
-
* });
|
|
248
|
-
* ```
|
|
249
|
-
*
|
|
250
|
-
* @example
|
|
251
|
-
* ```ts
|
|
252
|
-
* // With WHERE filter and disable rollback
|
|
253
|
-
* trigger({
|
|
254
|
-
* optimistic: (api) => api("posts")
|
|
255
|
-
* .GET()
|
|
256
|
-
* .NO_ROLLBACK()
|
|
257
|
-
* .WHERE(entry => entry.query.page === 1)
|
|
258
|
-
* .UPDATE_CACHE(posts => [newPost, ...posts]),
|
|
259
|
-
* });
|
|
260
|
-
* ```
|
|
261
|
-
*
|
|
262
|
-
* @example
|
|
263
|
-
* ```ts
|
|
264
|
-
* // Apply after success with typed response
|
|
265
|
-
* trigger({
|
|
266
|
-
* optimistic: (api) => api("posts")
|
|
267
|
-
* .GET()
|
|
268
|
-
* .ON_SUCCESS()
|
|
269
|
-
* .UPDATE_CACHE((posts, newPost) => [...posts, newPost]),
|
|
270
|
-
* });
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
218
|
declare function optimisticPlugin(): SpooshPlugin<{
|
|
274
219
|
readOptions: OptimisticReadOptions;
|
|
275
220
|
writeOptions: OptimisticWriteOptions;
|
package/dist/index.js
CHANGED
|
@@ -90,7 +90,7 @@ function resolveOptimisticTargets(context) {
|
|
|
90
90
|
const targets = Array.isArray(result) ? result : [result];
|
|
91
91
|
return targets;
|
|
92
92
|
}
|
|
93
|
-
function applyOptimisticUpdate(stateManager, target) {
|
|
93
|
+
function applyOptimisticUpdate(stateManager, target, t) {
|
|
94
94
|
if (!target.updater) return [];
|
|
95
95
|
const tags = extractTagsFromPath(target.path);
|
|
96
96
|
const targetSelfTag = getExactMatchPath(tags);
|
|
@@ -113,19 +113,24 @@ function applyOptimisticUpdate(stateManager, target) {
|
|
|
113
113
|
if (entry.state.data === void 0) {
|
|
114
114
|
continue;
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
const afterData = target.updater(entry.state.data, void 0);
|
|
117
|
+
snapshots.push({ key, previousData: entry.state.data, afterData });
|
|
117
118
|
stateManager.setCache(key, {
|
|
118
119
|
previousData: entry.state.data,
|
|
119
120
|
state: {
|
|
120
121
|
...entry.state,
|
|
121
|
-
data:
|
|
122
|
+
data: afterData
|
|
122
123
|
}
|
|
123
124
|
});
|
|
124
125
|
stateManager.setMeta(key, { isOptimistic: true });
|
|
126
|
+
t?.log("Marked as optimistic", {
|
|
127
|
+
color: "info",
|
|
128
|
+
info: [{ value: { isOptimistic: true } }]
|
|
129
|
+
});
|
|
125
130
|
}
|
|
126
131
|
return snapshots;
|
|
127
132
|
}
|
|
128
|
-
function confirmOptimistic(stateManager, snapshots) {
|
|
133
|
+
function confirmOptimistic(stateManager, snapshots, t) {
|
|
129
134
|
for (const { key } of snapshots) {
|
|
130
135
|
const entry = stateManager.getCache(key);
|
|
131
136
|
if (entry) {
|
|
@@ -133,10 +138,14 @@ function confirmOptimistic(stateManager, snapshots) {
|
|
|
133
138
|
previousData: void 0
|
|
134
139
|
});
|
|
135
140
|
stateManager.setMeta(key, { isOptimistic: false });
|
|
141
|
+
t?.log("Optimistic confirmed", {
|
|
142
|
+
color: "success",
|
|
143
|
+
info: [{ value: { isOptimistic: false } }]
|
|
144
|
+
});
|
|
136
145
|
}
|
|
137
146
|
}
|
|
138
147
|
}
|
|
139
|
-
function rollbackOptimistic(stateManager, snapshots) {
|
|
148
|
+
function rollbackOptimistic(stateManager, snapshots, t) {
|
|
140
149
|
for (const { key, previousData } of snapshots) {
|
|
141
150
|
const entry = stateManager.getCache(key);
|
|
142
151
|
if (entry) {
|
|
@@ -148,33 +157,66 @@ function rollbackOptimistic(stateManager, snapshots) {
|
|
|
148
157
|
}
|
|
149
158
|
});
|
|
150
159
|
stateManager.setMeta(key, { isOptimistic: false });
|
|
160
|
+
t?.log("Optimistic rolled back", {
|
|
161
|
+
color: "warning",
|
|
162
|
+
info: [{ value: { isOptimistic: false } }]
|
|
163
|
+
});
|
|
151
164
|
}
|
|
152
165
|
}
|
|
153
166
|
}
|
|
167
|
+
function buildSnapshotDiff(snapshots, mode = "apply") {
|
|
168
|
+
const first = snapshots[0];
|
|
169
|
+
const label = mode === "apply" ? "Optimistic update to cache" : mode === "rollback" ? "Rollback optimistic changes" : "Apply onSuccess updates";
|
|
170
|
+
if (snapshots.length === 1) {
|
|
171
|
+
return mode === "apply" || mode === "onSuccess" ? { before: first.previousData, after: first.afterData, label } : { before: first.afterData, after: first.previousData, label };
|
|
172
|
+
}
|
|
173
|
+
return mode === "apply" || mode === "onSuccess" ? {
|
|
174
|
+
before: snapshots.map((s) => ({ key: s.key, data: s.previousData })),
|
|
175
|
+
after: snapshots.map((s) => ({ key: s.key, data: s.afterData })),
|
|
176
|
+
label
|
|
177
|
+
} : {
|
|
178
|
+
before: snapshots.map((s) => ({ key: s.key, data: s.afterData })),
|
|
179
|
+
after: snapshots.map((s) => ({ key: s.key, data: s.previousData })),
|
|
180
|
+
label
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
var PLUGIN_NAME = "spoosh:optimistic";
|
|
154
184
|
function optimisticPlugin() {
|
|
155
185
|
return {
|
|
156
|
-
name:
|
|
186
|
+
name: PLUGIN_NAME,
|
|
157
187
|
operations: ["write"],
|
|
158
188
|
dependencies: ["spoosh:invalidation"],
|
|
159
189
|
middleware: async (context, next) => {
|
|
190
|
+
const t = context.tracer?.(PLUGIN_NAME);
|
|
160
191
|
const { stateManager } = context;
|
|
161
192
|
const targets = resolveOptimisticTargets(context);
|
|
162
|
-
if (targets.length
|
|
163
|
-
|
|
193
|
+
if (targets.length === 0) {
|
|
194
|
+
t?.skip("No optimistic targets");
|
|
195
|
+
return next();
|
|
164
196
|
}
|
|
165
|
-
|
|
197
|
+
context.plugins.get("spoosh:invalidation")?.setDefaultMode("none");
|
|
198
|
+
const immediateTargets = targets.filter((t2) => t2.timing !== "onSuccess");
|
|
166
199
|
const allSnapshots = [];
|
|
167
200
|
for (const target of immediateTargets) {
|
|
168
|
-
const snapshots = applyOptimisticUpdate(stateManager, target);
|
|
201
|
+
const snapshots = applyOptimisticUpdate(stateManager, target, t);
|
|
169
202
|
allSnapshots.push(...snapshots);
|
|
170
203
|
}
|
|
204
|
+
if (allSnapshots.length > 0) {
|
|
205
|
+
t?.log(`Applied ${allSnapshots.length} immediate update(s)`, {
|
|
206
|
+
diff: buildSnapshotDiff(allSnapshots)
|
|
207
|
+
});
|
|
208
|
+
}
|
|
171
209
|
const response = await next();
|
|
172
210
|
if (response.error) {
|
|
173
211
|
const shouldRollback = targets.some(
|
|
174
|
-
(
|
|
212
|
+
(t2) => t2.rollbackOnError && t2.timing !== "onSuccess"
|
|
175
213
|
);
|
|
176
214
|
if (shouldRollback && allSnapshots.length > 0) {
|
|
177
|
-
rollbackOptimistic(stateManager, allSnapshots);
|
|
215
|
+
rollbackOptimistic(stateManager, allSnapshots, t);
|
|
216
|
+
t?.log(`Rolled back ${allSnapshots.length} update(s)`, {
|
|
217
|
+
color: "warning",
|
|
218
|
+
diff: buildSnapshotDiff(allSnapshots, "rollback")
|
|
219
|
+
});
|
|
178
220
|
}
|
|
179
221
|
for (const target of targets) {
|
|
180
222
|
if (target.onError) {
|
|
@@ -183,11 +225,12 @@ function optimisticPlugin() {
|
|
|
183
225
|
}
|
|
184
226
|
} else {
|
|
185
227
|
if (allSnapshots.length > 0) {
|
|
186
|
-
confirmOptimistic(stateManager, allSnapshots);
|
|
228
|
+
confirmOptimistic(stateManager, allSnapshots, t);
|
|
187
229
|
}
|
|
188
230
|
const onSuccessTargets = targets.filter(
|
|
189
|
-
(
|
|
231
|
+
(target) => target.timing === "onSuccess"
|
|
190
232
|
);
|
|
233
|
+
const onSuccessSnapshots = [];
|
|
191
234
|
for (const target of onSuccessTargets) {
|
|
192
235
|
if (!target.updater) continue;
|
|
193
236
|
const tags = extractTagsFromPath(target.path);
|
|
@@ -210,14 +253,26 @@ function optimisticPlugin() {
|
|
|
210
253
|
if (entry.state.data === void 0) {
|
|
211
254
|
continue;
|
|
212
255
|
}
|
|
256
|
+
const afterData = target.updater(entry.state.data, response.data);
|
|
257
|
+
onSuccessSnapshots.push({
|
|
258
|
+
key,
|
|
259
|
+
previousData: entry.state.data,
|
|
260
|
+
afterData
|
|
261
|
+
});
|
|
213
262
|
stateManager.setCache(key, {
|
|
214
263
|
state: {
|
|
215
264
|
...entry.state,
|
|
216
|
-
data:
|
|
265
|
+
data: afterData
|
|
217
266
|
}
|
|
218
267
|
});
|
|
219
268
|
}
|
|
220
269
|
}
|
|
270
|
+
if (onSuccessSnapshots.length > 0) {
|
|
271
|
+
t?.log(`Applied ${onSuccessSnapshots.length} onSuccess update(s)`, {
|
|
272
|
+
color: "success",
|
|
273
|
+
diff: buildSnapshotDiff(onSuccessSnapshots, "onSuccess")
|
|
274
|
+
});
|
|
275
|
+
}
|
|
221
276
|
}
|
|
222
277
|
return response;
|
|
223
278
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -64,7 +64,7 @@ function resolveOptimisticTargets(context) {
|
|
|
64
64
|
const targets = Array.isArray(result) ? result : [result];
|
|
65
65
|
return targets;
|
|
66
66
|
}
|
|
67
|
-
function applyOptimisticUpdate(stateManager, target) {
|
|
67
|
+
function applyOptimisticUpdate(stateManager, target, t) {
|
|
68
68
|
if (!target.updater) return [];
|
|
69
69
|
const tags = extractTagsFromPath(target.path);
|
|
70
70
|
const targetSelfTag = getExactMatchPath(tags);
|
|
@@ -87,19 +87,24 @@ function applyOptimisticUpdate(stateManager, target) {
|
|
|
87
87
|
if (entry.state.data === void 0) {
|
|
88
88
|
continue;
|
|
89
89
|
}
|
|
90
|
-
|
|
90
|
+
const afterData = target.updater(entry.state.data, void 0);
|
|
91
|
+
snapshots.push({ key, previousData: entry.state.data, afterData });
|
|
91
92
|
stateManager.setCache(key, {
|
|
92
93
|
previousData: entry.state.data,
|
|
93
94
|
state: {
|
|
94
95
|
...entry.state,
|
|
95
|
-
data:
|
|
96
|
+
data: afterData
|
|
96
97
|
}
|
|
97
98
|
});
|
|
98
99
|
stateManager.setMeta(key, { isOptimistic: true });
|
|
100
|
+
t?.log("Marked as optimistic", {
|
|
101
|
+
color: "info",
|
|
102
|
+
info: [{ value: { isOptimistic: true } }]
|
|
103
|
+
});
|
|
99
104
|
}
|
|
100
105
|
return snapshots;
|
|
101
106
|
}
|
|
102
|
-
function confirmOptimistic(stateManager, snapshots) {
|
|
107
|
+
function confirmOptimistic(stateManager, snapshots, t) {
|
|
103
108
|
for (const { key } of snapshots) {
|
|
104
109
|
const entry = stateManager.getCache(key);
|
|
105
110
|
if (entry) {
|
|
@@ -107,10 +112,14 @@ function confirmOptimistic(stateManager, snapshots) {
|
|
|
107
112
|
previousData: void 0
|
|
108
113
|
});
|
|
109
114
|
stateManager.setMeta(key, { isOptimistic: false });
|
|
115
|
+
t?.log("Optimistic confirmed", {
|
|
116
|
+
color: "success",
|
|
117
|
+
info: [{ value: { isOptimistic: false } }]
|
|
118
|
+
});
|
|
110
119
|
}
|
|
111
120
|
}
|
|
112
121
|
}
|
|
113
|
-
function rollbackOptimistic(stateManager, snapshots) {
|
|
122
|
+
function rollbackOptimistic(stateManager, snapshots, t) {
|
|
114
123
|
for (const { key, previousData } of snapshots) {
|
|
115
124
|
const entry = stateManager.getCache(key);
|
|
116
125
|
if (entry) {
|
|
@@ -122,33 +131,66 @@ function rollbackOptimistic(stateManager, snapshots) {
|
|
|
122
131
|
}
|
|
123
132
|
});
|
|
124
133
|
stateManager.setMeta(key, { isOptimistic: false });
|
|
134
|
+
t?.log("Optimistic rolled back", {
|
|
135
|
+
color: "warning",
|
|
136
|
+
info: [{ value: { isOptimistic: false } }]
|
|
137
|
+
});
|
|
125
138
|
}
|
|
126
139
|
}
|
|
127
140
|
}
|
|
141
|
+
function buildSnapshotDiff(snapshots, mode = "apply") {
|
|
142
|
+
const first = snapshots[0];
|
|
143
|
+
const label = mode === "apply" ? "Optimistic update to cache" : mode === "rollback" ? "Rollback optimistic changes" : "Apply onSuccess updates";
|
|
144
|
+
if (snapshots.length === 1) {
|
|
145
|
+
return mode === "apply" || mode === "onSuccess" ? { before: first.previousData, after: first.afterData, label } : { before: first.afterData, after: first.previousData, label };
|
|
146
|
+
}
|
|
147
|
+
return mode === "apply" || mode === "onSuccess" ? {
|
|
148
|
+
before: snapshots.map((s) => ({ key: s.key, data: s.previousData })),
|
|
149
|
+
after: snapshots.map((s) => ({ key: s.key, data: s.afterData })),
|
|
150
|
+
label
|
|
151
|
+
} : {
|
|
152
|
+
before: snapshots.map((s) => ({ key: s.key, data: s.afterData })),
|
|
153
|
+
after: snapshots.map((s) => ({ key: s.key, data: s.previousData })),
|
|
154
|
+
label
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
var PLUGIN_NAME = "spoosh:optimistic";
|
|
128
158
|
function optimisticPlugin() {
|
|
129
159
|
return {
|
|
130
|
-
name:
|
|
160
|
+
name: PLUGIN_NAME,
|
|
131
161
|
operations: ["write"],
|
|
132
162
|
dependencies: ["spoosh:invalidation"],
|
|
133
163
|
middleware: async (context, next) => {
|
|
164
|
+
const t = context.tracer?.(PLUGIN_NAME);
|
|
134
165
|
const { stateManager } = context;
|
|
135
166
|
const targets = resolveOptimisticTargets(context);
|
|
136
|
-
if (targets.length
|
|
137
|
-
|
|
167
|
+
if (targets.length === 0) {
|
|
168
|
+
t?.skip("No optimistic targets");
|
|
169
|
+
return next();
|
|
138
170
|
}
|
|
139
|
-
|
|
171
|
+
context.plugins.get("spoosh:invalidation")?.setDefaultMode("none");
|
|
172
|
+
const immediateTargets = targets.filter((t2) => t2.timing !== "onSuccess");
|
|
140
173
|
const allSnapshots = [];
|
|
141
174
|
for (const target of immediateTargets) {
|
|
142
|
-
const snapshots = applyOptimisticUpdate(stateManager, target);
|
|
175
|
+
const snapshots = applyOptimisticUpdate(stateManager, target, t);
|
|
143
176
|
allSnapshots.push(...snapshots);
|
|
144
177
|
}
|
|
178
|
+
if (allSnapshots.length > 0) {
|
|
179
|
+
t?.log(`Applied ${allSnapshots.length} immediate update(s)`, {
|
|
180
|
+
diff: buildSnapshotDiff(allSnapshots)
|
|
181
|
+
});
|
|
182
|
+
}
|
|
145
183
|
const response = await next();
|
|
146
184
|
if (response.error) {
|
|
147
185
|
const shouldRollback = targets.some(
|
|
148
|
-
(
|
|
186
|
+
(t2) => t2.rollbackOnError && t2.timing !== "onSuccess"
|
|
149
187
|
);
|
|
150
188
|
if (shouldRollback && allSnapshots.length > 0) {
|
|
151
|
-
rollbackOptimistic(stateManager, allSnapshots);
|
|
189
|
+
rollbackOptimistic(stateManager, allSnapshots, t);
|
|
190
|
+
t?.log(`Rolled back ${allSnapshots.length} update(s)`, {
|
|
191
|
+
color: "warning",
|
|
192
|
+
diff: buildSnapshotDiff(allSnapshots, "rollback")
|
|
193
|
+
});
|
|
152
194
|
}
|
|
153
195
|
for (const target of targets) {
|
|
154
196
|
if (target.onError) {
|
|
@@ -157,11 +199,12 @@ function optimisticPlugin() {
|
|
|
157
199
|
}
|
|
158
200
|
} else {
|
|
159
201
|
if (allSnapshots.length > 0) {
|
|
160
|
-
confirmOptimistic(stateManager, allSnapshots);
|
|
202
|
+
confirmOptimistic(stateManager, allSnapshots, t);
|
|
161
203
|
}
|
|
162
204
|
const onSuccessTargets = targets.filter(
|
|
163
|
-
(
|
|
205
|
+
(target) => target.timing === "onSuccess"
|
|
164
206
|
);
|
|
207
|
+
const onSuccessSnapshots = [];
|
|
165
208
|
for (const target of onSuccessTargets) {
|
|
166
209
|
if (!target.updater) continue;
|
|
167
210
|
const tags = extractTagsFromPath(target.path);
|
|
@@ -184,14 +227,26 @@ function optimisticPlugin() {
|
|
|
184
227
|
if (entry.state.data === void 0) {
|
|
185
228
|
continue;
|
|
186
229
|
}
|
|
230
|
+
const afterData = target.updater(entry.state.data, response.data);
|
|
231
|
+
onSuccessSnapshots.push({
|
|
232
|
+
key,
|
|
233
|
+
previousData: entry.state.data,
|
|
234
|
+
afterData
|
|
235
|
+
});
|
|
187
236
|
stateManager.setCache(key, {
|
|
188
237
|
state: {
|
|
189
238
|
...entry.state,
|
|
190
|
-
data:
|
|
239
|
+
data: afterData
|
|
191
240
|
}
|
|
192
241
|
});
|
|
193
242
|
}
|
|
194
243
|
}
|
|
244
|
+
if (onSuccessSnapshots.length > 0) {
|
|
245
|
+
t?.log(`Applied ${onSuccessSnapshots.length} onSuccess update(s)`, {
|
|
246
|
+
color: "success",
|
|
247
|
+
diff: buildSnapshotDiff(onSuccessSnapshots, "onSuccess")
|
|
248
|
+
});
|
|
249
|
+
}
|
|
195
250
|
}
|
|
196
251
|
return response;
|
|
197
252
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spoosh/plugin-optimistic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Optimistic updates plugin for Spoosh - instant UI updates with automatic rollback",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@spoosh/core": ">=0.
|
|
36
|
+
"@spoosh/core": ">=0.13.0",
|
|
37
37
|
"@spoosh/plugin-invalidation": ">=0.4.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@spoosh/core": "0.
|
|
41
|
-
"@spoosh/test-utils": "0.
|
|
42
|
-
"@spoosh/plugin-invalidation": "0.
|
|
40
|
+
"@spoosh/core": "0.13.0",
|
|
41
|
+
"@spoosh/test-utils": "0.2.0",
|
|
42
|
+
"@spoosh/plugin-invalidation": "0.6.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"dev": "tsup --watch",
|