@arrai-innovations/reactive-helpers 2.0.1 → 2.1.1
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/package.json
CHANGED
|
@@ -219,14 +219,45 @@ describe("use/objectInstance.js", function () {
|
|
|
219
219
|
id,
|
|
220
220
|
retrieveArgs,
|
|
221
221
|
});
|
|
222
|
+
objectInstance.state.crud.create = jest.fn();
|
|
223
|
+
objectInstance.state.crud.create.mockImplementation(() => new Promise(() => {}));
|
|
222
224
|
objectInstance.state.crud.retrieve = jest.fn();
|
|
223
225
|
objectInstance.state.crud.retrieve.mockImplementation(() => new Promise(() => {}));
|
|
224
226
|
expectErrorToBeNull(objectInstance.state.error);
|
|
225
227
|
expect(objectInstance.state.errored).toBe(false);
|
|
226
228
|
expect(objectInstance.state.loading).toBeUndefined();
|
|
227
229
|
expect({ ...objectInstance.state.object }).toEqual({});
|
|
228
|
-
objectInstance.
|
|
230
|
+
objectInstance.create({
|
|
231
|
+
fake: "object",
|
|
232
|
+
});
|
|
233
|
+
expectErrorToBeNull(objectInstance.state.error);
|
|
234
|
+
expect(objectInstance.state.errored).toBe(false);
|
|
235
|
+
expect(objectInstance.state.loading).toBe(true);
|
|
229
236
|
await expect(() => objectInstance.retrieve()).rejects.toThrow(ObjectError);
|
|
237
|
+
expect(objectInstance.state.crud.retrieve).toHaveBeenCalledTimes(0);
|
|
238
|
+
expectErrorToBeNull(objectInstance.state.error);
|
|
239
|
+
expect(objectInstance.state.errored).toBe(false);
|
|
240
|
+
expect(objectInstance.state.loading).toBe(true);
|
|
241
|
+
expect({ ...objectInstance.state.object }).toEqual({});
|
|
242
|
+
});
|
|
243
|
+
it("double retrieve gets the same promise", async function () {
|
|
244
|
+
const id = ref(1);
|
|
245
|
+
const retrieveArgs = reactive({ fields });
|
|
246
|
+
const objectInstance = useObjectInstance({
|
|
247
|
+
crudArgs: { stream: "test_stream" },
|
|
248
|
+
id,
|
|
249
|
+
retrieveArgs,
|
|
250
|
+
});
|
|
251
|
+
objectInstance.state.crud.retrieve = jest.fn();
|
|
252
|
+
objectInstance.state.crud.retrieve.mockImplementation(() => new Promise(() => {}));
|
|
253
|
+
expectErrorToBeNull(objectInstance.state.error);
|
|
254
|
+
expect(objectInstance.state.errored).toBe(false);
|
|
255
|
+
expect(objectInstance.state.loading).toBeUndefined();
|
|
256
|
+
expect({ ...objectInstance.state.object }).toEqual({});
|
|
257
|
+
const firstPromise = objectInstance.retrieve();
|
|
258
|
+
const secondPromise = objectInstance.retrieve();
|
|
259
|
+
// await expect(() => objectInstance.retrieve()).rejects.toThrow(ObjectError);
|
|
260
|
+
expect(firstPromise).toBe(secondPromise);
|
|
230
261
|
expect(objectInstance.state.crud.retrieve).toHaveBeenCalledWith({
|
|
231
262
|
crudArgs: { stream: "test_stream" },
|
|
232
263
|
id: 1,
|
package/use/listSubscription.js
CHANGED
|
@@ -4,6 +4,7 @@ import { cloneDeep, isEmpty, isObject } from "lodash";
|
|
|
4
4
|
import { assignReactiveObject } from "../utils/assignReactiveObject";
|
|
5
5
|
import inspect from "browser-util-inspect";
|
|
6
6
|
import { useCancellableIntent } from "../utils/cancellableIntent";
|
|
7
|
+
import loadingCombine from "../utils/loadingCombine";
|
|
7
8
|
|
|
8
9
|
export class ListSubscriptionError extends Error {
|
|
9
10
|
constructor(message) {
|
|
@@ -140,7 +141,7 @@ export function useListSubscription({ listInstance, crudArgs, listArgs, retrieve
|
|
|
140
141
|
const es = effectScope();
|
|
141
142
|
|
|
142
143
|
es.run(() => {
|
|
143
|
-
state.loading = computed(() => listInstance.state.loading
|
|
144
|
+
state.loading = computed(() => loadingCombine(listInstance.state.loading, state.subscriptionLoading));
|
|
144
145
|
state.errored = computed(() => listInstance.state.errored || state.subscriptionErrored);
|
|
145
146
|
state.error = computed(() => listInstance.state.error || state.subscriptionError);
|
|
146
147
|
|
package/use/objectInstance.js
CHANGED
|
@@ -59,15 +59,26 @@ export function useObjectInstance({ crudArgs, id, retrieveArgs }) {
|
|
|
59
59
|
assignReactiveObject(state.crud.args, crudArgs);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
// due to retrieve being called by `useCancelleableIntent`, if called manually then by the watch,
|
|
63
|
+
// it will run into the loading check. Instead, return the current retrieve promise if it exists.
|
|
64
|
+
const promises = {
|
|
65
|
+
retrieve: null,
|
|
66
|
+
};
|
|
67
|
+
|
|
62
68
|
function retrieve() {
|
|
63
69
|
// this function cannot be async, or the resulting promise will lose its .cancel() method
|
|
70
|
+
if (promises.retrieve) {
|
|
71
|
+
// if a retrieve is already in progress, return the existing promise
|
|
72
|
+
return promises.retrieve;
|
|
73
|
+
}
|
|
64
74
|
if (state.loading) {
|
|
75
|
+
// if another operation is already in progress, return a rejected promise
|
|
65
76
|
return Promise.reject(new ObjectError("already loading."));
|
|
66
77
|
}
|
|
67
78
|
state.loading = true;
|
|
68
79
|
state.errored = false;
|
|
69
80
|
state.error = null;
|
|
70
|
-
|
|
81
|
+
promises.retrieve = state.crud
|
|
71
82
|
.retrieve({
|
|
72
83
|
crudArgs: state.crud.args,
|
|
73
84
|
id: state.id,
|
|
@@ -84,7 +95,9 @@ export function useObjectInstance({ crudArgs, id, retrieveArgs }) {
|
|
|
84
95
|
})
|
|
85
96
|
.finally(() => {
|
|
86
97
|
state.loading = false;
|
|
98
|
+
promises.retrieve = null;
|
|
87
99
|
});
|
|
100
|
+
return promises.retrieve;
|
|
88
101
|
}
|
|
89
102
|
|
|
90
103
|
async function create({ object }) {
|
|
@@ -3,6 +3,7 @@ import { computed, effectScope, reactive, toRef } from "vue";
|
|
|
3
3
|
import { assignReactiveObject } from "../utils/assignReactiveObject";
|
|
4
4
|
import { useObjectInstance } from "./objectInstance";
|
|
5
5
|
import { useCancellableIntent } from "../utils/cancellableIntent";
|
|
6
|
+
import loadingCombine from "../utils/loadingCombine";
|
|
6
7
|
|
|
7
8
|
export class ObjectSubscriptionError extends Error {
|
|
8
9
|
constructor(message) {
|
|
@@ -149,7 +150,7 @@ export function useObjectSubscription({ objectInstance, crudArgs, id, retrieveAr
|
|
|
149
150
|
const es = effectScope();
|
|
150
151
|
|
|
151
152
|
es.run(() => {
|
|
152
|
-
state.loading = computed(() => objectInstance.state.loading
|
|
153
|
+
state.loading = computed(() => loadingCombine(objectInstance.state.loading, state.subscriptionLoading));
|
|
153
154
|
state.errored = computed(() => objectInstance.state.errored || state.subscriptionErrored);
|
|
154
155
|
state.error = computed(() => objectInstance.state.error || state.subscriptionError);
|
|
155
156
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default function (...loadingStates) {
|
|
2
|
+
// loadingStates is an array of booleans or undefined
|
|
3
|
+
// if any true, return true
|
|
4
|
+
// if all undefined, return undefined
|
|
5
|
+
// otherwise return false (all false)
|
|
6
|
+
if (loadingStates.some((loadingState) => loadingState === true)) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (loadingStates.every((loadingState) => loadingState === undefined)) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|