@lotics/app-sdk 0.87.3 → 0.87.4
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/docs/mutations.md +5 -2
- package/docs/workflows.md +20 -13
- package/package.json +1 -1
package/docs/mutations.md
CHANGED
|
@@ -321,7 +321,8 @@ await update_records({
|
|
|
321
321
|
|
|
322
322
|
`set` still writes every key it carries — `null` in `set` **clears** the field; `null`/absent in
|
|
323
323
|
`set_skip_null` **skips** it. The full write surface (`set`, `set_skip_null`, the surgical
|
|
324
|
-
`add_to`/`remove_from`/`replace` ops, `field_edits`, and the exact value shape per
|
|
324
|
+
`add_to`/`remove_from`/`replace` ops, `increment`, `field_edits`, and the exact value shape per
|
|
325
|
+
field type)
|
|
325
326
|
is [workflows](./workflows.md#writing-records).
|
|
326
327
|
|
|
327
328
|
## Refetch after a mutation
|
|
@@ -446,7 +447,9 @@ Why a full-form snapshot save is a bug, not a style choice — three independent
|
|
|
446
447
|
append is the system's rather than a person's — an upload settling, a workflow attaching a
|
|
447
448
|
generated document — name the ITEMS with `add_to` / `remove_from`
|
|
448
449
|
([workflows](./workflows.md#writing-records)) and the write path resolves them against the
|
|
449
|
-
record as it stands.
|
|
450
|
+
record as it stands. A running total is the scalar form of the same defect: two writers both
|
|
451
|
+
read 100, both subtract 10, both write 90, and one sale is gone with no error anywhere. Name
|
|
452
|
+
the DELTA with `increment`.
|
|
450
453
|
|
|
451
454
|
```tsx
|
|
452
455
|
// load: snapshot the editable fields from the row
|
package/docs/workflows.md
CHANGED
|
@@ -482,31 +482,38 @@ differ from `<` / `>` (code-unit order) and from the database's collation.
|
|
|
482
482
|
|
|
483
483
|
## Writing records
|
|
484
484
|
|
|
485
|
-
`update_records` carries
|
|
485
|
+
`update_records` carries five composable surfaces. A field may appear in **at most one** of them.
|
|
486
486
|
|
|
487
487
|
| Surface | Shape | Effect |
|
|
488
488
|
|---|---|---|
|
|
489
489
|
| `set` | `{ fld_x: value }` | write the whole value. `null` **clears** the field |
|
|
490
490
|
| `set_skip_null` | `{ fld_x: value }` | same shape, but `null`/`undefined` entries are **dropped** — absent means "leave unchanged" |
|
|
491
491
|
| `add_to` / `remove_from` / `replace` | `{ fld_x: [items] }` | surgical edits on multi-value fields (files, multi select, multi member, record links) |
|
|
492
|
-
| `
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
492
|
+
| `increment` | `{ fld_x: delta }` | move a **number** field by a signed amount. Negative decrements; there is no separate decrement op |
|
|
493
|
+
| `field_edits` | `[{ field, op, value }]` | the multi-value ops with the field named by a **string expression** — the only way to target a field chosen at run time. `increment` has no value-form: its payload is a scalar, not an item list |
|
|
494
|
+
|
|
495
|
+
`add_to`, `remove_from` and `increment` are RELATIVE: the server resolves them against the record
|
|
496
|
+
as it stands when the write lands, inside the lock it already takes. Two runs changing one field at
|
|
497
|
+
the same time therefore each keep their effect — which reading the field and writing the result back
|
|
498
|
+
through `set` does not, since both fold onto the value they read and the later write drops the
|
|
499
|
+
earlier, both reporting success. On a stock count that is a sale that vanishes. Parallel runs are
|
|
500
|
+
ordinary (a trigger firing twice, an agent emitting two calls in one step), so reach for the ops
|
|
501
|
+
rather than a read-modify-write whenever the workflow is CHANGING a field by an amount rather than
|
|
502
|
+
stating its value.
|
|
503
|
+
|
|
504
|
+
`increment` counts an empty or unset field as 0, so a first decrement leaves a negative — oversold,
|
|
505
|
+
and visibly so. It is rejected on formula, rollup, lookup and autonumber fields: those come from
|
|
506
|
+
their own definition, so change what they aggregate instead.
|
|
501
507
|
|
|
502
508
|
Inside `set` and `create_records.records`: `null` clears (persisted), `undefined` or an omitted
|
|
503
509
|
key preserves. So passing a possibly-null read straight through is safe. Use
|
|
504
510
|
`coalesce(x, fallback)` only when you want a real fallback, never to "strip" null.
|
|
505
511
|
|
|
506
512
|
`set_skip_null` is what turns a bag of optional workflow inputs into a diff-write without a guard
|
|
507
|
-
per field; naming the same field in both `set` and `set_skip_null` is an error
|
|
508
|
-
all-dropped `set_skip_null
|
|
509
|
-
`before_update` hooks
|
|
513
|
+
per field; naming the same field in both `set` and `set_skip_null` is an error. A call whose
|
|
514
|
+
surfaces all resolve to nothing — an all-dropped `set_skip_null`, an op object with no entries —
|
|
515
|
+
is a no-op: no records touched, no `before_update` hooks. So a conditionally-built op object needs
|
|
516
|
+
no guard around the call. Why diffs and not snapshots, plus locked records and the
|
|
510
517
|
`request_locked_record_change` path: [mutations](./mutations.md#diff-before-update--send-only-what-changed).
|
|
511
518
|
|
|
512
519
|
**A `null` optional input is a CLEAR, and `set_skip_null` drops it.** The caller has three states
|