@lynstack/recipe 1.8.0 → 1.9.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/CHANGELOG.md CHANGED
@@ -4,186 +4,157 @@ All notable changes to `@lynstack/recipe`. Each version is published on
4
4
  npm and as a [GitHub release](https://github.com/lynstack/recipe/releases)
5
5
  tagged `recipe@<version>`.
6
6
 
7
+ ## 1.9.0 — 2026-10-09
8
+
9
+ ### Added
10
+
11
+ - `InheritedSlot` and `InheritedDefaultedName`: the slots and the
12
+ defaulted variants that a recipe inherits from the recipes it composes,
13
+ for libraries that wrap composable recipes.
14
+ - `UnknownSlot`, the type that errors show for a slot a recipe does not
15
+ declare.
16
+
17
+ ## 1.8.1 — 2026-10-09
18
+
19
+ ### Fixed
20
+
21
+ - Editors complete the variant names in `defaultVariants`, and the slot
22
+ names in the options of a slot recipe.
23
+ - Editors, errors, and declarations show the values a variant accepts by
24
+ name, such as `"sm" | "md"`, instead of `VariantOption<…>`.
25
+ - A slot that an option names without declaring it is reported as
26
+ `UnknownSlot<"lable", "label" | "root">`, not as "not assignable to type
27
+ 'never'" on every slot of the option.
28
+
7
29
  ## 1.8.0 — 2026-10-08
8
30
 
9
- A recipe warns about the names its config gives without declaring them,
10
- which TypeScript lets through in a config declared before the call, and
11
- a library's function generic over the slot recipe it composes can name
12
- its own slots.
13
-
14
- - A slot recipe's config types the slots of the slot recipes it composes
15
- apart from its own, so that a function generic over the slot recipe it
16
- composes can name its own slots, and declarations print the slots of
17
- `base` and of compound variants by name. Making library recipes
18
- composable advises the same for a library's types.
19
- - Creating a recipe or a slot recipe warns, once, with `console.warn`,
20
- about a default or a compound variant that names a variant or an option
21
- that no config of the recipe declares, and, in a slot recipe, about a
22
- value for a slot that no config lists in `slots`. The recipe ignores
23
- such names, as before; TypeScript does not report every one in a config
24
- declared before the call, as `isolatedDeclarations` requires.
31
+ ### Added
32
+
33
+ - Creating a recipe warns once, with `console.warn`, about a default, a
34
+ compound variant, or a slot that names something no config declares,
35
+ which TypeScript misses in a config declared before the call.
36
+
37
+ ### Fixed
38
+
39
+ - A function generic over the slot recipe it composes can name its own
40
+ slots, and declarations print the slots of `base` and of compound
41
+ variants by name.
25
42
 
26
43
  ## 1.7.0 — 2026-10-08
27
44
 
28
- A library can type its own functions and exported recipes: a function
29
- generic over a config returns the recipe of its config, an exported
30
- recipe has a type to annotate it with for `isolatedDeclarations`, and
31
- the declarations of composed slot recipes stay small.
32
-
33
- - `KindRecipeOf<Value, Result, Config, Composed>` and `KindSlotRecipeOf`
34
- are the types of the recipe and the slot recipe of a config declared
35
- `as const`, which annotate an exported recipe where
36
- `isolatedDeclarations` cannot infer the type of a call. A recipe that
37
- composes others lists their types as the last parameter.
38
- - `KindSelection` is exported: a function generic over a config, such as
39
- a library's own helper, returns
40
- `KindRecipe<KindSelection<Variants, DefaultedName>, Result>`. Since
41
- 1.3.0, the type of a recipe could not be assigned to such a type while
42
- the names of its defaults were a type parameter.
43
- - The declaration of a slot recipe that composes others lists the names
44
- of its slots, instead of the types of the slot recipes it composes, so
45
- that it grows linearly with the level of composition. Before, it grew
46
- about 2.4 times with each level.
45
+ ### Added
46
+
47
+ - `KindRecipeOf` and `KindSlotRecipeOf`, the types of the recipe of a
48
+ config declared `as const`, to annotate exported recipes under
49
+ `isolatedDeclarations`.
50
+ - `KindSelection`, so that a function generic over a config can return
51
+ `KindRecipe<KindSelection<Variants, DefaultedName>, Result>`.
52
+
53
+ ### Fixed
54
+
55
+ - A function generic over a config can return its recipe again, which
56
+ failed since 1.3.0 while the names of its defaults were generic.
57
+ - The declaration of a composed slot recipe grows linearly with each level
58
+ of composition, not about 2.4 times.
47
59
 
48
60
  ## 1.6.0 — 2026-10-07
49
61
 
50
- A config with the wrong shape fails with a message that names what is
51
- wrong, and a library that wraps slot recipes can reject unknown slots.
52
-
53
- - Creating a recipe or a slot recipe checks the shape of its config,
54
- which the types already check, so that a config from untyped code
55
- throws a `TypeError` that names the part to fix: no `variants`, a
56
- variant whose options are not an object, a `compoundVariants` that is
57
- not an array, or a compound variant without `variants`. In a slot
58
- recipe, it also checks that `slots` is an array and that `base`, each
59
- option, and the `value` of each compound variant are an object of the
60
- value of each slot. Before, such a config threw an unrelated error, or a
61
- compound variant without `variants` matched every selection. The check
62
- runs once, when the recipe is created.
63
- - `NoUnknownSlots` is exported: a library intersects the variants of its
64
- slot recipes' configs with it, as the engine's own config does, so that
65
- a value for a slot that `slots` does not name is a type error.
62
+ ### Added
63
+
64
+ - Creating a recipe checks the shape of its config and throws a
65
+ `TypeError` that names the part to fix, such as a missing `variants` or
66
+ a compound variant without `variants`.
67
+ - `NoUnknownSlots`, so that a library's slot recipe configs reject a slot
68
+ that `slots` does not name.
69
+
70
+ ### Fixed
71
+
72
+ - A compound variant without `variants` no longer matches every
73
+ selection; it throws.
66
74
 
67
75
  ## 1.5.0 — 2026-10-07
68
76
 
69
- A recipe lists the options and defaults of its variants, so that a
70
- library can list every selection of a recipe, as a story or a table of
71
- every option does, without reading its config.
72
-
73
- - Every recipe and slot recipe has `variantOptions`, the names of the
74
- options of each variant, as strings, in the order the recipe numbers
75
- them: integer names first, in ascending order, then `"false"` and
76
- `"true"`, which a variant that declares either one has, then the others
77
- in the order of the config.
78
- - Every recipe and slot recipe has `defaultVariants`, the option each
79
- variant uses when a selection leaves it out, as a string: its default,
80
- or `"false"` for a variant whose only options are `"true"` and
81
- `"false"`. A variant without a default is not in it.
82
- - Both are frozen, keyed in the order of `variantKeys`, and typed with
83
- the names of the options of each variant. A recipe that composes others
84
- lists the variants, options, and defaults of the one config it stands
85
- for.
86
- - `KindRecipe` has the two properties, so a type that implements it by
77
+ ### Added
78
+
79
+ - `variantOptions` and `defaultVariants` on every recipe: the options of
80
+ each variant and the default each uses, as frozen, typed lists of names.
81
+
82
+ ### Changed
83
+
84
+ - `KindRecipe` has these two properties, so a type that implements it by
87
85
  hand needs them too.
88
86
 
89
87
  ## 1.4.0 — 2026-10-07
90
88
 
91
- A recipe kind can combine two values into one, so that a recipe that
92
- composes others builds its results as fast as the one config it stands
93
- for.
94
-
95
- - `RecipeKind` takes `combine(first, second)`, optional, which returns
96
- one value that adds what `first` then `second` add. A recipe that
97
- composes others calls it when it is created, never on a call, to
98
- combine its bases and the values that several configs give one option.
99
- A slot recipe combines the values of each slot in the same way.
100
- - A kind with `combine` must not change `first` or `second`, and follows
101
- two rules, in which two accumulators must give the same results from
102
- `finish`, now and after the same values are reduced into each: reducing
103
- `first` then `second` gives what reducing `combine(first, second)`
104
- gives, and `initial(base)` gives what reducing `base` into
105
- `initial(undefined)` gives.
106
- - Without `combine`, a composed recipe returns what it returned before.
107
- When no option or compound variant has values from several configs, it
108
- now compiles as one config too, and builds its results as fast.
109
- - 1.3.0 said that a composed recipe is as fast as its one config. That
110
- holds for cached calls; a result built without the cache cost more when
111
- several configs gave values to one option or had a base. With
112
- `combine`, it costs what the one config costs.
89
+ ### Added
90
+
91
+ - `combine(first, second)` on a recipe kind, optional: a recipe that
92
+ composes others merges the values of its configs into one when it is
93
+ created, so that it builds its results as fast as one config.
94
+ `combine` must not change its arguments, and must give what reducing
95
+ `first` then `second` gives.
96
+
97
+ ### Changed
98
+
99
+ - A composed recipe without overlapping values compiles as one config,
100
+ with or without `combine`.
113
101
 
114
102
  ## 1.3.0 — 2026-10-07
115
103
 
116
- A recipe can build on other recipes with `composes`.
117
-
118
- - A recipe and a slot recipe take `composes`, a list of recipes whose
119
- configs they add to their own, as if written in one config: their bases
120
- first, every variant and option of each, with the values of an option in
121
- the order of the recipes, their compound variants first, and the last
122
- default given for each variant. A slot recipe has the slots of the slot
123
- recipes it composes, theirs first. A recipe composed several times
124
- counts once.
125
- - A recipe composes recipes of any kind whose values have the type of its
126
- own. Composing anything else, or a slot recipe in a recipe, is a type
127
- error and throws a `TypeError` when the recipe is created.
128
- - The configs are merged when the recipe is created: a composed recipe is
129
- as fast as the one config it stands for.
130
- - A recipe's type carries what it passes on to the recipes that compose
131
- it, under a `~composition` property that exists in the type only.
132
- `KindRecipe` takes it as a third, optional type parameter.
133
- - New types for libraries built on the engine: `RecipeComposition`,
104
+ ### Added
105
+
106
+ - `composes`: a recipe or slot recipe builds on other recipes of any kind
107
+ whose values have its type, as if their configs and its own were one.
108
+ - Types for libraries built on the engine: `RecipeComposition`,
134
109
  `Composable`, `ComposableKindRecipe`, `ComposableKindSlotRecipe`,
135
110
  `ComposedVariants`, `ComposedDefaultedName`, and `ComposedSlot`.
136
111
 
112
+ ### Changed
113
+
114
+ - `KindRecipe` takes an optional third type parameter, what the recipe
115
+ passes on to the recipes that compose it.
116
+
137
117
  ## 1.2.0 — 2026-10-06
138
118
 
139
- - A recipe and a slot recipe take `cache` in their config, which
140
- overrides the `cache` of their kind. A recipe whose variants come from
141
- untrusted input, such as the requests of a server, can turn its cache
142
- off while the other recipes of its kind keep theirs, since a cache keeps
143
- up to one result for each combination of declared options.
144
- - A slot recipe keeps a slot named `__proto__` in its result. It set the
145
- prototype of the result before, and the slot was missing.
146
- - The README states the requirements: TypeScript 5.4 or newer for the
147
- types, and an ES2022 runtime.
119
+ ### Added
120
+
121
+ - `cache` in a recipe's config, which overrides the kind's, to turn off
122
+ the cache of a recipe whose variants come from untrusted input.
123
+
124
+ ### Fixed
125
+
126
+ - A slot recipe keeps a slot named `__proto__` in its result.
148
127
 
149
128
  ## 1.1.2 — 2026-10-05
150
129
 
151
- The public API and behavior are unchanged.
130
+ ### Fixed
152
131
 
153
- - `package.json` declares `main` as well as `exports`, for bundlers that
154
- read only `main`, such as the one of Expo Snack.
132
+ - `package.json` declares `main`, for bundlers that ignore `exports`, such
133
+ as the one of Expo Snack.
155
134
 
156
135
  ## 1.1.1 — 2026-10-05
157
136
 
158
- - A recipe whose kind returns `undefined` caches that result, as it
159
- caches any other, instead of building it again on every call.
137
+ ### Fixed
138
+
139
+ - A recipe whose kind returns `undefined` caches that result.
160
140
 
161
141
  ## 1.1.0 — 2026-10-05
162
142
 
163
- `@lynstack/recipe` now creates slot recipes, which map a selection of
164
- variants to the result of each of several slots, such as the class names
165
- or the styles of the elements of a component.
166
-
167
- - `createSlotRecipeKind` takes the same kind as `createRecipeKind` and
168
- returns the function that creates slot recipes of that kind. Each slot
169
- reduces its own values, and the result is a frozen object of each
170
- slot's result, cached for each declared selection.
171
- - New types for slot recipes: `CreateKindSlotRecipe`,
172
- `KindSlotRecipeConfig`, `KindSlotVariants`, `KindSlotCompoundVariant`,
173
- and `SlotValues`.
174
- - `VariantsOf` returns the variants a recipe accepts, to type the props of
175
- a component built on it, and `VariantKey` names the variants of a
176
- selection.
143
+ ### Added
144
+
145
+ - `createSlotRecipeKind`, which creates slot recipes: a selection maps to
146
+ the result of each of several slots.
147
+ - Types for slot recipes: `CreateKindSlotRecipe`, `KindSlotRecipeConfig`,
148
+ `KindSlotVariants`, `KindSlotCompoundVariant`, and `SlotValues`.
149
+ - `VariantsOf`, the variants a recipe accepts, and `VariantKey`.
177
150
 
178
151
  ## 1.0.0 — 2026-10-04
179
152
 
180
- The first release of `@lynstack/recipe`, which creates recipes for values
181
- of any type.
153
+ First release.
154
+
155
+ ### Added
182
156
 
183
- - `createRecipeKind` defines a kind of recipe by how it reduces values,
184
- such as class names or style objects, and returns the function that
185
- creates recipes of that kind.
186
- - Recipes support variants, compound variants, default variants, and
187
- boolean variants, list their variants in `variantKeys`, and cache the
188
- result of each declared selection.
189
- - No dependencies; ES modules only.
157
+ - `createRecipeKind`, which defines a kind of recipe by how it reduces
158
+ values, such as class names or style objects.
159
+ - Variants, compound variants, default variants, boolean variants,
160
+ `variantKeys`, and a cache for each declared selection.