@homebound/form-state 2.5.2 → 2.6.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/dist/formState.js +15 -3
- package/dist/formState.test.js +75 -0
- package/dist/formStateDomain.d.ts +1 -0
- package/package.json +1 -1
package/dist/formState.js
CHANGED
|
@@ -431,10 +431,22 @@ function newListFieldState(parentInstance, parentState, key, rules, listConfig,
|
|
|
431
431
|
},
|
|
432
432
|
get changedValue() {
|
|
433
433
|
const result = [];
|
|
434
|
-
const
|
|
434
|
+
const hasOpKey = Object.keys(listConfig.config).includes("op");
|
|
435
|
+
const hasLegacyOpKey = Object.keys(listConfig.config).some((key) => key === "delete" || key === "remove");
|
|
436
|
+
const incremental = listConfig.update === "incremental" ||
|
|
437
|
+
// Implicitly enable incremental mode if we see an op key
|
|
438
|
+
(listConfig.update === undefined && (hasOpKey || hasLegacyOpKey));
|
|
439
|
+
const exhaustive = !incremental;
|
|
435
440
|
this.rows.forEach((r) => {
|
|
436
|
-
|
|
437
|
-
|
|
441
|
+
var _a;
|
|
442
|
+
var _b;
|
|
443
|
+
if (exhaustive || r.dirty || r.isNewEntity) {
|
|
444
|
+
const changed = r.changedValue;
|
|
445
|
+
// Ensure we have an `op: include` key, following https://joist-orm.io/docs/features/partial-update-apis
|
|
446
|
+
if (incremental && hasOpKey) {
|
|
447
|
+
(_a = (_b = changed).op) !== null && _a !== void 0 ? _a : (_b.op = "include");
|
|
448
|
+
}
|
|
449
|
+
result.push(changed);
|
|
438
450
|
}
|
|
439
451
|
});
|
|
440
452
|
return result;
|
package/dist/formState.test.js
CHANGED
|
@@ -979,6 +979,81 @@ describe("formState", () => {
|
|
|
979
979
|
books: [{ id: "b:1", title: "t1b" }],
|
|
980
980
|
});
|
|
981
981
|
});
|
|
982
|
+
it("uses the op key as a hint to use incremental list behavior", () => {
|
|
983
|
+
// Given an author
|
|
984
|
+
const formState = formState_1.createObjectState({
|
|
985
|
+
id: { type: "value" },
|
|
986
|
+
// And the books collection is not explicitly marked as incremental
|
|
987
|
+
books: {
|
|
988
|
+
type: "list",
|
|
989
|
+
config: {
|
|
990
|
+
id: { type: "value" },
|
|
991
|
+
title: { type: "value", rules: [formState_1.required] },
|
|
992
|
+
// But it does have an op key
|
|
993
|
+
op: { type: "value" },
|
|
994
|
+
},
|
|
995
|
+
},
|
|
996
|
+
}, {
|
|
997
|
+
id: "a:1",
|
|
998
|
+
firstName: "f",
|
|
999
|
+
books: [
|
|
1000
|
+
// And the books start out as included
|
|
1001
|
+
{ id: "b:1", title: "t1", op: "include" },
|
|
1002
|
+
{ id: "b:2", title: "t2", op: "include" },
|
|
1003
|
+
],
|
|
1004
|
+
});
|
|
1005
|
+
// And initially nothing is changed
|
|
1006
|
+
expect(formState.changedValue).toEqual({ id: "a:1" });
|
|
1007
|
+
// When we delete the 1st book
|
|
1008
|
+
formState.books.rows[0].op.value = "delete";
|
|
1009
|
+
// Then only the 1st book is included
|
|
1010
|
+
expect(formState.changedValue).toEqual({
|
|
1011
|
+
id: "a:1",
|
|
1012
|
+
books: [{ id: "b:1", op: "delete" }],
|
|
1013
|
+
});
|
|
1014
|
+
});
|
|
1015
|
+
it("defaults the incremental op key to included when not set", () => {
|
|
1016
|
+
// Given an author
|
|
1017
|
+
const formState = formState_1.createObjectState({
|
|
1018
|
+
id: { type: "value" },
|
|
1019
|
+
// And the books collection is not explicitly marked as incremental
|
|
1020
|
+
books: {
|
|
1021
|
+
type: "list",
|
|
1022
|
+
config: {
|
|
1023
|
+
id: { type: "value" },
|
|
1024
|
+
title: { type: "value", rules: [formState_1.required] },
|
|
1025
|
+
// But it does have an op key
|
|
1026
|
+
op: { type: "value" },
|
|
1027
|
+
},
|
|
1028
|
+
},
|
|
1029
|
+
}, {
|
|
1030
|
+
id: "a:1",
|
|
1031
|
+
firstName: "f",
|
|
1032
|
+
books: [
|
|
1033
|
+
// And no op keys are initially set
|
|
1034
|
+
{ id: "b:1", title: "t1" },
|
|
1035
|
+
{ id: "b:2", title: "t2" },
|
|
1036
|
+
],
|
|
1037
|
+
});
|
|
1038
|
+
// And initially nothing is changed
|
|
1039
|
+
expect(formState.changedValue).toEqual({ id: "a:1" });
|
|
1040
|
+
// When we delete the 1st book
|
|
1041
|
+
formState.books.rows[0].op.value = "delete";
|
|
1042
|
+
// And add a 3rd book
|
|
1043
|
+
formState.books.add({ title: "t3" });
|
|
1044
|
+
// Then the 3rd book doesn't have an explicit op yet
|
|
1045
|
+
expect(formState.books.rows[2].op.value).toBeUndefined();
|
|
1046
|
+
// But when we create changedValue
|
|
1047
|
+
expect(formState.changedValue).toEqual({
|
|
1048
|
+
id: "a:1",
|
|
1049
|
+
books: [
|
|
1050
|
+
// Then the deleted book is included
|
|
1051
|
+
{ id: "b:1", op: "delete" },
|
|
1052
|
+
// And the 3rd book is included w/the `op: include` flag added
|
|
1053
|
+
{ title: "t3", op: "include" },
|
|
1054
|
+
],
|
|
1055
|
+
});
|
|
1056
|
+
});
|
|
982
1057
|
it("can observe value changes", () => {
|
|
983
1058
|
const formState = formState_1.createObjectState(authorWithBooksConfig, { firstName: "f" });
|
|
984
1059
|
let ticks = 0;
|