@modular-component/core 0.1.3 → 0.1.5

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 (67) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/index.d.ts +304 -91
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +107 -53
  5. package/dist/index.js.map +1 -1
  6. package/dist/types/arguments.d.ts +33 -0
  7. package/dist/types/arguments.d.ts.map +1 -0
  8. package/dist/types/arguments.js +6 -0
  9. package/dist/types/arguments.js.map +1 -0
  10. package/dist/types/methods/add.d.ts +23 -0
  11. package/dist/types/methods/add.d.ts.map +1 -0
  12. package/dist/types/methods/add.js +8 -0
  13. package/dist/types/methods/add.js.map +1 -0
  14. package/dist/types/methods/at.d.ts +22 -0
  15. package/dist/types/methods/at.d.ts.map +1 -0
  16. package/dist/types/methods/at.js +7 -0
  17. package/dist/types/methods/at.js.map +1 -0
  18. package/dist/types/methods/hook.d.ts +14 -0
  19. package/dist/types/methods/hook.d.ts.map +1 -0
  20. package/dist/types/methods/hook.js +7 -0
  21. package/dist/types/methods/hook.js.map +1 -0
  22. package/dist/types/methods/mock.d.ts +26 -0
  23. package/dist/types/methods/mock.d.ts.map +1 -0
  24. package/dist/types/methods/mock.js +6 -0
  25. package/dist/types/methods/mock.js.map +1 -0
  26. package/dist/types/methods/with.d.ts +44 -0
  27. package/dist/types/methods/with.d.ts.map +1 -0
  28. package/dist/types/methods/with.js +8 -0
  29. package/dist/types/methods/with.js.map +1 -0
  30. package/dist/types/methods.d.ts +10 -0
  31. package/dist/types/methods.d.ts.map +1 -0
  32. package/dist/types/methods.js +5 -0
  33. package/dist/types/methods.js.map +1 -0
  34. package/dist/types/modular-component.d.ts +15 -0
  35. package/dist/types/modular-component.d.ts.map +1 -0
  36. package/dist/types/modular-component.js +5 -0
  37. package/dist/types/modular-component.js.map +1 -0
  38. package/dist/types/stage.d.ts +41 -0
  39. package/dist/types/stage.d.ts.map +1 -0
  40. package/dist/types/stage.js +5 -0
  41. package/dist/types/stage.js.map +1 -0
  42. package/dist/types/utils.d.ts +24 -0
  43. package/dist/types/utils.d.ts.map +1 -0
  44. package/dist/types/utils.js +5 -0
  45. package/dist/types/utils.js.map +1 -0
  46. package/dist/types/validation.d.ts +4 -0
  47. package/dist/types/validation.d.ts.map +1 -0
  48. package/dist/types/validation.js +2 -0
  49. package/dist/types/validation.js.map +1 -0
  50. package/package.json +1 -1
  51. package/src/index.ts +185 -83
  52. package/src/types/arguments.ts +55 -0
  53. package/src/types/methods/add.ts +50 -0
  54. package/src/types/methods/at.ts +64 -0
  55. package/src/types/methods/hook.ts +27 -0
  56. package/src/types/methods/mock.ts +90 -0
  57. package/src/types/methods/with.ts +153 -0
  58. package/src/types/methods.ts +11 -0
  59. package/src/types/modular-component.ts +25 -0
  60. package/src/types/stage.ts +91 -0
  61. package/src/types/utils.ts +63 -0
  62. package/src/types/validation.ts +13 -0
  63. package/dist/types.d.ts +0 -79
  64. package/dist/types.d.ts.map +0 -1
  65. package/dist/types.js +0 -2
  66. package/dist/types.js.map +0 -1
  67. package/src/types.ts +0 -279
package/src/types.ts DELETED
@@ -1,279 +0,0 @@
1
- import { FunctionComponent } from 'react'
2
-
3
- // Collapse a union of similar object into the intersection of the various objects
4
- type UnionToIntersection<U> = [U] extends [never]
5
- ? never
6
- : (U extends infer V ? (k: U) => void : never) extends (k: infer I) => void
7
- ? I
8
- : never
9
-
10
- // Base types used for manipulating stages
11
- export type StageEntry = { key: MethodName; value: unknown; stages: string }
12
- type StageList = StageEntry[]
13
-
14
- // Base type used for manipulating methods
15
- export type MethodName = `with${Capitalize<string>}`
16
- export type MethodEntry = {
17
- field: string
18
- transform?: (args: any, value: any) => any
19
- restrict?: unknown
20
- multiple?: boolean
21
- empty?: boolean
22
- symbol?: symbol
23
- }
24
- export type MethodRecord = Record<MethodName, MethodEntry>
25
-
26
- // Take a stage list, and append a new stage at the end
27
- type AppendStage<
28
- List extends StageList,
29
- Stage extends MethodName,
30
- Value extends unknown,
31
- Prev extends StageEntry = GetStage<List, Stage>,
32
- > = [
33
- ...List,
34
- {
35
- key: Stage
36
- value: Value
37
- stages: [Prev] extends [never] ? List[number]['key'] : Prev['stages']
38
- },
39
- ]
40
-
41
- // Take a stage list, and remove all stages matching a set of keys
42
- type DropStages<List extends StageList, Dropped extends string> = {
43
- [Index in keyof List]: List[Index]['key'] extends Dropped
44
- ? never
45
- : List[Index]
46
- }
47
-
48
- // Take a stage list, and keep only the stages matching a set of keys
49
- type KeepStages<List extends StageList, Allowed extends string> = {
50
- [Index in keyof List]: List[Index]['key'] extends Allowed
51
- ? List[Index]
52
- : never
53
- }
54
-
55
- // Parse a stage list to extract all the stages matching a key
56
- type GetStage<
57
- List extends StageList,
58
- Key extends MethodName,
59
- Union = List[number],
60
- > = Union extends { key: Key; value: infer U; stages: infer S }
61
- ? { key: Key; value: U; stages: S }
62
- : never
63
-
64
- // Parse a stage list to extract the collapsed value for a given stage key
65
- type GetStageValue<
66
- List extends StageList,
67
- Key extends MethodName,
68
- > = UnionToIntersection<GetStage<List, Key>['value']>
69
-
70
- // Collapse a complete stage list into an argument object
71
- // Use the deep `extends infer U` method to get a clean object in tooltips
72
- type ComputeArgs<
73
- Stages extends StageList,
74
- Limit extends string,
75
- Union = Stages[number],
76
- Intersection = UnionToIntersection<
77
- Union extends { key: infer Key; value: infer Value }
78
- ? { [key in Key extends string ? Key : never]: Value }
79
- : never
80
- >,
81
- > = Pick<
82
- Intersection,
83
- Limit extends keyof Intersection ? Limit : never
84
-
85
- // Deeply spread the object for cleaner type tooltips
86
- > extends infer U
87
- ? {
88
- [key in keyof U]: U[key] extends Record<string, unknown>
89
- ? U[key] extends infer V
90
- ? { [key in keyof V]: V[key] }
91
- : never
92
- : U[key]
93
- }
94
- : never
95
-
96
- // Check if a custom transform exists for the given argument, and apply
97
- // it to the current value if there is
98
- type TransformArg<
99
- Value,
100
- Symbol
101
- > = Symbol extends keyof ModularStageTransform<Value>
102
- ? ModularStageTransform<Value>[Symbol]
103
- : Value
104
-
105
- // Map all computed arguments against the methods map to convert
106
- // from the stage key to the wanted field name
107
- // Use the deep `extends infer U` method to get a clean object in tooltips
108
- type MapArgs<
109
- Stages extends StageList,
110
- Limit extends string,
111
- Methods extends MethodRecord,
112
- Props,
113
- Args = ComputeArgs<Stages, Limit>,
114
- > = UnionToIntersection<
115
- // Start by injecting the original props
116
- | { props: Props, children: Props extends { children: infer U } ? U : never }
117
- // Map over all configured methods
118
- | {
119
- [key in keyof Methods]: key extends keyof Args // Check if an arg exists for the given method
120
- ? Methods[key] extends MethodEntry
121
- ? {
122
- // Extract the field name from the method
123
- [k in Methods[key]['field']]: TransformArg<
124
- Args[key],
125
- Methods[key]['symbol']
126
- >
127
- }
128
- : never
129
- : // Set to never if the arg does not exist
130
- never
131
- }[keyof Methods]
132
-
133
- // Deeply spread the object for cleaner type tooltips
134
- > extends infer U
135
- ? {
136
- [key in keyof U]: U[key] extends Record<string, unknown>
137
- ? U[key] extends infer V
138
- ? { [key in keyof V]: V[key] }
139
- : never
140
- : U[key]
141
- }
142
- : never
143
-
144
- type ModularExtension<
145
- Props,
146
- Methods extends MethodRecord,
147
- Stages extends StageList,
148
- > = {
149
- [key in keyof Methods]: (Methods[key] extends MethodEntry
150
- ? Methods[key]
151
- : never)['restrict'] extends undefined
152
- ? <
153
- // Cast the method key to a method name
154
- Key extends key extends MethodName ? key : never,
155
- // Extract the current method
156
- Method extends Methods[Key] extends MethodEntry ? Methods[Key] : never,
157
- // If the mode is not 'multiple', get any previous value used
158
- // for the stage
159
- Prev extends Method['multiple'] extends true
160
- ? never
161
- : GetStageValue<Stages, Key>,
162
- // Find the stages occurring before the first instance of the current
163
- // stage, in order to limit the arguments to those defined before the
164
- // stage. This is needed for 'single' mode stages that are called
165
- // multiple time.
166
- Limit extends Method['multiple'] extends true // Ignore for 'multiple' stages
167
- ? Stages[number]['key']
168
- : [GetStage<Stages, Key>] extends [never] // Ignore if it's the first time we see the stage
169
- ? Stages[number]['key']
170
- : GetStage<Stages, Key>['stages'],
171
- // Compute the kept stages by dropping all references to current stage
172
- // for multiple mode, or keeping all previous stages for single mode
173
- KeptStages extends Method['multiple'] extends true
174
- ? DropStages<Stages, Key>
175
- : Stages,
176
- // Get the value to use or infer, restricting it to any
177
- // configured restriction or previously used values
178
- Value extends [Prev] extends [never]
179
- ? [Method['restrict']] extends [never]
180
- ? unknown
181
- : Method['restrict']
182
- : Prev,
183
- >(
184
- // A stage accepts either a direct value or a function (hook) generating the value
185
- value?:
186
- | Value
187
- | ((args: MapArgs<Stages, Limit, Methods, Props>) => Value | void),
188
- ) => Modular<Props, Methods, AppendStage<KeptStages, Key, Value>>
189
- : <
190
- // Cast the method key to a method name
191
- Key extends key extends MethodName ? key : never,
192
- // Extract the current method
193
- Method extends Methods[Key] extends MethodEntry ? Methods[Key] : never,
194
- // If the mode is not 'multiple', get any previous value used
195
- // for the stage
196
- Prev extends Method['multiple'] extends true
197
- ? never
198
- : GetStageValue<Stages, Key>,
199
- // Find the stages occurring before the first instance of the current
200
- // stage, in order to limit the arguments to those defined before the
201
- // stage. This is needed for 'single' mode stages that are called
202
- // multiple time.
203
- Limit extends Method['multiple'] extends true // Ignore for 'multiple' stages
204
- ? Stages[number]['key']
205
- : [GetStage<Stages, Key>] extends [never] // Ignore if it's the first time we see the stage
206
- ? Stages[number]['key']
207
- : GetStage<Stages, Key>['stages'],
208
- // Compute the kept stages by dropping all references to current stage
209
- // for multiple mode, or keeping all previous stages for single mode
210
- KeptStages extends Method['multiple'] extends true
211
- ? DropStages<Stages, Key>
212
- : Stages,
213
- // Get the value to use or infer, restricting it to any
214
- // configured restriction or previously used values
215
- Value extends [Prev] extends [never]
216
- ? [Method['restrict']] extends [never]
217
- ? unknown
218
- : Method['restrict']
219
- : Prev,
220
- >(
221
- // A stage accepts either a direct value or a function (hook) generating the value
222
- value:
223
- | Value
224
- | ((args: MapArgs<Stages, Limit, Methods, Props>) => Value),
225
- ) => Modular<Props, Methods, AppendStage<KeptStages, Key, Value>>
226
- } & {
227
- // Create a new component using the same stages as the current component
228
- // up to a certain point
229
- atStage<
230
- // Key of the stage to keep to
231
- Key extends Stages[number]['key'],
232
- // List of stages up to the one referenced by the key
233
- KeptStages extends KeepStages<
234
- Stages,
235
- GetStage<Stages, Key>['stages'] | Key
236
- >,
237
- >(
238
- stage: Key,
239
- ): Modular<Props, Methods, KeptStages>
240
- // Generate a hook instead of a component, returning the generated arguments
241
- asHook(): Props extends {}
242
- ? () => MapArgs<Stages, Stages[number]['key'], Methods, Props>
243
- : (props: Props) => MapArgs<Stages, Stages[number]['key'], Methods, Props>
244
- // Overload the asHook function to allow taking in a field from the generated arguments,
245
- // and returning only the value from this field
246
- asHook<
247
- Field extends keyof MapArgs<Stages, Stages[number]['key'], Methods, Props>,
248
- >(
249
- field: Field,
250
- ): Props extends {}
251
- ? () => MapArgs<Stages, Stages[number]['key'], Methods, Props>[Field]
252
- : (
253
- props: Props,
254
- ) => MapArgs<Stages, Stages[number]['key'], Methods, Props>[Field]
255
- }
256
-
257
- // Type used for describing a ModularComponent. In essence, it is a FunctionComponent
258
- // with all the factories methods appended.
259
- // In this type, we strongly-type all factory methods and the enhanced returned component
260
- // by keeping track of all the previous stages through a stage-list tuple
261
- export type Modular<
262
- // The props are set and are invariant for the component, but the `props` argument
263
- // itself can be extended
264
- Props,
265
- // List of all methods available for the component, won't change as the component
266
- // is built but depends on the factory that started the build
267
- Methods extends MethodRecord,
268
- // Finally, the list of stages that will be appended as methods are called
269
- Stages extends StageList,
270
- > =
271
- // At its core, the ModularComponent is a normal FunctionComponent taking
272
- // the original props, extended with additional methods
273
- FunctionComponent<Props> & ModularExtension<Props, Methods, Stages>
274
-
275
- /* Exposed interfaces used for extending functionality */
276
-
277
- // Add a value transformation for a given stage. The T type is the
278
- // original type of the value passed to the stage.
279
- export interface ModularStageTransform<T> {}