@arrai-innovations/reactive-helpers 18.0.0 → 18.0.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/package.json +20 -6
- package/types/config/listCrud.d.ts +153 -0
- package/types/config/listCrud.d.ts.map +1 -0
- package/types/config/objectCrud.d.ts +171 -0
- package/types/config/objectCrud.d.ts.map +1 -0
- package/types/index.d.ts +37 -0
- package/types/index.d.ts.map +1 -0
- package/types/tests/unit/config/listCrud.spec.d.ts +2 -0
- package/types/tests/unit/config/listCrud.spec.d.ts.map +1 -0
- package/types/tests/unit/config/objectCrud.spec.d.ts +2 -0
- package/types/tests/unit/config/objectCrud.spec.d.ts.map +1 -0
- package/types/tests/unit/crudPromise.d.ts +25 -0
- package/types/tests/unit/crudPromise.d.ts.map +1 -0
- package/types/tests/unit/expectHelpers.d.ts +2 -0
- package/types/tests/unit/expectHelpers.d.ts.map +1 -0
- package/types/tests/unit/mockOnUnmounted.d.ts +2 -0
- package/types/tests/unit/mockOnUnmounted.d.ts.map +1 -0
- package/types/tests/unit/poll.d.ts +2 -0
- package/types/tests/unit/poll.d.ts.map +1 -0
- package/types/tests/unit/use/cancellableIntent.spec.d.ts +2 -0
- package/types/tests/unit/use/cancellableIntent.spec.d.ts.map +1 -0
- package/types/tests/unit/use/listCalculated.spec.d.ts +2 -0
- package/types/tests/unit/use/listCalculated.spec.d.ts.map +1 -0
- package/types/tests/unit/use/listFilter.spec.d.ts +2 -0
- package/types/tests/unit/use/listFilter.spec.d.ts.map +1 -0
- package/types/tests/unit/use/listInstance.spec.d.ts +2 -0
- package/types/tests/unit/use/listInstance.spec.d.ts.map +1 -0
- package/types/tests/unit/use/listRelated.spec.d.ts +2 -0
- package/types/tests/unit/use/listRelated.spec.d.ts.map +1 -0
- package/types/tests/unit/use/listSearch.spec.d.ts +2 -0
- package/types/tests/unit/use/listSearch.spec.d.ts.map +1 -0
- package/types/tests/unit/use/listSort.spec.d.ts +2 -0
- package/types/tests/unit/use/listSort.spec.d.ts.map +1 -0
- package/types/tests/unit/use/listSubscription.spec.d.ts +2 -0
- package/types/tests/unit/use/listSubscription.spec.d.ts.map +1 -0
- package/types/tests/unit/use/loadingError.spec.d.ts +2 -0
- package/types/tests/unit/use/loadingError.spec.d.ts.map +1 -0
- package/types/tests/unit/use/objectInstance.spec.d.ts +2 -0
- package/types/tests/unit/use/objectInstance.spec.d.ts.map +1 -0
- package/types/tests/unit/use/objectSubscription.spec.d.ts +2 -0
- package/types/tests/unit/use/objectSubscription.spec.d.ts.map +1 -0
- package/types/tests/unit/use/proxyLoadingError.spec.d.ts +2 -0
- package/types/tests/unit/use/proxyLoadingError.spec.d.ts.map +1 -0
- package/types/tests/unit/use/search.spec.d.ts +2 -0
- package/types/tests/unit/use/search.spec.d.ts.map +1 -0
- package/types/tests/unit/utils/assignReactiveObject.spec.d.ts +2 -0
- package/types/tests/unit/utils/assignReactiveObject.spec.d.ts.map +1 -0
- package/types/tests/unit/utils/classes.spec.d.ts +2 -0
- package/types/tests/unit/utils/classes.spec.d.ts.map +1 -0
- package/types/tests/unit/utils/deleteKey.spec.d.ts +2 -0
- package/types/tests/unit/utils/deleteKey.spec.d.ts.map +1 -0
- package/types/tests/unit/utils/flattenPaths.spec.d.ts +2 -0
- package/types/tests/unit/utils/flattenPaths.spec.d.ts.map +1 -0
- package/types/tests/unit/utils/keyDiff.spec.d.ts +2 -0
- package/types/tests/unit/utils/keyDiff.spec.d.ts.map +1 -0
- package/types/tests/unit/utils/set.spec.d.ts +2 -0
- package/types/tests/unit/utils/set.spec.d.ts.map +1 -0
- package/types/tests/unit/utils/watches.spec.d.ts +2 -0
- package/types/tests/unit/utils/watches.spec.d.ts.map +1 -0
- package/types/use/cancellableIntent.d.ts +129 -0
- package/types/use/cancellableIntent.d.ts.map +1 -0
- package/types/use/combineClasses.d.ts +43 -0
- package/types/use/combineClasses.d.ts.map +1 -0
- package/types/use/list.d.ts +176 -0
- package/types/use/list.d.ts.map +1 -0
- package/types/use/listCalculated.d.ts +192 -0
- package/types/use/listCalculated.d.ts.map +1 -0
- package/types/use/listFilter.d.ts +203 -0
- package/types/use/listFilter.d.ts.map +1 -0
- package/types/use/listInstance.d.ts +357 -0
- package/types/use/listInstance.d.ts.map +1 -0
- package/types/use/listKeys.d.ts +15 -0
- package/types/use/listKeys.d.ts.map +1 -0
- package/types/use/listRelated.d.ts +239 -0
- package/types/use/listRelated.d.ts.map +1 -0
- package/types/use/listSearch.d.ts +298 -0
- package/types/use/listSearch.d.ts.map +1 -0
- package/types/use/listSort.d.ts +235 -0
- package/types/use/listSort.d.ts.map +1 -0
- package/types/use/listSubscription.d.ts +218 -0
- package/types/use/listSubscription.d.ts.map +1 -0
- package/types/use/loadingError.d.ts +81 -0
- package/types/use/loadingError.d.ts.map +1 -0
- package/types/use/object.d.ts +67 -0
- package/types/use/object.d.ts.map +1 -0
- package/types/use/objectCalculated.d.ts +215 -0
- package/types/use/objectCalculated.d.ts.map +1 -0
- package/types/use/objectInstance.d.ts +289 -0
- package/types/use/objectInstance.d.ts.map +1 -0
- package/types/use/objectRelated.d.ts +264 -0
- package/types/use/objectRelated.d.ts.map +1 -0
- package/types/use/objectSubscription.d.ts +249 -0
- package/types/use/objectSubscription.d.ts.map +1 -0
- package/types/use/paginatedListInstance.d.ts +51 -0
- package/types/use/paginatedListInstance.d.ts.map +1 -0
- package/types/use/proxyLoadingError.d.ts +36 -0
- package/types/use/proxyLoadingError.d.ts.map +1 -0
- package/types/use/search.d.ts +144 -0
- package/types/use/search.d.ts.map +1 -0
- package/types/use/watchesRunning.d.ts +63 -0
- package/types/use/watchesRunning.d.ts.map +1 -0
- package/types/utils/assignReactiveObject.d.ts +115 -0
- package/types/utils/assignReactiveObject.d.ts.map +1 -0
- package/types/utils/classes.d.ts +22 -0
- package/types/utils/classes.d.ts.map +1 -0
- package/types/utils/compact.d.ts +4 -0
- package/types/utils/compact.d.ts.map +1 -0
- package/types/utils/deleteKey.d.ts +16 -0
- package/types/utils/deleteKey.d.ts.map +1 -0
- package/types/utils/flattenPaths.d.ts +23 -0
- package/types/utils/flattenPaths.d.ts.map +1 -0
- package/types/utils/getFakePk.d.ts +13 -0
- package/types/utils/getFakePk.d.ts.map +1 -0
- package/types/utils/keepAliveTry.d.ts +15 -0
- package/types/utils/keepAliveTry.d.ts.map +1 -0
- package/types/utils/keyDiff.d.ts +63 -0
- package/types/utils/keyDiff.d.ts.map +1 -0
- package/types/utils/loadingCombine.d.ts +9 -0
- package/types/utils/loadingCombine.d.ts.map +1 -0
- package/types/utils/proxyRunning.d.ts +9 -0
- package/types/utils/proxyRunning.d.ts.map +1 -0
- package/types/utils/relatedCalculatedHelpers.d.ts +5 -0
- package/types/utils/relatedCalculatedHelpers.d.ts.map +1 -0
- package/types/utils/set.d.ts +7 -0
- package/types/utils/set.d.ts.map +1 -0
- package/types/utils/transformWalk.d.ts +2 -0
- package/types/utils/transformWalk.d.ts.map +1 -0
- package/types/utils/watches.d.ts +155 -0
- package/types/utils/watches.d.ts.map +1 -0
- package/use/loadingError.js +1 -1
- package/.circleci/config.yml +0 -88
- package/.commitlintrc.json +0 -25
- package/.editorconfig +0 -5
- package/.husky/commit-msg +0 -3
- package/.husky/pre-commit +0 -3
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/encodings.xml +0 -6
- package/.idea/inspectionProfiles/Project_Default.xml +0 -7
- package/.idea/modules.xml +0 -8
- package/.idea/prettier.xml +0 -8
- package/.idea/reactive-helpers.iml +0 -15
- package/.prettierignore +0 -5
- package/.prettierrc.cjs +0 -5
- package/.vscode/extensions.json +0 -3
- package/docs/README.md +0 -45
- package/docs/config/listCrud.md +0 -422
- package/docs/config/objectCrud.md +0 -427
- package/docs/use/cancellableIntent.md +0 -165
- package/docs/use/combineClasses.md +0 -62
- package/docs/use/list.md +0 -361
- package/docs/use/listCalculated.md +0 -794
- package/docs/use/listFilter.md +0 -897
- package/docs/use/listInstance.md +0 -559
- package/docs/use/listKeys.md +0 -91
- package/docs/use/listRelated.md +0 -706
- package/docs/use/listSearch.md +0 -903
- package/docs/use/listSort.md +0 -1171
- package/docs/use/listSubscription.md +0 -393
- package/docs/use/loadingError.md +0 -115
- package/docs/use/object.md +0 -668
- package/docs/use/objectCalculated.md +0 -741
- package/docs/use/objectInstance.md +0 -685
- package/docs/use/objectRelated.md +0 -723
- package/docs/use/objectSubscription.md +0 -538
- package/docs/use/paginatedListInstance.md +0 -155
- package/docs/use/proxyLoadingError.md +0 -51
- package/docs/use/search.md +0 -321
- package/docs/use/watchesRunning.md +0 -84
- package/docs/utils/assignReactiveObject.md +0 -413
- package/docs/utils/classes.md +0 -139
- package/docs/utils/compact.md +0 -67
- package/docs/utils/deleteKey.md +0 -61
- package/docs/utils/flattenPaths.md +0 -53
- package/docs/utils/getFakePk.md +0 -39
- package/docs/utils/keepAliveTry.md +0 -59
- package/docs/utils/keyDiff.md +0 -117
- package/docs/utils/loadingCombine.md +0 -30
- package/docs/utils/proxyRunning.md +0 -39
- package/docs/utils/relatedCalculatedHelpers.md +0 -93
- package/docs/utils/set.md +0 -223
- package/docs/utils/transformWalk.md +0 -68
- package/docs/utils/watches.md +0 -489
- package/eslint.config.js +0 -125
- package/lint-staged.config.js +0 -10
- package/makeTypeDoc.sh +0 -25
- package/make_type_doc.js +0 -59
- package/tests/unit/config/listCrud.spec.js +0 -114
- package/tests/unit/config/objectCrud.spec.js +0 -160
- package/tests/unit/crudPromise.js +0 -40
- package/tests/unit/expectHelpers.js +0 -6
- package/tests/unit/mockOnUnmounted.js +0 -9
- package/tests/unit/poll.js +0 -50
- package/tests/unit/use/cancellableIntent.spec.js +0 -152
- package/tests/unit/use/listCalculated.spec.js +0 -135
- package/tests/unit/use/listFilter.spec.js +0 -484
- package/tests/unit/use/listInstance.spec.js +0 -1166
- package/tests/unit/use/listRelated.spec.js +0 -260
- package/tests/unit/use/listSearch.spec.js +0 -586
- package/tests/unit/use/listSort.spec.js +0 -418
- package/tests/unit/use/listSubscription.spec.js +0 -845
- package/tests/unit/use/loadingError.spec.js +0 -43
- package/tests/unit/use/objectInstance.spec.js +0 -1525
- package/tests/unit/use/objectSubscription.spec.js +0 -849
- package/tests/unit/use/proxyLoadingError.spec.js +0 -64
- package/tests/unit/use/search.spec.js +0 -248
- package/tests/unit/utils/assignReactiveObject.spec.js +0 -593
- package/tests/unit/utils/classes.spec.js +0 -427
- package/tests/unit/utils/deleteKey.spec.js +0 -265
- package/tests/unit/utils/flattenPaths.spec.js +0 -126
- package/tests/unit/utils/keyDiff.spec.js +0 -110
- package/tests/unit/utils/set.spec.js +0 -81
- package/tests/unit/utils/watches.spec.js +0 -276
- package/tsconfig.json +0 -19
- package/typedoc-local-plugins/customize-output.js +0 -13
- package/typedoc.json +0 -11
- package/vitest.config.js +0 -11
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import cloneDeep from "lodash-es/cloneDeep.js";
|
|
2
|
-
import { reactive } from "vue";
|
|
3
|
-
|
|
4
|
-
describe("config/listCrud.js", () => {
|
|
5
|
-
describe("get & set", () => {
|
|
6
|
-
let setListCrud, getListCrud;
|
|
7
|
-
beforeAll(async () => {
|
|
8
|
-
const listCrudModule = await import("../../../config/listCrud.js");
|
|
9
|
-
setListCrud = listCrudModule.setListCrud;
|
|
10
|
-
getListCrud = listCrudModule.getListCrud;
|
|
11
|
-
});
|
|
12
|
-
it("should not die getting crud before setting", () => {
|
|
13
|
-
const reactiveCrud = reactive({});
|
|
14
|
-
expect(() => getListCrud(reactiveCrud)).not.toThrow();
|
|
15
|
-
});
|
|
16
|
-
it("should set and get the default crud, avoiding mutation", () => {
|
|
17
|
-
const crud = {
|
|
18
|
-
list: () => 1,
|
|
19
|
-
subscribe: () => 2,
|
|
20
|
-
args: {
|
|
21
|
-
test: "test",
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
expect(() => setListCrud(crud)).not.toThrow();
|
|
25
|
-
|
|
26
|
-
/** @type {import("vue").UnwrapNestedRefs<
|
|
27
|
-
* import('../../../config/listCrud.js').ListCrudFunctions &
|
|
28
|
-
* import('../../../config/listCrud.js').ListCrudArgs
|
|
29
|
-
* >}
|
|
30
|
-
*/
|
|
31
|
-
const retrievedCrud = reactive({});
|
|
32
|
-
expect(() => getListCrud(retrievedCrud)).not.toThrow();
|
|
33
|
-
expect(new Set(Object.keys(retrievedCrud))).toEqual(
|
|
34
|
-
new Set(["list", "bulkDelete", "executeAction", "subscribe", "args"])
|
|
35
|
-
);
|
|
36
|
-
expect(retrievedCrud.args).not.toBe(crud.args);
|
|
37
|
-
expect(retrievedCrud.args).toEqual(crud.args);
|
|
38
|
-
expect(retrievedCrud.list).toBe(crud.list);
|
|
39
|
-
expect(retrievedCrud.subscribe).toBe(crud.subscribe);
|
|
40
|
-
|
|
41
|
-
const originalCrud = cloneDeep(crud);
|
|
42
|
-
crud.args.test = "test2";
|
|
43
|
-
crud.list = () => 3;
|
|
44
|
-
crud.subscribe = () => 4;
|
|
45
|
-
expect(retrievedCrud.args.test).toBe(originalCrud.args.test);
|
|
46
|
-
expect(retrievedCrud.list).toBe(originalCrud.list);
|
|
47
|
-
expect(retrievedCrud.subscribe).toBe(originalCrud.subscribe);
|
|
48
|
-
});
|
|
49
|
-
it("should die if an unknown function is passed", () => {
|
|
50
|
-
expect(() =>
|
|
51
|
-
setListCrud({ list: () => 1, subscribe: () => 2, args: { test: "test" }, unknown: () => 3 })
|
|
52
|
-
).toThrow("Unknown key(s) passed to setListCrud: unknown");
|
|
53
|
-
});
|
|
54
|
-
it("should customize via getListCrud", () => {
|
|
55
|
-
const defaultCrud = {
|
|
56
|
-
list: () => 1,
|
|
57
|
-
subscribe: () => 2,
|
|
58
|
-
args: {
|
|
59
|
-
test: "test",
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
const customCrudArgs = {
|
|
63
|
-
props: reactive({
|
|
64
|
-
crudArgs: {
|
|
65
|
-
test: "test2",
|
|
66
|
-
},
|
|
67
|
-
}),
|
|
68
|
-
functions: {
|
|
69
|
-
list: () => 3,
|
|
70
|
-
subscribe: () => 4,
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
const expectedCustomCrud = {
|
|
74
|
-
list: customCrudArgs.functions.list,
|
|
75
|
-
subscribe: customCrudArgs.functions.subscribe,
|
|
76
|
-
args: customCrudArgs.props.crudArgs,
|
|
77
|
-
};
|
|
78
|
-
expect(() => setListCrud(defaultCrud)).not.toThrow();
|
|
79
|
-
const defaultRetrievedCrud = reactive({});
|
|
80
|
-
getListCrud(defaultRetrievedCrud);
|
|
81
|
-
expect(defaultRetrievedCrud).toEqual(defaultCrud);
|
|
82
|
-
expect(defaultRetrievedCrud).not.toEqual(expectedCustomCrud);
|
|
83
|
-
const customRetrievedCrud = reactive({});
|
|
84
|
-
getListCrud(customRetrievedCrud, customCrudArgs);
|
|
85
|
-
expect(customRetrievedCrud).toEqual(expectedCustomCrud);
|
|
86
|
-
expect(customRetrievedCrud).not.toEqual(defaultCrud);
|
|
87
|
-
expect(defaultRetrievedCrud).toEqual(defaultCrud);
|
|
88
|
-
expect(defaultRetrievedCrud).not.toEqual(expectedCustomCrud);
|
|
89
|
-
});
|
|
90
|
-
it("should throw if passed functions object that has values that are not functions", () => {
|
|
91
|
-
const retrievedCrud = reactive({});
|
|
92
|
-
expect(() =>
|
|
93
|
-
getListCrud(retrievedCrud, {
|
|
94
|
-
functions: {
|
|
95
|
-
list: () => 1,
|
|
96
|
-
subscribe: true,
|
|
97
|
-
},
|
|
98
|
-
})
|
|
99
|
-
).toThrow('Invalid function "subscribe" for getListCrud: invalid key or not a function.');
|
|
100
|
-
});
|
|
101
|
-
it("should throw if passed unexpected functions", () => {
|
|
102
|
-
const retrievedCrud = reactive({});
|
|
103
|
-
expect(() =>
|
|
104
|
-
getListCrud(retrievedCrud, {
|
|
105
|
-
functions: {
|
|
106
|
-
list: () => 1,
|
|
107
|
-
subscribe: () => 2,
|
|
108
|
-
unknown: () => 3,
|
|
109
|
-
},
|
|
110
|
-
})
|
|
111
|
-
).toThrow('Invalid function "unknown" for getListCrud: invalid key or not a function.');
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import cloneDeep from "lodash-es/cloneDeep.js";
|
|
2
|
-
import { reactive } from "vue";
|
|
3
|
-
|
|
4
|
-
describe("config/objectCrud.js", () => {
|
|
5
|
-
describe("get & set", () => {
|
|
6
|
-
let setObjectCrud, getObjectCrud;
|
|
7
|
-
beforeAll(async () => {
|
|
8
|
-
const objectCrudModule = await import("../../../config/objectCrud.js");
|
|
9
|
-
setObjectCrud = objectCrudModule.setObjectCrud;
|
|
10
|
-
getObjectCrud = objectCrudModule.getObjectCrud;
|
|
11
|
-
});
|
|
12
|
-
it("should not die getting crud before setting", () => {
|
|
13
|
-
const reactiveCrud = reactive({});
|
|
14
|
-
expect(() => getObjectCrud(reactiveCrud)).not.toThrow();
|
|
15
|
-
});
|
|
16
|
-
it("should set and get the default crud, avoiding mutation", () => {
|
|
17
|
-
const crud = {
|
|
18
|
-
retrieve: () => 1,
|
|
19
|
-
create: () => 2,
|
|
20
|
-
update: () => 3,
|
|
21
|
-
patch: () => 4,
|
|
22
|
-
delete: () => 5,
|
|
23
|
-
subscribe: () => 6,
|
|
24
|
-
args: {
|
|
25
|
-
test: "test",
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
expect(() => setObjectCrud(crud)).not.toThrow();
|
|
29
|
-
|
|
30
|
-
/** @type {import("vue").UnwrapNestedRefs<
|
|
31
|
-
* import('../../../config/objectCrud.js').ObjectCrudFunctions &
|
|
32
|
-
* import('../../../config/objectCrud.js').ObjectCrudArgs
|
|
33
|
-
* >}
|
|
34
|
-
*/
|
|
35
|
-
const retrievedCrud = reactive({});
|
|
36
|
-
expect(() => getObjectCrud(retrievedCrud)).not.toThrow();
|
|
37
|
-
expect(new Set(Object.keys(retrievedCrud))).toEqual(
|
|
38
|
-
new Set(["retrieve", "create", "update", "patch", "delete", "subscribe", "args"])
|
|
39
|
-
);
|
|
40
|
-
expect(retrievedCrud.args).not.toBe(crud.args);
|
|
41
|
-
expect(retrievedCrud.args).toEqual(crud.args);
|
|
42
|
-
expect(retrievedCrud.retrieve).toBe(crud.retrieve);
|
|
43
|
-
expect(retrievedCrud.create).toBe(crud.create);
|
|
44
|
-
expect(retrievedCrud.update).toBe(crud.update);
|
|
45
|
-
expect(retrievedCrud.patch).toBe(crud.patch);
|
|
46
|
-
expect(retrievedCrud.delete).toBe(crud.delete);
|
|
47
|
-
expect(retrievedCrud.subscribe).toBe(crud.subscribe);
|
|
48
|
-
|
|
49
|
-
const originalCrud = cloneDeep(crud);
|
|
50
|
-
crud.args.test = "test2";
|
|
51
|
-
crud.retrieve = () => 7;
|
|
52
|
-
crud.create = () => 8;
|
|
53
|
-
crud.update = () => 9;
|
|
54
|
-
crud.patch = () => 10;
|
|
55
|
-
crud.delete = () => 11;
|
|
56
|
-
crud.subscribe = () => 12;
|
|
57
|
-
expect(retrievedCrud.args.test).toBe(originalCrud.args.test);
|
|
58
|
-
expect(retrievedCrud.retrieve).toBe(originalCrud.retrieve);
|
|
59
|
-
expect(retrievedCrud.create).toBe(originalCrud.create);
|
|
60
|
-
expect(retrievedCrud.update).toBe(originalCrud.update);
|
|
61
|
-
expect(retrievedCrud.patch).toBe(originalCrud.patch);
|
|
62
|
-
expect(retrievedCrud.delete).toBe(originalCrud.delete);
|
|
63
|
-
expect(retrievedCrud.subscribe).toBe(originalCrud.subscribe);
|
|
64
|
-
});
|
|
65
|
-
it("should customize via getObjectCrud", () => {
|
|
66
|
-
const defaultCrud = {
|
|
67
|
-
retrieve: () => 1,
|
|
68
|
-
create: () => 2,
|
|
69
|
-
update: () => 3,
|
|
70
|
-
patch: () => 4,
|
|
71
|
-
delete: () => 5,
|
|
72
|
-
subscribe: () => 6,
|
|
73
|
-
args: {
|
|
74
|
-
test: "test",
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
const customCrudArgs = {
|
|
78
|
-
props: reactive({
|
|
79
|
-
crudArgs: {
|
|
80
|
-
test: "test2",
|
|
81
|
-
},
|
|
82
|
-
}),
|
|
83
|
-
functions: {
|
|
84
|
-
retrieve: () => 7,
|
|
85
|
-
create: () => 8,
|
|
86
|
-
update: () => 9,
|
|
87
|
-
patch: () => 10,
|
|
88
|
-
delete: () => 11,
|
|
89
|
-
subscribe: () => 12,
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
const expectedCustomCrud = {
|
|
93
|
-
retrieve: customCrudArgs.functions.retrieve,
|
|
94
|
-
create: customCrudArgs.functions.create,
|
|
95
|
-
update: customCrudArgs.functions.update,
|
|
96
|
-
patch: customCrudArgs.functions.patch,
|
|
97
|
-
delete: customCrudArgs.functions.delete,
|
|
98
|
-
subscribe: customCrudArgs.functions.subscribe,
|
|
99
|
-
args: customCrudArgs.props.crudArgs,
|
|
100
|
-
};
|
|
101
|
-
expect(() => setObjectCrud(defaultCrud)).not.toThrow();
|
|
102
|
-
const defaultRetrievedCrud = reactive({});
|
|
103
|
-
getObjectCrud(defaultRetrievedCrud);
|
|
104
|
-
expect(defaultRetrievedCrud).toEqual(defaultCrud);
|
|
105
|
-
expect(defaultRetrievedCrud).not.toEqual(expectedCustomCrud);
|
|
106
|
-
const customRetrievedCrud = reactive({});
|
|
107
|
-
getObjectCrud(customRetrievedCrud, customCrudArgs);
|
|
108
|
-
expect(customRetrievedCrud).toEqual(expectedCustomCrud);
|
|
109
|
-
expect(customRetrievedCrud).not.toEqual(defaultCrud);
|
|
110
|
-
expect(defaultRetrievedCrud).toEqual(defaultCrud);
|
|
111
|
-
expect(defaultRetrievedCrud).not.toEqual(expectedCustomCrud);
|
|
112
|
-
});
|
|
113
|
-
it("should die if an unknown function is passed", () => {
|
|
114
|
-
expect(() =>
|
|
115
|
-
setObjectCrud({
|
|
116
|
-
retrieve: () => 1,
|
|
117
|
-
create: () => 2,
|
|
118
|
-
update: () => 3,
|
|
119
|
-
patch: () => 4,
|
|
120
|
-
delete: () => 5,
|
|
121
|
-
subscribe: () => 6,
|
|
122
|
-
args: { test: "test" },
|
|
123
|
-
unknown: () => 7,
|
|
124
|
-
})
|
|
125
|
-
).toThrow("Unknown key(s) passed to setObjectCrud: unknown");
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it("should throw if passed functions object that has values that are not functions", () => {
|
|
129
|
-
const retrievedCrud = reactive({});
|
|
130
|
-
expect(() =>
|
|
131
|
-
getObjectCrud(retrievedCrud, {
|
|
132
|
-
functions: {
|
|
133
|
-
retrieve: () => 1,
|
|
134
|
-
create: () => 2,
|
|
135
|
-
update: 3,
|
|
136
|
-
patch: () => 4,
|
|
137
|
-
delete: () => 5,
|
|
138
|
-
subscribe: () => 6,
|
|
139
|
-
},
|
|
140
|
-
})
|
|
141
|
-
).toThrow('Invalid function "update" for getObjectCrud: invalid key or not a function.');
|
|
142
|
-
});
|
|
143
|
-
it("should throw if passed unexpected functions", () => {
|
|
144
|
-
const retrievedCrud = reactive({});
|
|
145
|
-
expect(() =>
|
|
146
|
-
getObjectCrud(retrievedCrud, {
|
|
147
|
-
functions: {
|
|
148
|
-
retrieve: () => 1,
|
|
149
|
-
create: () => 2,
|
|
150
|
-
update: () => 3,
|
|
151
|
-
patch: () => 4,
|
|
152
|
-
delete: () => 5,
|
|
153
|
-
subscribe: () => 6,
|
|
154
|
-
unknown: () => 7,
|
|
155
|
-
},
|
|
156
|
-
})
|
|
157
|
-
).toThrow('Invalid function "unknown" for getObjectCrud: invalid key or not a function.');
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A class that wraps a promise and its resolve and reject functions
|
|
3
|
-
*/
|
|
4
|
-
export class Resolvable {
|
|
5
|
-
/**
|
|
6
|
-
* Create a new Resolvable
|
|
7
|
-
*/
|
|
8
|
-
constructor() {
|
|
9
|
-
/**
|
|
10
|
-
* @type {Promise}
|
|
11
|
-
*/
|
|
12
|
-
this.promise = new Promise((resolve, reject) => {
|
|
13
|
-
/** @type {Function} */
|
|
14
|
-
this.resolve = resolve;
|
|
15
|
-
/** @type {Function} */
|
|
16
|
-
this.reject = reject;
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* A Resolvable with a cancel function.
|
|
23
|
-
*/
|
|
24
|
-
export class CancellableResolvable {
|
|
25
|
-
constructor() {
|
|
26
|
-
this.promise = new Promise((resolve, reject) => {
|
|
27
|
-
/** @type {Function} */
|
|
28
|
-
this.resolve = resolve;
|
|
29
|
-
/** @type {Function} */
|
|
30
|
-
this.reject = reject;
|
|
31
|
-
});
|
|
32
|
-
const cancelResolvable = new Resolvable();
|
|
33
|
-
// @ts-ignore - the whole point of this class is add and mock this function
|
|
34
|
-
this.promise.cancel = vi
|
|
35
|
-
.fn()
|
|
36
|
-
.mockImplementationOnce(async () => cancelResolvable.promise)
|
|
37
|
-
.mockRejectedValue(new Error("cancel already called"));
|
|
38
|
-
this.cancel = cancelResolvable;
|
|
39
|
-
}
|
|
40
|
-
}
|
package/tests/unit/poll.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Resolvable } from "./crudPromise.js";
|
|
2
|
-
|
|
3
|
-
export async function poll(condition, interval = 100, timeout = 1000) {
|
|
4
|
-
let intervalId,
|
|
5
|
-
timeoutId,
|
|
6
|
-
resolvable = new Resolvable();
|
|
7
|
-
|
|
8
|
-
const calledStack = new Error().stack.split("\n").slice(2).join("\n");
|
|
9
|
-
|
|
10
|
-
function stop() {
|
|
11
|
-
if (intervalId) {
|
|
12
|
-
clearInterval(intervalId);
|
|
13
|
-
intervalId = null;
|
|
14
|
-
}
|
|
15
|
-
if (timeoutId) {
|
|
16
|
-
clearTimeout(timeoutId);
|
|
17
|
-
timeoutId = null;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function doInterval() {
|
|
22
|
-
if (condition()) {
|
|
23
|
-
stop();
|
|
24
|
-
if (resolvable) {
|
|
25
|
-
resolvable.resolve();
|
|
26
|
-
resolvable = null;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function doTimeout() {
|
|
32
|
-
stop();
|
|
33
|
-
let conditionValue = condition();
|
|
34
|
-
if (conditionValue) {
|
|
35
|
-
if (resolvable) {
|
|
36
|
-
resolvable.resolve();
|
|
37
|
-
resolvable = null;
|
|
38
|
-
}
|
|
39
|
-
} else if (resolvable) {
|
|
40
|
-
let timedOutError = new Error(`poll timeout: condition was never true (it was last ${conditionValue})`);
|
|
41
|
-
timedOutError.stack = timedOutError.stack.split("\n").slice(0, 1).join("\n") + "\n" + calledStack;
|
|
42
|
-
resolvable.reject(timedOutError);
|
|
43
|
-
resolvable = null;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
intervalId = setInterval(doInterval, interval);
|
|
47
|
-
timeoutId = setTimeout(doTimeout, timeout);
|
|
48
|
-
|
|
49
|
-
return resolvable.promise;
|
|
50
|
-
}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { useCancellableIntent } from "../../../use/cancellableIntent.js";
|
|
2
|
-
import { CancellableResolvable } from "../crudPromise.js";
|
|
3
|
-
import flushPromises from "flush-promises";
|
|
4
|
-
import { nextTick, reactive, ref } from "vue";
|
|
5
|
-
|
|
6
|
-
describe("use/cancellableIntent", () => {
|
|
7
|
-
let mockAwaitableWithCancel, cancellableResolvable;
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
cancellableResolvable = new CancellableResolvable();
|
|
10
|
-
mockAwaitableWithCancel = vi.fn().mockReturnValue(cancellableResolvable.promise);
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
cancellableResolvable = null;
|
|
14
|
-
vi.resetAllMocks();
|
|
15
|
-
});
|
|
16
|
-
it("should throw an error if awaitableWithCancel is not provided", () => {
|
|
17
|
-
expect(() => {
|
|
18
|
-
// @ts-ignore - we're testing the error case
|
|
19
|
-
useCancellableIntent({});
|
|
20
|
-
}).toThrow("awaitableWithCancel is required");
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("should throw an error if awaitableWithCancel is not a function", () => {
|
|
24
|
-
expect(() => {
|
|
25
|
-
useCancellableIntent({
|
|
26
|
-
// @ts-ignore - we're testing the error case
|
|
27
|
-
awaitableWithCancel: "not a function",
|
|
28
|
-
});
|
|
29
|
-
}).toThrow("awaitableWithCancel must be a function");
|
|
30
|
-
});
|
|
31
|
-
describe("Resolution", () => {
|
|
32
|
-
it("should initiate the intent and resolve the promise when the awaitableWithCancel resolves", async () => {
|
|
33
|
-
const subscribeIntent = useCancellableIntent({
|
|
34
|
-
awaitableWithCancel: mockAwaitableWithCancel,
|
|
35
|
-
watchArguments: {
|
|
36
|
-
testArg: 1,
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
await nextTick();
|
|
40
|
-
await flushPromises();
|
|
41
|
-
expect(mockAwaitableWithCancel).toHaveBeenCalledTimes(1);
|
|
42
|
-
expect(subscribeIntent.state.active).toBe(true);
|
|
43
|
-
expect(subscribeIntent.state.resolving).toBe(true);
|
|
44
|
-
|
|
45
|
-
cancellableResolvable.resolve(true);
|
|
46
|
-
|
|
47
|
-
await nextTick();
|
|
48
|
-
await flushPromises();
|
|
49
|
-
|
|
50
|
-
expect(subscribeIntent.state.active).toBe(false);
|
|
51
|
-
expect(subscribeIntent.state.resolving).toBe(false);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
describe("Cancellation", () => {
|
|
56
|
-
it("should cancel the previous promise when watched arguments changed", async () => {
|
|
57
|
-
let testArgRef = ref(1);
|
|
58
|
-
const subscribeIntent = useCancellableIntent({
|
|
59
|
-
awaitableWithCancel: mockAwaitableWithCancel,
|
|
60
|
-
watchArguments: reactive({
|
|
61
|
-
testArg: testArgRef,
|
|
62
|
-
}),
|
|
63
|
-
clearActiveOnResolved: true,
|
|
64
|
-
});
|
|
65
|
-
await nextTick();
|
|
66
|
-
await flushPromises();
|
|
67
|
-
expect(mockAwaitableWithCancel).toHaveBeenCalledTimes(1);
|
|
68
|
-
expect(subscribeIntent.state.active).toBe(true);
|
|
69
|
-
expect(subscribeIntent.state.resolving).toBe(true);
|
|
70
|
-
testArgRef.value = 2;
|
|
71
|
-
|
|
72
|
-
await nextTick();
|
|
73
|
-
await flushPromises();
|
|
74
|
-
expect(cancellableResolvable.promise.cancel).toHaveBeenCalledTimes(1);
|
|
75
|
-
expect(subscribeIntent.state.active).toBe(true);
|
|
76
|
-
expect(subscribeIntent.state.resolving).toBe(true);
|
|
77
|
-
|
|
78
|
-
cancellableResolvable.resolve(true);
|
|
79
|
-
await nextTick();
|
|
80
|
-
await flushPromises();
|
|
81
|
-
expect(subscribeIntent.state.active).toBe(false);
|
|
82
|
-
expect(subscribeIntent.state.resolving).toBe(false);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
describe("Delay", () => {
|
|
87
|
-
it("should handle the delayed watch properly", async () => {
|
|
88
|
-
let testGuardRef = ref(true);
|
|
89
|
-
const subscribeIntent = useCancellableIntent({
|
|
90
|
-
awaitableWithCancel: mockAwaitableWithCancel,
|
|
91
|
-
watchArguments: {
|
|
92
|
-
testArg: 1,
|
|
93
|
-
},
|
|
94
|
-
guardArguments: reactive({
|
|
95
|
-
testGuard: testGuardRef,
|
|
96
|
-
}),
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
expect(mockAwaitableWithCancel).not.toHaveBeenCalled();
|
|
100
|
-
expect(subscribeIntent.state.activeCount).toBeUndefined();
|
|
101
|
-
expect(subscribeIntent.state.resolvingCount).toBeUndefined();
|
|
102
|
-
|
|
103
|
-
testGuardRef.value = false;
|
|
104
|
-
await nextTick();
|
|
105
|
-
await flushPromises();
|
|
106
|
-
expect(mockAwaitableWithCancel).toHaveBeenCalled();
|
|
107
|
-
expect(subscribeIntent.state.active).toBe(true);
|
|
108
|
-
expect(subscribeIntent.state.resolving).toBe(true);
|
|
109
|
-
|
|
110
|
-
cancellableResolvable.resolve(true);
|
|
111
|
-
await nextTick();
|
|
112
|
-
await flushPromises();
|
|
113
|
-
expect(subscribeIntent.state.active).toBe(false);
|
|
114
|
-
expect(subscribeIntent.state.resolving).toBe(false);
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
describe("Rejection", () => {
|
|
118
|
-
//error is not being caught
|
|
119
|
-
it.skip("errored", async () => {
|
|
120
|
-
const consoleErrorMock = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
121
|
-
const subscribeIntent = useCancellableIntent({
|
|
122
|
-
awaitableWithCancel: mockAwaitableWithCancel,
|
|
123
|
-
watchArguments: {
|
|
124
|
-
testArg: 1,
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
await nextTick();
|
|
128
|
-
await flushPromises();
|
|
129
|
-
|
|
130
|
-
const mockError = new Error("rejected");
|
|
131
|
-
cancellableResolvable.reject(mockError);
|
|
132
|
-
|
|
133
|
-
await nextTick();
|
|
134
|
-
await flushPromises();
|
|
135
|
-
|
|
136
|
-
expect(cancellableResolvable.promise.cancel).toHaveBeenCalledTimes(1);
|
|
137
|
-
expect(subscribeIntent.state.active).toBe(true);
|
|
138
|
-
expect(subscribeIntent.state.resolving).toBe(true);
|
|
139
|
-
|
|
140
|
-
await cancellableResolvable.cancel.resolve(true);
|
|
141
|
-
await nextTick();
|
|
142
|
-
await flushPromises();
|
|
143
|
-
|
|
144
|
-
await expect(cancellableResolvable.promise).rejects.toThrow(mockError);
|
|
145
|
-
expect(consoleErrorMock).toHaveBeenCalledWith(mockError);
|
|
146
|
-
expect(subscribeIntent.state.active).toBe(false);
|
|
147
|
-
expect(subscribeIntent.state.resolving).toBe(false);
|
|
148
|
-
expect(subscribeIntent.state.errored).toBe(true);
|
|
149
|
-
expect(subscribeIntent.state.error).toBe(mockError);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
});
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { nextTick } from "vue";
|
|
2
|
-
import { deepUnref } from "vue-deepunref";
|
|
3
|
-
|
|
4
|
-
describe("use/listCalculated", () => {
|
|
5
|
-
let useListInstance, useListCalculated, useListRelated, AwaitNot;
|
|
6
|
-
beforeEach(async () => {
|
|
7
|
-
const listInstanceModule = await import("../../../use/listInstance.js");
|
|
8
|
-
useListInstance = listInstanceModule.useListInstance;
|
|
9
|
-
const listCalculatedModule = await import("../../../use/listCalculated.js");
|
|
10
|
-
useListCalculated = listCalculatedModule.useListCalculated;
|
|
11
|
-
// todo: no useListCalculateds test yet
|
|
12
|
-
const listRelatedModule = await import("../../../use/listRelated.js");
|
|
13
|
-
useListRelated = listRelatedModule.useListRelated;
|
|
14
|
-
const watchesModule = await import("../../../utils/watches.js");
|
|
15
|
-
AwaitNot = watchesModule.AwaitNot;
|
|
16
|
-
});
|
|
17
|
-
it("should return a list of calculated items", async () => {
|
|
18
|
-
const mainListInstance = useListInstance({ props: { pkKey: "id" }, keepOldPages: false });
|
|
19
|
-
const calculatedListInstance = useListInstance({ props: { pkKey: "id" }, keepOldPages: false });
|
|
20
|
-
mainListInstance.addListObject({
|
|
21
|
-
id: "1",
|
|
22
|
-
name: "main",
|
|
23
|
-
calculated_items: ["2", "3"],
|
|
24
|
-
calculated_id: "4",
|
|
25
|
-
});
|
|
26
|
-
calculatedListInstance.addListObject({
|
|
27
|
-
id: "2",
|
|
28
|
-
name: "calculated1",
|
|
29
|
-
});
|
|
30
|
-
calculatedListInstance.addListObject({
|
|
31
|
-
id: "3",
|
|
32
|
-
name: "calculated2",
|
|
33
|
-
});
|
|
34
|
-
calculatedListInstance.addListObject({
|
|
35
|
-
id: "4",
|
|
36
|
-
name: "calculated3",
|
|
37
|
-
});
|
|
38
|
-
const listCalculated = useListCalculated({
|
|
39
|
-
parentState: mainListInstance.state,
|
|
40
|
-
calculatedObjectsRules: {
|
|
41
|
-
calculatedItems: (obj) => obj.calculated_items.map((x) => calculatedListInstance.state.objects[x]),
|
|
42
|
-
calculatedItem: (obj) => calculatedListInstance.state.objects[obj.calculated_id],
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
await nextTick();
|
|
46
|
-
// listCalculated.state.objects is doing proxy shenanigans
|
|
47
|
-
// in uses handler.has
|
|
48
|
-
expect(!!listCalculated.state.calculatedObjects?.[1]).toBe(true);
|
|
49
|
-
expect("calculatedItems" in listCalculated.state.calculatedObjects[1]).toBe(true);
|
|
50
|
-
expect("calculatedItem" in listCalculated.state.calculatedObjects[1]).toBe(true);
|
|
51
|
-
// expect uses enumeration, which uses handler.ownKeys and handler.getOwnPropertyDescriptor
|
|
52
|
-
expect(deepUnref(listCalculated.state.objects)).toEqual({
|
|
53
|
-
1: {
|
|
54
|
-
id: "1",
|
|
55
|
-
name: "main",
|
|
56
|
-
calculated_id: "4",
|
|
57
|
-
calculated_items: ["2", "3"],
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
expect(deepUnref(listCalculated.state.calculatedObjects)).toEqual({
|
|
61
|
-
1: {
|
|
62
|
-
calculatedItems: [
|
|
63
|
-
{
|
|
64
|
-
id: "2",
|
|
65
|
-
name: "calculated1",
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
id: "3",
|
|
69
|
-
name: "calculated2",
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
calculatedItem: {
|
|
73
|
-
id: "4",
|
|
74
|
-
name: "calculated3",
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
it("should allow calculated objects to return results based on related objects", async () => {
|
|
80
|
-
const mainListInstance = useListInstance({ props: { pkKey: "id" }, keepOldPages: false });
|
|
81
|
-
const relatedListInstance = useListInstance({ props: { pkKey: "id" }, keepOldPages: false });
|
|
82
|
-
mainListInstance.addListObject({
|
|
83
|
-
id: "1",
|
|
84
|
-
name: "main",
|
|
85
|
-
related_items: ["2", "3"],
|
|
86
|
-
related_id: "4",
|
|
87
|
-
calculated_items: ["2", "3"],
|
|
88
|
-
calculated_id: "4",
|
|
89
|
-
});
|
|
90
|
-
relatedListInstance.addListObject({
|
|
91
|
-
id: "2",
|
|
92
|
-
name: "related1",
|
|
93
|
-
});
|
|
94
|
-
relatedListInstance.addListObject({
|
|
95
|
-
id: "3",
|
|
96
|
-
name: "related2",
|
|
97
|
-
});
|
|
98
|
-
relatedListInstance.addListObject({
|
|
99
|
-
id: "4",
|
|
100
|
-
name: "related3",
|
|
101
|
-
});
|
|
102
|
-
const listRelated = useListRelated({
|
|
103
|
-
parentState: mainListInstance.state,
|
|
104
|
-
relatedObjectsRules: {
|
|
105
|
-
relatedItems: {
|
|
106
|
-
objects: relatedListInstance.state.objects,
|
|
107
|
-
pkKey: "related_items",
|
|
108
|
-
},
|
|
109
|
-
relatedItem: {
|
|
110
|
-
objects: relatedListInstance.state.objects,
|
|
111
|
-
pkKey: "related_id",
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
const listCalculated = useListCalculated({
|
|
116
|
-
parentState: listRelated.state,
|
|
117
|
-
calculatedObjectsRules: {
|
|
118
|
-
calculatedItems: (obj, relatedObj) => relatedObj.relatedItems?.map((x) => x.name + "-modified"),
|
|
119
|
-
calculatedItem: (obj, relatedObj) => relatedObj.relatedItem?.name + "-modified",
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
|
-
const anr = new AwaitNot({
|
|
123
|
-
obj: listCalculated.state,
|
|
124
|
-
prop: "running",
|
|
125
|
-
});
|
|
126
|
-
anr.start();
|
|
127
|
-
await anr.promise;
|
|
128
|
-
expect(deepUnref(listCalculated.state.calculatedObjects)).toEqual({
|
|
129
|
-
1: {
|
|
130
|
-
calculatedItems: ["related1-modified", "related2-modified"],
|
|
131
|
-
calculatedItem: "related3-modified",
|
|
132
|
-
},
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
});
|