map-transform 1.6.0-rc.7 → 1.6.0-rc.8

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.
Files changed (72) hide show
  1. package/NEXT.md +123 -0
  2. package/README.md +187 -52
  3. package/WRITING_PIPELINES.md +279 -106
  4. package/dist/legacy/createPathMapper.d.ts +4 -0
  5. package/dist/legacy/createPathMapper.js +21 -2
  6. package/dist/legacy/createPathMapper.js.map +1 -1
  7. package/dist/legacy/operations/lookup.js +2 -2
  8. package/dist/legacy/operations/lookup.js.map +1 -1
  9. package/dist/legacy/transformers/bucket.js +2 -1
  10. package/dist/legacy/transformers/bucket.js.map +1 -1
  11. package/dist/legacy/transformers/compare.js +3 -3
  12. package/dist/legacy/transformers/compare.js.map +1 -1
  13. package/dist/legacy/transformers/get.js +2 -2
  14. package/dist/legacy/transformers/get.js.map +1 -1
  15. package/dist/legacy/transformers/project.js +2 -2
  16. package/dist/legacy/transformers/project.js.map +1 -1
  17. package/dist/legacy/transformers/sort.js +2 -2
  18. package/dist/legacy/transformers/sort.js.map +1 -1
  19. package/dist/mapTransform.d.ts +1 -0
  20. package/dist/mapTransform.js +14 -22
  21. package/dist/mapTransform.js.map +1 -1
  22. package/dist/prep/alt.js +6 -0
  23. package/dist/prep/alt.js.map +1 -1
  24. package/dist/prep/apply.js +15 -3
  25. package/dist/prep/apply.js.map +1 -1
  26. package/dist/prep/array.js +6 -0
  27. package/dist/prep/array.js.map +1 -1
  28. package/dist/prep/filter.js +4 -1
  29. package/dist/prep/filter.js.map +1 -1
  30. package/dist/prep/index.d.ts +1 -1
  31. package/dist/prep/index.js +33 -12
  32. package/dist/prep/index.js.map +1 -1
  33. package/dist/prep/iterate.d.ts +1 -1
  34. package/dist/prep/iterate.js +2 -1
  35. package/dist/prep/iterate.js.map +1 -1
  36. package/dist/prep/mutation.js +17 -6
  37. package/dist/prep/mutation.js.map +1 -1
  38. package/dist/prep/path.js +3 -9
  39. package/dist/prep/path.js.map +1 -1
  40. package/dist/prep/transform.d.ts +1 -0
  41. package/dist/prep/transform.js +5 -4
  42. package/dist/prep/transform.js.map +1 -1
  43. package/dist/prepareOptions.d.ts +9 -0
  44. package/dist/prepareOptions.js +24 -0
  45. package/dist/prepareOptions.js.map +1 -0
  46. package/dist/run/alt.js +7 -5
  47. package/dist/run/alt.js.map +1 -1
  48. package/dist/run/index.d.ts +0 -5
  49. package/dist/run/index.js +33 -27
  50. package/dist/run/index.js.map +1 -1
  51. package/dist/run/iterate.js +2 -22
  52. package/dist/run/iterate.js.map +1 -1
  53. package/dist/run/mutation.d.ts +2 -1
  54. package/dist/run/mutation.js +2 -2
  55. package/dist/run/mutation.js.map +1 -1
  56. package/dist/run/path.d.ts +2 -1
  57. package/dist/run/path.js +11 -6
  58. package/dist/run/path.js.map +1 -1
  59. package/dist/run/resolveParentSets.d.ts +2 -0
  60. package/dist/run/resolveParentSets.js +46 -0
  61. package/dist/run/resolveParentSets.js.map +1 -0
  62. package/dist/run/transform.d.ts +3 -1
  63. package/dist/run/transform.js +9 -1
  64. package/dist/run/transform.js.map +1 -1
  65. package/dist/state.d.ts +2 -0
  66. package/dist/state.js +2 -0
  67. package/dist/state.js.map +1 -1
  68. package/dist/typesNext.d.ts +1 -1
  69. package/dist/utils/is.d.ts +1 -0
  70. package/dist/utils/is.js +1 -0
  71. package/dist/utils/is.js.map +1 -1
  72. package/package.json +2 -2
package/NEXT.md ADDED
@@ -0,0 +1,123 @@
1
+ # Proposals for MapTransform v2 (`next`)
2
+
3
+ A list of suggested changes to the `next` mutation language, to be taken on one
4
+ at a time. Each section is self-contained: what the problem is, what the change
5
+ is, and which verified findings it addresses. Findings marked _(verified)_ were
6
+ reproduced by running `mapTransform` from `src/mapTransform.ts` on small inputs.
7
+
8
+ ## Background: how the engine models context and reverse today
9
+
10
+ **Context is structural.** Only drilling down adds a level, operations are
11
+ opaque, set steps don't move, `^^` is depth zero of the current tree and `^^^`
12
+ the original input. In reverse, a target context mirrors the context, so parent
13
+ and root paths set on the parent or root target
14
+ (`src/run/resolveParentSets.ts`). See "Parent and root paths" in the README.
15
+
16
+ **Reverse is a syntactic reversal.** `adjustPipelineToDirection`
17
+ (`src/run/index.ts`) reverses the prepped steps. Pipelines whose first step is
18
+ not a path are silently prefixed with `.` or given a reverse plug
19
+ (`src/prep/mutation.ts`).
20
+
21
+ **`flip` is runtime state.** `isRev = xor(rev, flip)`. `$apply` clears it, `$if`
22
+ conditions force forward, `$array` forces a direction per branch, `$direction`
23
+ ignores it, and `lookup` special-cases it.
24
+
25
+ ## Reverse by rule, not by heuristic
26
+
27
+ ### Problem
28
+
29
+ - `$flip: false` is dropped at prep time, so a nested object cannot un-flip.
30
+ - `$direction` ignores `flip`, but paths honor it.
31
+ - Pipelines that do not start with a path are silently plugged or prefixed with
32
+ `.` in reverse (`addStepWhenNoGetStep` in `src/prep/mutation.ts`).
33
+
34
+ ### Change
35
+
36
+ - Add an explicit two-sided form for the hard cases, JSON-friendly:
37
+ `{ "$fwd": [...], "$rev": [...] }`. This replaces legacy `divide`, `fwd`, and
38
+ `rev`, and most uses of `$direction` on two adjacent steps.
39
+ - `$alt` in reverse: set with the first pipeline; if the value is a nonvalue,
40
+ use the last `$default`. Losing pipelines are never run as setters.
41
+ - `$flip` becomes a prep-time rewrite: swap key and value, reverse each
42
+ pipeline, toggle `>`. `flip` leaves `State`. Transformers that need to know,
43
+ such as `lookup`, get a flag on the transform step at prep time.
44
+
45
+ ## One modifier for "the other direction"
46
+
47
+ ### Problem
48
+
49
+ Direction pairs are spelled five ways: `$concat`/`$concatRev`,
50
+ `merge`/`mergeRev`, `$lookup`/`$lookdown`, `explode`/`implode`, and `$array`
51
+ with `$flip`.
52
+
53
+ ### Change
54
+
55
+ Allow `$flip: true` on any operation object, and drop `$concatRev`, `mergeRev`,
56
+ `$lookdown`, `implode`, and the special `$flip` handling on `$array`. Keep
57
+ `explode`/`implode` names only if they read better than `explode` + `$flip`.
58
+
59
+ ## Constants vs defaults
60
+
61
+ ### Problem
62
+
63
+ Two concepts have five spellings: `$value`, `$fixed`, `$value` with
64
+ `fixed: true`, and the `value` and `fixed` transformers. `$value` being
65
+ suppressed by `noDefaults` is surprising when it is used as a constant, which is
66
+ why `fixed` exists.
67
+
68
+ ### Change
69
+
70
+ - `$value: x` is a constant and is never suppressed.
71
+ - `$default: x` is a fallback and is suppressed by `noDefaults`.
72
+ - Drop `$fixed`, `fixed: true`, and the `fixed` transformer.
73
+
74
+ `$alt: ['fullname', { $default: 'Anon' }]` then reads as intended.
75
+
76
+ ## Reverse-only props without slashed keys
77
+
78
+ ### Problem
79
+
80
+ Reverse-only props use the lexical trick `name/1`, with `\/` escaping for
81
+ literal slashes.
82
+
83
+ ### Change
84
+
85
+ A `$rev: { name: [...] }` block on a mutation object holds props that only apply
86
+ in reverse, merged over the main props. `$fwd: { ... }` for symmetry. `name/1`
87
+ and its escaping go away.
88
+
89
+ ## Fail loudly at prep time
90
+
91
+ ### Problem
92
+
93
+ Bad input is accepted silently:
94
+
95
+ - Unknown `$direction` values, including typos, mean "both" _(verified)_.
96
+ - `[1:3]` and `[abc]` go through `parseInt` and become `[1]` and `[NaN]`
97
+ _(verified)_.
98
+ - Unknown `$`-keys on a mutation object, boolean values, `$alt: []`, non-array
99
+ `$nonvalues`, and unknown `compare` operators are dropped or ignored without a
100
+ message.
101
+ - Setting to parent or root degrades silently instead of failing.
102
+
103
+ ### Change
104
+
105
+ Throw at prep time on all of the above. Prep runs once, so this costs nothing at
106
+ run time.
107
+
108
+ ## Trim compatibility leftovers
109
+
110
+ ### Problem
111
+
112
+ Kept for compatibility but pure noise in v2: the `<` get prefix, the
113
+ `$undefined` alias of `$nonvalues`, `fwdAlias`/`revAlias`, `$value` accepting a
114
+ function, and `$if` using unprefixed `then`/`else` while everything else is
115
+ `$`-prefixed.
116
+
117
+ `$alwaysApply` is not inherited, so it must be repeated on every nested mutation
118
+ object.
119
+
120
+ ### Change
121
+
122
+ Drop the leftovers listed above. Make `$alwaysApply` inherited by nested
123
+ mutation objects.
package/README.md CHANGED
@@ -197,6 +197,12 @@ it won't happen again on the next call. `prepareOptions` is idempotent, so
197
197
  passing already prepared options to `mapTransform` -- or calling
198
198
  `prepareOptions` on them again -- costs nothing.
199
199
 
200
+ `map-transform/next` exports its own `prepareOptions` alongside `mapTransform`.
201
+ Options prepared with one API cannot be handed to the other. Note that the sync
202
+ `mapTransform()` and the async `mapTransformAsync()` cache their prepared
203
+ pipelines separately, so mixing both on the same prepared options will prepare
204
+ each pipeline twice.
205
+
200
206
  > [!NOTE] We are preparing for an upcoming 2.0 version, which will include
201
207
  > breaking changes.
202
208
  >
@@ -221,6 +227,27 @@ passing already prepared options to `mapTransform` -- or calling
221
227
  > new `mapTransformSync` and `mapTransformAsync`, but there might still be gaps
222
228
  > in the documentation here.
223
229
 
230
+ #### Deviations from v1 behaviour in `next`
231
+
232
+ The following behaviours of `mapTransformSync` and `mapTransformAsync` differ
233
+ from the default export, on purpose:
234
+
235
+ - The root form without a dot after a single caret, `^path`, is removed. Write
236
+ `^^.path`.
237
+ - `$alt` no longer changes the levels for parent paths after it. Before, a
238
+ `$alt` that found no value added a level, so the next step needed `^.^` to
239
+ reach the parent. After, the next step sees the same levels as before the
240
+ `$alt`, so `^` is enough.
241
+ - Parent and root paths in reverse set on the parent or root level of the target
242
+ instead of on the current level. Before, `section: '^.^.meta.section'` inside
243
+ an iteration reversed to `items[].section`, and a root path in reverse set
244
+ nothing. After, the same definition sets `meta.section` on the object holding
245
+ `items`. When the parent level does not exist, the value is dropped.
246
+ - Mutation objects iterate arrays by default, just like get paths map over
247
+ arrays. Before, you had to set `$iterate: true`, and without it the entire
248
+ array was passed to the mutation object, giving one object with an array of
249
+ values on every property. Set `$iterate: false` to get that behaviour back.
250
+
224
251
  ### The mutation object
225
252
 
226
253
  Think of a mutation object as a description of the object structure you want.
@@ -267,6 +294,10 @@ mutation object. If you don't, the entire array will be passed to the mutation
267
294
  object. This will in most cases have the (propably unwanted) effect of returning
268
295
  one object with an array of values on every property.
269
296
 
297
+ > [!NOTE] In the next version, mutation objects iterate arrays by default, so
298
+ > `$iterate: true` is not needed. Set `$iterate: false` to pass the entire array
299
+ > to the mutation object instead.
300
+
270
301
  ```javascript
271
302
  const def = {
272
303
  $iterate: true,
@@ -307,8 +338,9 @@ as its value, this mutation object will be iterated by default (no need to set
307
338
  the `$iterate` property). This does not happen to pipelines, paths, or
308
339
  operations.
309
340
 
310
- > [!NOTE] This automatic iteration will disappear in v2.0 and is also removed in
311
- > the new `mapTransformSync` and `mapTransformAsync` exports.
341
+ > [!NOTE] This changes slightly in the next version, as mutation objects iterate
342
+ > by default. A key with the `[]` suffix will still be iterated, but not because
343
+ > of that suffix.
312
344
 
313
345
  #### Values on the mutation object
314
346
 
@@ -395,6 +427,25 @@ This will essentially make MapTransform treat `null` the same way as
395
427
  You could in principle include any primitive value in `nonvalues` and it will be
396
428
  treated as `undefined`, e.g. an empty string or the number `0`.
397
429
 
430
+ You may also set `$nonvalues` on an operation or mutation object, to use another
431
+ set of non-values for that operation and any pipelines within it. This overrides
432
+ the `nonvalues` option for that part of the definition. `$undefined` is an alias
433
+ of `$nonvalues`, and when both are set, `$nonvalues` is used. As a definition
434
+ may be written in JSON, where `undefined` cannot be expressed, the value
435
+ `'**undefined**'` is treated as `undefined` in these lists:
436
+
437
+ ```javascript
438
+ const def = {
439
+ // Treat an empty string as `undefined` when picking a default here
440
+ name: [
441
+ {
442
+ $alt: ['data.name', { $value: 'Anonymous' }],
443
+ $nonvalues: ['**undefined**', ''],
444
+ },
445
+ ],
446
+ }
447
+ ```
448
+
398
449
  A mutation object will be skipped in its entirety when it encounters a non-value
399
450
  in the pipeline. This is not always wanted, e.g. when the mutation object has
400
451
  defaults that we want to set in the mutation object. In these cases, you may set
@@ -459,8 +510,11 @@ const def = {
459
510
 
460
511
  The `$modify: true` notation is actually an alias for `$modify: '.'`.
461
512
 
462
- This is the way to set it for reverse direction (this is the exact same as the
463
- example above, just reversed):
513
+ `$modify` works like a path segment that merges instead of replacing, and it
514
+ takes effect on the side of the prop that is being set. When it is in a key, it
515
+ modifies going forward. When it is in a value, it modifies in reverse. This is
516
+ the way to set it for reverse direction (this is the exact same as the example
517
+ above, just reversed):
464
518
 
465
519
  ```javascript
466
520
  const def = {
@@ -479,6 +533,18 @@ const def = {
479
533
  }
480
534
  ```
481
535
 
536
+ > [!NOTE] In the next version, you may put `$modify` on both sides of a prop to
537
+ > modify in both directions. `$modify: '$modify'` modifies the pipeline value
538
+ > both going forward and in reverse, and `$modify: 'response.$modify'` does the
539
+ > same with the object at `response`:
540
+ >
541
+ > ```javascript
542
+ > const def = {
543
+ > $modify: 'response.$modify',
544
+ > data: 'response.data.deeply.placed.items',
545
+ > }
546
+ > ```
547
+
482
548
  ### Transform pipelines
483
549
 
484
550
  The idea of the transform pipeline, or "pipeline" for short, is that you
@@ -544,6 +610,10 @@ specified. In the example above, we have set `$iterate: true` on the mutation
544
610
  object, to signal that we want the mutation to be applied to each item of any
545
611
  array. See also [the `iterate` operation](#iteratepipeline-operation) for more.
546
612
 
613
+ > [!NOTE] In the next version, mutation objects will iterate by default, so to
614
+ > get the behavior described as default for mutation objects above, you will
615
+ > have to set `$iterate: false`.
616
+
547
617
  > Editors note: We should think through how we use the word "pipeline", as it is
548
618
  > sometimes ment to refer to an array of operations that a value may be
549
619
  > transformed through, other times any operation that could have been a part of
@@ -654,41 +724,68 @@ In the example with the `content` path, you may access the `id` with the path
654
724
  much the same way as `../` in file paths on any computer. You may go up several
655
725
  levels with e.g. `^.^.^.prop` (not applicable to our example).
656
726
 
657
- In an iteration you need to remember that the array counts as one level, so if
658
- iterating the `tags[]` array from our example, you would have to use the path
659
- `^.^.id` to get to the id. You could also use `^.[0]` to get the first item in
660
- the array you're iterating.
661
-
662
- > Editors note: We should probably have more examples here, especially on what
663
- > happens in a pipeline where we go up and down.
664
-
665
- The root notation follows the same logic, but will always go to the base level
666
- of the data structure, regardless of how many levels down you have moved. Roots
667
- are specified with double carets, so the path `^^.id` will get the id from our
668
- data from anywhere in the data structure, be it in `content` or when iterating
669
- through `tags[]`.
670
-
671
- There is a gotcha here, for both parent and root paths, relating to what data
672
- you're moving up in, as you are mutating the data as you move "down". The short
673
- answer is that you're moving in the mutated data if you are mutating it. Say
674
- you have a pipeline where you first mutate the data on the level you're at with
675
- a mutation object. The following steps in the pipeline will relate to the
676
- mutated object, and if you move into the mutated data with a path, and then go
677
- up again with a parent path, you are moving up in the mutated data. But if you
678
- instead just move into the data without mutating it, moving up with a parent
679
- path will give you the original data – there's nothing else, as you have not
680
- mutated it.
681
-
682
- This is probably as expected, but the confusing part comes into play when there
683
- is some "distance" between mutating the data and referencing it with a root or
684
- parent path, especially the root. Say you first mutate the root level with a
685
- mutation object, then move on with other operations, and then at some point,
686
- further down in the data, you want to reference something at the root level in
687
- _the original data_. This is where the **original root** notation comes in.
688
-
689
- Use triple carets (`^^^`) to always reference the original, untransformed source
690
- data, regardless of any prior transformations in the pipeline. This is useful in
691
- multi-step pipelines where earlier steps may have transformed the root:
727
+ The number of carets you need follows from the structure of the definition
728
+ alone, by these rules:
729
+
730
+ 1. **Only drilling down adds a level.** A key segment like `content` adds one
731
+ level, and so does an index like `[0]`. Entering an item in an array adds one
732
+ level too, whether you get there by iterating a path with `[]`, by a mutation
733
+ object iterating an array, or by an `$iterate` operation. A bare `[]` that
734
+ only makes sure you have an array, adds nothing. So when iterating the
735
+ `tags[]` array from our example above, you would use `^.^.id` to get to the
736
+ id: one caret to the array and one more to the object holding it. You could
737
+ also use `^.[0]` to get the first item in the array you're iterating.
738
+ 2. **Operations are opaque.** After a `$transform`, a mutation object, `$alt`,
739
+ `$if`, `$filter`, `$apply`, or `$array`, the levels are what they were before
740
+ the operation, no matter what the operation did on the inside. Inside an
741
+ operation, you inherit the levels from where the operation is used.
742
+ 3. **Set paths don't move.** A `>prop` step does not add a level, so `^` after
743
+ it is the same as `^` before it.
744
+ 4. **`^^` is the top of the tree you're in, `^^^` is the original data.** The
745
+ root notation `^^.id` goes to the base level of the data structure,
746
+ regardless of how many levels down you have moved.
747
+ 5. **In reverse, parent and root paths set on the parent or root level.** See
748
+ [Setting on parent and root](#setting-on-parent-and-root) below.
749
+
750
+ The parents you move up in, are the data you moved down in. When you first
751
+ mutate the data with a mutation object and then move into the result with a
752
+ path, going up again with a parent path takes you up in the mutated data:
753
+
754
+ ```javascript
755
+ const def = [
756
+ { id: 'key', item: { title: 'content.heading' } },
757
+ { title: 'item.title', id: ['item.title', '^.^.id'] },
758
+ ]
759
+ // From { key: 'ent1', content: { heading: 'The heading' } }
760
+ // we get { title: 'The heading', id: 'ent1' }
761
+ ```
762
+
763
+ Here, `item.title` in the second mutation object moves two levels down into the
764
+ object from the first, and `^.^.id` goes back up to the mutated object and gets
765
+ the `id` we set there. Note that within a mutation object, all pipelines start
766
+ from the same object, so the pipeline for `id` is not affected by the pipeline
767
+ for `title`.
768
+
769
+ Rule 2 means you don't have to know what an operation did to get the levels
770
+ right after it. In this example, `$alt` may find the article on different
771
+ depths, but the mutation object after it sees the same levels either way:
772
+
773
+ ```javascript
774
+ const def = [
775
+ 'items[]',
776
+ {
777
+ $iterate: true,
778
+ article: [
779
+ { $alt: ['content', 'original.content'] },
780
+ { title: 'title', section: '^.^.meta.section' },
781
+ ],
782
+ },
783
+ ]
784
+ // From { meta: { section: 'news' }, items: [{ content: { title: 'A' } }] }
785
+ // we get [{ article: { title: 'A', section: 'news' } }]
786
+ ```
787
+
788
+ Rule 4 in a multi-step pipeline, where the first step mutates the root:
692
789
 
693
790
  ```javascript
694
791
  const def = [
@@ -703,22 +800,43 @@ const def = [
703
800
  ]
704
801
  ```
705
802
 
706
- This is especially useful when you write a named pipeline and reference it with
707
- an `$apply` operation, as you have no knowledge in the named pipeline about any
708
- mutation of the root outside it. Using `^^^` guarantees access to the original
709
- source data in all cases.
803
+ The same holds inside a named pipeline applied with `$apply`: `^^` is the top of
804
+ the tree the pipeline is applied in, mutated or not, and `^^^` is the original
805
+ source data.
710
806
 
711
- Note also, that if you are within a mutation object and move down into the data,
712
- the data above where you are isn't transformed yet. As long as you are within a
713
- mutation object, you're referencing the data as it was before entering that
714
- mutation object. But as soon as you move to the next step in the pipeline –
715
- after the mutation object, you are left with the results of that mutation
716
- object.
807
+ ##### Setting on parent and root
717
808
 
718
- > Editor's note: We need examples.
809
+ When you go in reverse, a parent or root path becomes a set path, and it sets on
810
+ the parent or root level of the target, with the same number of carets as going
811
+ forward. In this example, `section` is read from two levels up going forward,
812
+ and in reverse it is set two levels up: on the object holding `items`.
719
813
 
720
- > [!NOTE] Setting on parent and root paths is currently not supported, but may
721
- > be in the future.
814
+ ```javascript
815
+ const def = [
816
+ 'items[]',
817
+ { $iterate: true, id: 'key', section: '^.^.meta.section' },
818
+ ]
819
+ // Forward, from { meta: { section: 'news' }, items: [{ key: 'ent1' }] }
820
+ // we get [{ id: 'ent1', section: 'news' }]
821
+ // In reverse, from [{ id: 'ent1', section: 'news' }]
822
+ // we get { meta: { section: 'news' }, items: [{ key: 'ent1' }] }
823
+ ```
824
+
825
+ A root path sets on the root level of the target in the same way, so
826
+ `'^^.meta.section'` in the example above would give the same result in reverse.
827
+ When you set on a parent level, nothing is set on the current level, so `id` is
828
+ the only prop on the items here.
829
+
830
+ Set paths may also use parent and root notation going forward, with a `>` prefix
831
+ or as a key on a mutation object. `{ '^.^.meta.section': 'section' }` sets
832
+ `meta.section` two levels up in the target.
833
+
834
+ When there is no parent level to set on, e.g. when a mutation object with
835
+ `section: '^.section'` is run in reverse at the top level, the value is dropped.
836
+
837
+ A parent path _within_ a path is different from these cases. The path
838
+ `item.^.count` moves down into `item` and up again, and is the same as `count`.
839
+ In reverse, it sets `count`, not `item.count`.
722
840
 
723
841
  #### Setting on a path
724
842
 
@@ -927,6 +1045,12 @@ would be a truly pure function.
927
1045
  > call the outer function yourself with any relevant props. This option will be
928
1046
  > removed in v2.0, but is still available to the regular MapTransform function.
929
1047
 
1048
+ Transformers may be asynchronous, but only when you run the transformation with
1049
+ `mapTransformAsync`. When you run it with `mapTransformSync` and a transformer
1050
+ returns a promise, MapTransform will throw, telling you the id of the offending
1051
+ transformer. This also applies to transformers used by other operations, like
1052
+ `filter`.
1053
+
930
1054
  #### `filter` operation
931
1055
 
932
1056
  The `filter` operation will use a transformer function or a pipeline to decide
@@ -1087,6 +1211,9 @@ const def = [
1087
1211
  For mutation objects, you may set `$iterate: true` to apply the mutation to each
1088
1212
  item in an array.
1089
1213
 
1214
+ > [!NOTE] In the next version, mutation objects do this by default, and
1215
+ > `$iterate: false` turns it off.
1216
+
1090
1217
  When you need to iterate a pipeline or an operation that is not a mutation
1091
1218
  object or an operation that supports the `$iterate` flag direction, you may wrap
1092
1219
  it in an `$iterate` operation object like this:
@@ -1238,6 +1365,10 @@ don't think too much about it. See
1238
1365
  [the `get` and `set` operations](#getpath-and-setpath-operation) for more on how
1239
1366
  `get` works in reverse.
1240
1367
 
1368
+ When the value is `undefined` in reverse, the alternative pipelines are used to
1369
+ look for a default value. Only pipelines without set paths (e.g. a `$value`
1370
+ pipeline) are used for this, so put the default in its own pipeline.
1371
+
1241
1372
  To apply the `alt` operation to each item in an array, set `$iterate: true` on
1242
1373
  the operation object. You may also set `$direction: 'fwd'` or
1243
1374
  `$direction: 'rev'` to limit it to one direction only.
@@ -1829,6 +1960,10 @@ except that the value set with `fixed` will be included even when
1829
1960
  `state.noDefaults` is `true`. Use `value` for default values, and `fixed` for
1830
1961
  values that should be set no matter what.
1831
1962
 
1963
+ Like the `value` transformer, `fixed` has its own short-hand operation object
1964
+ notation, so `{ $transform: 'fixed', value: 'customer' }` may be written
1965
+ `{ $fixed: 'customer' }`.
1966
+
1832
1967
  #### `flatten` transformer
1833
1968
 
1834
1969
  Will flatten an array in the pipeline. The default is to flatten one layer deep,