@spoosh/plugin-optimistic 0.8.0 → 0.8.2
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/dist/index.js +47 -95
- package/dist/index.mjs +47 -95
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -32,54 +32,28 @@ var import_plugin_invalidation = require("@spoosh/plugin-invalidation");
|
|
|
32
32
|
function isParameterSegment(segment) {
|
|
33
33
|
return segment.startsWith(":");
|
|
34
34
|
}
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
function pathMatchesPattern(actualPath, pattern) {
|
|
39
|
-
const actualSegments = actualPath.split("/").filter(Boolean);
|
|
35
|
+
function pathMatchesPattern(resolvedPath, pattern) {
|
|
36
|
+
const resolvedSegments = resolvedPath.split("/").filter(Boolean);
|
|
40
37
|
const patternSegments = pattern.split("/").filter(Boolean);
|
|
41
|
-
if (
|
|
42
|
-
return { matches: false, params: {}
|
|
38
|
+
if (resolvedSegments.length !== patternSegments.length) {
|
|
39
|
+
return { matches: false, params: {} };
|
|
43
40
|
}
|
|
44
41
|
const params = {};
|
|
45
|
-
const paramMapping = {};
|
|
46
42
|
for (let i = 0; i < patternSegments.length; i++) {
|
|
47
43
|
const patternSeg = patternSegments[i];
|
|
48
|
-
const
|
|
44
|
+
const resolvedSeg = resolvedSegments[i];
|
|
49
45
|
if (isParameterSegment(patternSeg)) {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
params[targetParamName] = actualSeg;
|
|
57
|
-
} else if (isParameterSegment(actualSeg)) {
|
|
58
|
-
continue;
|
|
59
|
-
} else if (patternSeg !== actualSeg) {
|
|
60
|
-
return { matches: false, params: {}, paramMapping: {} };
|
|
46
|
+
const paramName = patternSeg.slice(1);
|
|
47
|
+
params[paramName] = resolvedSeg;
|
|
48
|
+
} else if (patternSeg !== resolvedSeg) {
|
|
49
|
+
return { matches: false, params: {} };
|
|
61
50
|
}
|
|
62
51
|
}
|
|
63
|
-
return { matches: true, params
|
|
52
|
+
return { matches: true, params };
|
|
64
53
|
}
|
|
65
54
|
|
|
66
55
|
// src/utils/cache-key.ts
|
|
67
56
|
var import_core = require("@spoosh/core");
|
|
68
|
-
function extractPathFromKey(key) {
|
|
69
|
-
try {
|
|
70
|
-
const parsed = JSON.parse(key);
|
|
71
|
-
const path = parsed.path;
|
|
72
|
-
if (typeof path === "string") {
|
|
73
|
-
return path;
|
|
74
|
-
}
|
|
75
|
-
if (Array.isArray(path)) {
|
|
76
|
-
return path.join("/");
|
|
77
|
-
}
|
|
78
|
-
return null;
|
|
79
|
-
} catch {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
57
|
function formatCacheKeyForTrace(key) {
|
|
84
58
|
const resolvedPath = (0, import_core.generateSelfTagFromKey)(key);
|
|
85
59
|
if (!resolvedPath) return "unknown";
|
|
@@ -122,26 +96,16 @@ function extractOptionsFromKey(key) {
|
|
|
122
96
|
return null;
|
|
123
97
|
}
|
|
124
98
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
for (const [targetName, actualName] of Object.entries(paramMapping)) {
|
|
129
|
-
if (actualName in actualParams) {
|
|
130
|
-
result[targetName] = String(actualParams[actualName]);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
for (const [key, value] of Object.entries(actualParams)) {
|
|
134
|
-
if (!Object.values(paramMapping).includes(key)) {
|
|
135
|
-
result[key] = String(value);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return result;
|
|
139
|
-
}
|
|
99
|
+
|
|
100
|
+
// src/plugin.ts
|
|
101
|
+
var import_core3 = require("@spoosh/core");
|
|
140
102
|
|
|
141
103
|
// src/builder/index.ts
|
|
142
104
|
function createBuilder(state, isConfirmed = false) {
|
|
143
105
|
return {
|
|
144
106
|
...state,
|
|
107
|
+
// Expose the internal state so the plugin can access predicates
|
|
108
|
+
__state: state,
|
|
145
109
|
filter(predicate) {
|
|
146
110
|
return createBuilder({ ...state, filter: predicate }, isConfirmed);
|
|
147
111
|
},
|
|
@@ -193,27 +157,13 @@ function resolveOptimisticTargets(context) {
|
|
|
193
157
|
function getMatchingEntries(stateManager, targetPath) {
|
|
194
158
|
const results = [];
|
|
195
159
|
const allEntries = stateManager.getAllCacheEntries();
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
targetPath
|
|
204
|
-
);
|
|
205
|
-
if (matches) {
|
|
206
|
-
results.push({ key, entry, extractedParams: params, paramMapping });
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
} else {
|
|
210
|
-
for (const { key, entry } of allEntries) {
|
|
211
|
-
if (!key.includes(`"method":"GET"`)) continue;
|
|
212
|
-
const actualPath = extractPathFromKey(key);
|
|
213
|
-
if (!actualPath) continue;
|
|
214
|
-
if (actualPath === targetPath) {
|
|
215
|
-
results.push({ key, entry, extractedParams: {}, paramMapping: {} });
|
|
216
|
-
}
|
|
160
|
+
for (const { key, entry } of allEntries) {
|
|
161
|
+
if (!key.includes(`"method":"GET"`)) continue;
|
|
162
|
+
const resolvedPath = (0, import_core3.generateSelfTagFromKey)(key);
|
|
163
|
+
if (!resolvedPath) continue;
|
|
164
|
+
const { matches, params } = pathMatchesPattern(resolvedPath, targetPath);
|
|
165
|
+
if (matches) {
|
|
166
|
+
results.push({ key, entry, extractedParams: params });
|
|
217
167
|
}
|
|
218
168
|
}
|
|
219
169
|
return results;
|
|
@@ -222,28 +172,22 @@ function applyUpdate(stateManager, target, updater, response, t) {
|
|
|
222
172
|
const snapshots = [];
|
|
223
173
|
const matchingEntries = getMatchingEntries(stateManager, target.path);
|
|
224
174
|
if (matchingEntries.length === 0) {
|
|
225
|
-
t?.skip(`Skipped ${target.path} (no cache entry)`);
|
|
226
175
|
return [];
|
|
227
176
|
}
|
|
228
|
-
for (const { key, entry, extractedParams
|
|
229
|
-
|
|
177
|
+
for (const { key, entry, extractedParams } of matchingEntries) {
|
|
178
|
+
const targetWithState = target;
|
|
179
|
+
const filterPredicate = targetWithState.__state ? targetWithState.__state.filter : target.filter;
|
|
180
|
+
if (filterPredicate) {
|
|
230
181
|
const options = extractOptionsFromKey(key) ?? {};
|
|
231
|
-
const mappedParams = mapParamsToTargetNames(
|
|
232
|
-
options.params,
|
|
233
|
-
paramMapping
|
|
234
|
-
);
|
|
235
182
|
const mergedOptions = {
|
|
236
183
|
...options,
|
|
237
184
|
params: {
|
|
238
|
-
...
|
|
239
|
-
...
|
|
185
|
+
...options.params,
|
|
186
|
+
...extractedParams
|
|
240
187
|
}
|
|
241
188
|
};
|
|
242
189
|
try {
|
|
243
|
-
if (!
|
|
244
|
-
t?.skip(
|
|
245
|
-
`Skipped ${formatCacheKeyForTrace(key)} (filter not matched)`
|
|
246
|
-
);
|
|
190
|
+
if (!filterPredicate(mergedOptions)) {
|
|
247
191
|
continue;
|
|
248
192
|
}
|
|
249
193
|
} catch {
|
|
@@ -252,7 +196,6 @@ function applyUpdate(stateManager, target, updater, response, t) {
|
|
|
252
196
|
}
|
|
253
197
|
}
|
|
254
198
|
if (entry?.state.data === void 0) {
|
|
255
|
-
t?.skip(`Skipped ${formatCacheKeyForTrace(key)} (no cached data)`);
|
|
256
199
|
continue;
|
|
257
200
|
}
|
|
258
201
|
const afterData = updater(entry.state.data, response);
|
|
@@ -315,11 +258,13 @@ function optimisticPlugin() {
|
|
|
315
258
|
context.plugins.get("spoosh:invalidation")?.setDefaultMode("none");
|
|
316
259
|
const allImmediateSnapshots = [];
|
|
317
260
|
for (const target of targets) {
|
|
318
|
-
|
|
261
|
+
const targetWithState = target;
|
|
262
|
+
const immediateUpdater = targetWithState.__state ? targetWithState.__state.immediateUpdater : target.immediateUpdater;
|
|
263
|
+
if (!immediateUpdater) continue;
|
|
319
264
|
const snapshots = applyUpdate(
|
|
320
265
|
stateManager,
|
|
321
266
|
target,
|
|
322
|
-
|
|
267
|
+
immediateUpdater,
|
|
323
268
|
void 0,
|
|
324
269
|
t
|
|
325
270
|
);
|
|
@@ -333,9 +278,12 @@ function optimisticPlugin() {
|
|
|
333
278
|
}
|
|
334
279
|
const response = await next();
|
|
335
280
|
if (response.error) {
|
|
336
|
-
const shouldRollback = targets.some(
|
|
337
|
-
|
|
338
|
-
|
|
281
|
+
const shouldRollback = targets.some((target) => {
|
|
282
|
+
const targetWithState = target;
|
|
283
|
+
const rollbackOnError = targetWithState.__state ? targetWithState.__state.rollbackOnError : target.rollbackOnError;
|
|
284
|
+
const immediateUpdater = targetWithState.__state ? targetWithState.__state.immediateUpdater : target.immediateUpdater;
|
|
285
|
+
return rollbackOnError && immediateUpdater;
|
|
286
|
+
});
|
|
339
287
|
if (shouldRollback && allImmediateSnapshots.length > 0) {
|
|
340
288
|
rollbackOptimistic(stateManager, allImmediateSnapshots);
|
|
341
289
|
for (const snapshot of allImmediateSnapshots) {
|
|
@@ -346,8 +294,10 @@ function optimisticPlugin() {
|
|
|
346
294
|
}
|
|
347
295
|
}
|
|
348
296
|
for (const target of targets) {
|
|
349
|
-
|
|
350
|
-
|
|
297
|
+
const targetWithState = target;
|
|
298
|
+
const onError = targetWithState.__state ? targetWithState.__state.onError : target.onError;
|
|
299
|
+
if (onError) {
|
|
300
|
+
onError(response.error);
|
|
351
301
|
}
|
|
352
302
|
}
|
|
353
303
|
} else {
|
|
@@ -355,11 +305,13 @@ function optimisticPlugin() {
|
|
|
355
305
|
confirmOptimistic(stateManager, allImmediateSnapshots);
|
|
356
306
|
}
|
|
357
307
|
for (const target of targets) {
|
|
358
|
-
|
|
308
|
+
const targetWithState = target;
|
|
309
|
+
const confirmedUpdater = targetWithState.__state ? targetWithState.__state.confirmedUpdater : target.confirmedUpdater;
|
|
310
|
+
if (!confirmedUpdater) continue;
|
|
359
311
|
const snapshots = applyUpdate(
|
|
360
312
|
stateManager,
|
|
361
313
|
target,
|
|
362
|
-
|
|
314
|
+
confirmedUpdater,
|
|
363
315
|
response.data,
|
|
364
316
|
t
|
|
365
317
|
);
|
package/dist/index.mjs
CHANGED
|
@@ -8,54 +8,28 @@ import "@spoosh/plugin-invalidation";
|
|
|
8
8
|
function isParameterSegment(segment) {
|
|
9
9
|
return segment.startsWith(":");
|
|
10
10
|
}
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
function pathMatchesPattern(actualPath, pattern) {
|
|
15
|
-
const actualSegments = actualPath.split("/").filter(Boolean);
|
|
11
|
+
function pathMatchesPattern(resolvedPath, pattern) {
|
|
12
|
+
const resolvedSegments = resolvedPath.split("/").filter(Boolean);
|
|
16
13
|
const patternSegments = pattern.split("/").filter(Boolean);
|
|
17
|
-
if (
|
|
18
|
-
return { matches: false, params: {}
|
|
14
|
+
if (resolvedSegments.length !== patternSegments.length) {
|
|
15
|
+
return { matches: false, params: {} };
|
|
19
16
|
}
|
|
20
17
|
const params = {};
|
|
21
|
-
const paramMapping = {};
|
|
22
18
|
for (let i = 0; i < patternSegments.length; i++) {
|
|
23
19
|
const patternSeg = patternSegments[i];
|
|
24
|
-
const
|
|
20
|
+
const resolvedSeg = resolvedSegments[i];
|
|
25
21
|
if (isParameterSegment(patternSeg)) {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
params[targetParamName] = actualSeg;
|
|
33
|
-
} else if (isParameterSegment(actualSeg)) {
|
|
34
|
-
continue;
|
|
35
|
-
} else if (patternSeg !== actualSeg) {
|
|
36
|
-
return { matches: false, params: {}, paramMapping: {} };
|
|
22
|
+
const paramName = patternSeg.slice(1);
|
|
23
|
+
params[paramName] = resolvedSeg;
|
|
24
|
+
} else if (patternSeg !== resolvedSeg) {
|
|
25
|
+
return { matches: false, params: {} };
|
|
37
26
|
}
|
|
38
27
|
}
|
|
39
|
-
return { matches: true, params
|
|
28
|
+
return { matches: true, params };
|
|
40
29
|
}
|
|
41
30
|
|
|
42
31
|
// src/utils/cache-key.ts
|
|
43
32
|
import { generateSelfTagFromKey } from "@spoosh/core";
|
|
44
|
-
function extractPathFromKey(key) {
|
|
45
|
-
try {
|
|
46
|
-
const parsed = JSON.parse(key);
|
|
47
|
-
const path = parsed.path;
|
|
48
|
-
if (typeof path === "string") {
|
|
49
|
-
return path;
|
|
50
|
-
}
|
|
51
|
-
if (Array.isArray(path)) {
|
|
52
|
-
return path.join("/");
|
|
53
|
-
}
|
|
54
|
-
return null;
|
|
55
|
-
} catch {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
33
|
function formatCacheKeyForTrace(key) {
|
|
60
34
|
const resolvedPath = generateSelfTagFromKey(key);
|
|
61
35
|
if (!resolvedPath) return "unknown";
|
|
@@ -98,26 +72,16 @@ function extractOptionsFromKey(key) {
|
|
|
98
72
|
return null;
|
|
99
73
|
}
|
|
100
74
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
for (const [targetName, actualName] of Object.entries(paramMapping)) {
|
|
105
|
-
if (actualName in actualParams) {
|
|
106
|
-
result[targetName] = String(actualParams[actualName]);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
for (const [key, value] of Object.entries(actualParams)) {
|
|
110
|
-
if (!Object.values(paramMapping).includes(key)) {
|
|
111
|
-
result[key] = String(value);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return result;
|
|
115
|
-
}
|
|
75
|
+
|
|
76
|
+
// src/plugin.ts
|
|
77
|
+
import { generateSelfTagFromKey as generateSelfTagFromKey2 } from "@spoosh/core";
|
|
116
78
|
|
|
117
79
|
// src/builder/index.ts
|
|
118
80
|
function createBuilder(state, isConfirmed = false) {
|
|
119
81
|
return {
|
|
120
82
|
...state,
|
|
83
|
+
// Expose the internal state so the plugin can access predicates
|
|
84
|
+
__state: state,
|
|
121
85
|
filter(predicate) {
|
|
122
86
|
return createBuilder({ ...state, filter: predicate }, isConfirmed);
|
|
123
87
|
},
|
|
@@ -169,27 +133,13 @@ function resolveOptimisticTargets(context) {
|
|
|
169
133
|
function getMatchingEntries(stateManager, targetPath) {
|
|
170
134
|
const results = [];
|
|
171
135
|
const allEntries = stateManager.getAllCacheEntries();
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
targetPath
|
|
180
|
-
);
|
|
181
|
-
if (matches) {
|
|
182
|
-
results.push({ key, entry, extractedParams: params, paramMapping });
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
} else {
|
|
186
|
-
for (const { key, entry } of allEntries) {
|
|
187
|
-
if (!key.includes(`"method":"GET"`)) continue;
|
|
188
|
-
const actualPath = extractPathFromKey(key);
|
|
189
|
-
if (!actualPath) continue;
|
|
190
|
-
if (actualPath === targetPath) {
|
|
191
|
-
results.push({ key, entry, extractedParams: {}, paramMapping: {} });
|
|
192
|
-
}
|
|
136
|
+
for (const { key, entry } of allEntries) {
|
|
137
|
+
if (!key.includes(`"method":"GET"`)) continue;
|
|
138
|
+
const resolvedPath = generateSelfTagFromKey2(key);
|
|
139
|
+
if (!resolvedPath) continue;
|
|
140
|
+
const { matches, params } = pathMatchesPattern(resolvedPath, targetPath);
|
|
141
|
+
if (matches) {
|
|
142
|
+
results.push({ key, entry, extractedParams: params });
|
|
193
143
|
}
|
|
194
144
|
}
|
|
195
145
|
return results;
|
|
@@ -198,28 +148,22 @@ function applyUpdate(stateManager, target, updater, response, t) {
|
|
|
198
148
|
const snapshots = [];
|
|
199
149
|
const matchingEntries = getMatchingEntries(stateManager, target.path);
|
|
200
150
|
if (matchingEntries.length === 0) {
|
|
201
|
-
t?.skip(`Skipped ${target.path} (no cache entry)`);
|
|
202
151
|
return [];
|
|
203
152
|
}
|
|
204
|
-
for (const { key, entry, extractedParams
|
|
205
|
-
|
|
153
|
+
for (const { key, entry, extractedParams } of matchingEntries) {
|
|
154
|
+
const targetWithState = target;
|
|
155
|
+
const filterPredicate = targetWithState.__state ? targetWithState.__state.filter : target.filter;
|
|
156
|
+
if (filterPredicate) {
|
|
206
157
|
const options = extractOptionsFromKey(key) ?? {};
|
|
207
|
-
const mappedParams = mapParamsToTargetNames(
|
|
208
|
-
options.params,
|
|
209
|
-
paramMapping
|
|
210
|
-
);
|
|
211
158
|
const mergedOptions = {
|
|
212
159
|
...options,
|
|
213
160
|
params: {
|
|
214
|
-
...
|
|
215
|
-
...
|
|
161
|
+
...options.params,
|
|
162
|
+
...extractedParams
|
|
216
163
|
}
|
|
217
164
|
};
|
|
218
165
|
try {
|
|
219
|
-
if (!
|
|
220
|
-
t?.skip(
|
|
221
|
-
`Skipped ${formatCacheKeyForTrace(key)} (filter not matched)`
|
|
222
|
-
);
|
|
166
|
+
if (!filterPredicate(mergedOptions)) {
|
|
223
167
|
continue;
|
|
224
168
|
}
|
|
225
169
|
} catch {
|
|
@@ -228,7 +172,6 @@ function applyUpdate(stateManager, target, updater, response, t) {
|
|
|
228
172
|
}
|
|
229
173
|
}
|
|
230
174
|
if (entry?.state.data === void 0) {
|
|
231
|
-
t?.skip(`Skipped ${formatCacheKeyForTrace(key)} (no cached data)`);
|
|
232
175
|
continue;
|
|
233
176
|
}
|
|
234
177
|
const afterData = updater(entry.state.data, response);
|
|
@@ -291,11 +234,13 @@ function optimisticPlugin() {
|
|
|
291
234
|
context.plugins.get("spoosh:invalidation")?.setDefaultMode("none");
|
|
292
235
|
const allImmediateSnapshots = [];
|
|
293
236
|
for (const target of targets) {
|
|
294
|
-
|
|
237
|
+
const targetWithState = target;
|
|
238
|
+
const immediateUpdater = targetWithState.__state ? targetWithState.__state.immediateUpdater : target.immediateUpdater;
|
|
239
|
+
if (!immediateUpdater) continue;
|
|
295
240
|
const snapshots = applyUpdate(
|
|
296
241
|
stateManager,
|
|
297
242
|
target,
|
|
298
|
-
|
|
243
|
+
immediateUpdater,
|
|
299
244
|
void 0,
|
|
300
245
|
t
|
|
301
246
|
);
|
|
@@ -309,9 +254,12 @@ function optimisticPlugin() {
|
|
|
309
254
|
}
|
|
310
255
|
const response = await next();
|
|
311
256
|
if (response.error) {
|
|
312
|
-
const shouldRollback = targets.some(
|
|
313
|
-
|
|
314
|
-
|
|
257
|
+
const shouldRollback = targets.some((target) => {
|
|
258
|
+
const targetWithState = target;
|
|
259
|
+
const rollbackOnError = targetWithState.__state ? targetWithState.__state.rollbackOnError : target.rollbackOnError;
|
|
260
|
+
const immediateUpdater = targetWithState.__state ? targetWithState.__state.immediateUpdater : target.immediateUpdater;
|
|
261
|
+
return rollbackOnError && immediateUpdater;
|
|
262
|
+
});
|
|
315
263
|
if (shouldRollback && allImmediateSnapshots.length > 0) {
|
|
316
264
|
rollbackOptimistic(stateManager, allImmediateSnapshots);
|
|
317
265
|
for (const snapshot of allImmediateSnapshots) {
|
|
@@ -322,8 +270,10 @@ function optimisticPlugin() {
|
|
|
322
270
|
}
|
|
323
271
|
}
|
|
324
272
|
for (const target of targets) {
|
|
325
|
-
|
|
326
|
-
|
|
273
|
+
const targetWithState = target;
|
|
274
|
+
const onError = targetWithState.__state ? targetWithState.__state.onError : target.onError;
|
|
275
|
+
if (onError) {
|
|
276
|
+
onError(response.error);
|
|
327
277
|
}
|
|
328
278
|
}
|
|
329
279
|
} else {
|
|
@@ -331,11 +281,13 @@ function optimisticPlugin() {
|
|
|
331
281
|
confirmOptimistic(stateManager, allImmediateSnapshots);
|
|
332
282
|
}
|
|
333
283
|
for (const target of targets) {
|
|
334
|
-
|
|
284
|
+
const targetWithState = target;
|
|
285
|
+
const confirmedUpdater = targetWithState.__state ? targetWithState.__state.confirmedUpdater : target.confirmedUpdater;
|
|
286
|
+
if (!confirmedUpdater) continue;
|
|
335
287
|
const snapshots = applyUpdate(
|
|
336
288
|
stateManager,
|
|
337
289
|
target,
|
|
338
|
-
|
|
290
|
+
confirmedUpdater,
|
|
339
291
|
response.data,
|
|
340
292
|
t
|
|
341
293
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spoosh/plugin-optimistic",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Optimistic updates plugin for Spoosh - instant UI updates with automatic rollback",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"@spoosh/plugin-invalidation": ">=0.7.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@spoosh/core": "0.17.
|
|
41
|
-
"@spoosh/
|
|
42
|
-
"@spoosh/
|
|
40
|
+
"@spoosh/core": "0.17.1",
|
|
41
|
+
"@spoosh/test-utils": "0.3.0",
|
|
42
|
+
"@spoosh/plugin-invalidation": "0.10.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"dev": "tsup --watch",
|