@strictly/react-form 0.0.10 → 0.0.12

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 (54) hide show
  1. package/.out/core/mobx/field_adapter_builder.js +18 -6
  2. package/.out/core/mobx/{form_presenter.d.ts → form_model.d.ts} +15 -21
  3. package/.out/core/mobx/form_model.js +513 -0
  4. package/.out/core/mobx/hooks.d.ts +6 -25
  5. package/.out/core/mobx/hooks.js +14 -50
  6. package/.out/core/mobx/merge_field_adapters_with_validators.js +1 -5
  7. package/.out/core/mobx/specs/fixtures.js +2 -1
  8. package/.out/core/mobx/specs/{form_presenter.tests.js → form_model.tests.js} +52 -43
  9. package/.out/core/mobx/specs/sub_form_field_adapters.tests.js +2 -1
  10. package/.out/core/mobx/types.d.ts +4 -4
  11. package/.out/field_converters/integer_to_string_converter.js +12 -4
  12. package/.out/field_converters/maybe_identity_converter.js +12 -4
  13. package/.out/field_converters/nullable_to_boolean_converter.js +24 -7
  14. package/.out/field_converters/select_value_type_converter.js +36 -12
  15. package/.out/index.d.ts +1 -1
  16. package/.out/index.js +1 -1
  17. package/.out/mantine/create_checkbox.js +8 -4
  18. package/.out/mantine/create_fields_view.js +7 -4
  19. package/.out/mantine/create_form.js +1 -1
  20. package/.out/mantine/create_radio_group.js +8 -4
  21. package/.out/mantine/create_text_input.js +8 -4
  22. package/.out/mantine/create_value_input.js +8 -4
  23. package/.out/mantine/hooks.js +218 -92
  24. package/.out/mantine/specs/checkbox_hooks.stories.js +13 -1
  25. package/.out/mantine/specs/checkbox_hooks.tests.js +22 -9
  26. package/.out/mantine/specs/fields_view_hooks.stories.js +15 -2
  27. package/.out/mantine/specs/fields_view_hooks.tests.js +12 -3
  28. package/.out/mantine/specs/radio_group_hooks.stories.js +13 -1
  29. package/.out/mantine/specs/radio_group_hooks.tests.js +23 -10
  30. package/.out/mantine/specs/select_hooks.stories.js +13 -1
  31. package/.out/mantine/specs/text_input_hooks.stories.js +13 -1
  32. package/.out/mantine/specs/text_input_hooks.tests.js +18 -7
  33. package/.out/mantine/specs/value_input_hooks.stories.js +14 -2
  34. package/.out/tsconfig.tsbuildinfo +1 -1
  35. package/.out/tsup.config.js +2 -9
  36. package/.out/types/merge_validators.js +1 -4
  37. package/.out/util/partial.js +5 -5
  38. package/.out/vitest.workspace.js +2 -10
  39. package/.turbo/turbo-build.log +9 -9
  40. package/.turbo/turbo-check-types.log +1 -1
  41. package/.turbo/turbo-release$colon$exports.log +1 -1
  42. package/core/mobx/{form_presenter.ts → form_model.ts} +287 -329
  43. package/core/mobx/hooks.tsx +26 -123
  44. package/core/mobx/specs/{form_presenter.tests.ts → form_model.tests.ts} +101 -94
  45. package/core/mobx/types.ts +12 -12
  46. package/dist/index.cjs +639 -600
  47. package/dist/index.d.cts +51 -73
  48. package/dist/index.d.ts +51 -73
  49. package/dist/index.js +644 -601
  50. package/index.ts +1 -1
  51. package/mantine/hooks.tsx +2 -0
  52. package/package.json +1 -1
  53. package/.out/core/mobx/form_presenter.js +0 -422
  54. /package/.out/core/mobx/specs/{form_presenter.tests.d.ts → form_model.tests.d.ts} +0 -0
@@ -3,194 +3,97 @@ import {
3
3
  type ValueOfType,
4
4
  } from '@strictly/define'
5
5
  import {
6
- type FieldsViewProps,
7
- } from 'core/props'
8
- import {
9
- type ComponentType,
10
6
  useCallback,
11
- useMemo,
12
7
  } from 'react'
8
+ import { type FormModel } from './form_model'
13
9
  import {
14
- createUnsafePartialObserverComponent,
15
- type UnsafePartialComponent,
16
- } from 'util/partial'
17
- import { type FormPresenter } from './form_presenter'
18
- import {
19
- type FormFieldsOfPresenter,
20
- type ToValueOfPresenterValuePath,
21
- type ValuePathsOfPresenter,
10
+ type FormFieldsOfModel,
11
+ type ToValueOfModelValuePath,
12
+ type ValuePathsOfModel,
22
13
  } from './types'
23
14
 
24
15
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
- type ValueOfPresenter<P extends FormPresenter<any, any, any, any>> = P extends FormPresenter<infer T, any, any, any>
16
+ type ValueOfModel<M extends FormModel<any, any, any, any>> = M extends FormModel<infer T, any, any, any>
26
17
  ? ValueOfType<ReadonlyTypeOfType<T>>
27
18
  : never
28
19
 
29
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
- type ModelOfPresenter<P extends FormPresenter<any, any, any, any>> = ReturnType<P['createModel']>
31
-
32
- export function useDefaultMobxFormHooks<
33
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
- P extends FormPresenter<any, any, any, any>,
35
- C extends ComponentType<FieldsViewProps<F>>,
36
- F extends FormFieldsOfPresenter<P> = FormFieldsOfPresenter<P>,
37
- >(
38
- presenter: P,
39
- value: ValueOfPresenter<P>,
40
- options?: {
41
- onValidFieldSubmit?: <Path extends ValuePathsOfPresenter<P>>(model: ModelOfPresenter<P>, valuePath: Path) => void,
42
- onValidFormSubmit?: (model: ModelOfPresenter<P>, value: ValueOfPresenter<P>) => void,
43
- },
44
- ): {
45
- model: ModelOfPresenter<P>,
46
- FormFields?: UnsafePartialComponent<C, FieldsViewProps<F>>,
47
- onFormSubmit: () => void,
48
- onFieldValueChange<K extends keyof F>(this: void, key: K, value: F[K]['value']): void,
49
- onFieldFocus?(this: void, key: keyof F): void,
50
- onFieldBlur?(this: void, key: keyof F): void,
51
- onFieldSubmit?(this: void, key: keyof F): boolean | void,
52
- }
53
20
  export function useDefaultMobxFormHooks<
54
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
- P extends FormPresenter<any, any, any, any>,
56
- C extends ComponentType<FieldsViewProps<F>>,
57
- F extends FormFieldsOfPresenter<P> = FormFieldsOfPresenter<P>,
22
+ M extends FormModel<any, any, any, any>,
23
+ F extends FormFieldsOfModel<M> = FormFieldsOfModel<M>,
58
24
  >(
59
- presenter: P,
60
- value: ValueOfPresenter<P>,
61
- options: {
62
- onValidFieldSubmit?: <Path extends ValuePathsOfPresenter<P>>(model: ModelOfPresenter<P>, valuePath: Path) => void,
63
- onValidFormSubmit?: (model: ModelOfPresenter<P>, value: ValueOfPresenter<P>) => void,
64
- FormFieldsView: C,
65
- },
66
- ): {
67
- model: ModelOfPresenter<P>,
68
- FormFields: UnsafePartialComponent<C, FieldsViewProps<F>>,
69
- onFormSubmit: () => void,
70
- onFieldValueChange<K extends keyof F>(this: void, key: K, value: F[K]['value']): void,
71
- onFieldFocus?(this: void, key: keyof F): void,
72
- onFieldBlur?(this: void, key: keyof F): void,
73
- onFieldSubmit?(this: void, key: keyof F): boolean | void,
74
- }
75
- export function useDefaultMobxFormHooks<
76
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
- P extends FormPresenter<any, any, any, any>,
78
- C extends FieldsViewProps<F>,
79
- F extends FormFieldsOfPresenter<P> = FormFieldsOfPresenter<P>,
80
- >(
81
- presenter: P,
82
- value: ValueOfPresenter<P>,
25
+ model: M,
83
26
  {
84
27
  onValidFieldSubmit,
85
28
  onValidFormSubmit,
86
- FormFieldsView,
87
29
  }: {
88
- onValidFieldSubmit?: <Path extends ValuePathsOfPresenter<P>>(model: ModelOfPresenter<P>, valuePath: Path) => void,
89
- onValidFormSubmit?: (model: ModelOfPresenter<P>, value: ValueOfPresenter<P>) => void,
90
- FormFieldsView?: ComponentType<C>,
30
+ onValidFieldSubmit?: <Path extends ValuePathsOfModel<M>>(valuePath: Path) => void,
31
+ onValidFormSubmit?: (value: ValueOfModel<M>) => void,
91
32
  } = {},
92
33
  ): {
93
- model: ModelOfPresenter<P>,
94
- FormFields?: UnsafePartialComponent<ComponentType<C>, FieldsViewProps<F>> | undefined,
95
34
  onFormSubmit: () => void,
96
35
  onFieldValueChange<K extends keyof F>(this: void, key: K, value: F[K]['value']): void,
97
36
  onFieldFocus?(this: void, key: keyof F): void,
98
37
  onFieldBlur?(this: void, key: keyof F): void,
99
38
  onFieldSubmit?(this: void, key: keyof F): boolean | void,
100
39
  } {
101
- const model = useMemo(function () {
102
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
103
- return presenter.createModel(value) as ReturnType<P['createModel']>
104
- }, [
105
- presenter,
106
- value,
107
- ])
108
-
109
40
  const onFieldValueChange = useCallback(
110
- function<Path extends ValuePathsOfPresenter<P>> (
41
+ function<Path extends ValuePathsOfModel<M>> (
111
42
  path: Path,
112
- value: ToValueOfPresenterValuePath<P, Path>,
43
+ value: ToValueOfModelValuePath<M, Path>,
113
44
  ) {
114
- presenter.clearFieldError(model, path)
115
- presenter.setFieldValue<Path>(model, path, value)
45
+ // TODO do in one action
46
+ model.clearFieldError(path)
47
+ model.setFieldValue<Path>(path, value)
116
48
  },
117
- [
118
- presenter,
119
- model,
120
- ],
49
+ [model],
121
50
  )
122
51
 
123
52
  const onFieldSubmit = useCallback(
124
- function<Path extends ValuePathsOfPresenter<P>> (valuePath: Path) {
125
- if (presenter.validateField(model, valuePath)) {
126
- onValidFieldSubmit?.(model, valuePath)
53
+ function<Path extends ValuePathsOfModel<M>> (valuePath: Path) {
54
+ if (model.validateField(valuePath)) {
55
+ onValidFieldSubmit?.(valuePath)
127
56
  }
128
57
  return false
129
58
  },
130
59
  [
131
- presenter,
132
60
  model,
133
61
  onValidFieldSubmit,
134
62
  ],
135
63
  )
136
64
 
137
65
  const onFieldBlur = useCallback(
138
- function<Path extends ValuePathsOfPresenter<P>> (path: Path) {
66
+ function<Path extends ValuePathsOfModel<M>> (path: Path) {
139
67
  // work around potential loss of focus prior to state potentially invalidating change triggering
140
68
  // (e.g. changing a discriminator)
141
69
  // TODO debounce?
142
70
  setTimeout(function () {
143
- if (presenter.isValuePathActive(model, path)) {
144
- presenter.validateField(model, path, true)
71
+ if (model.isValuePathActive(path)) {
72
+ model.validateField(path, true)
145
73
  }
146
74
  }, 100)
147
75
  },
148
- [
149
- presenter,
150
- model,
151
- ],
76
+ [model],
152
77
  )
153
78
 
154
79
  const onFormSubmit = useCallback(
155
80
  function () {
156
- if (presenter.validateAll(model)) {
157
- onValidFormSubmit?.(model, model.value)
81
+ if (model.validateAll()) {
82
+ onValidFormSubmit?.(model.value)
158
83
  }
159
84
  },
160
85
  [
161
- presenter,
162
86
  model,
163
87
  onValidFormSubmit,
164
88
  ],
165
89
  )
166
90
 
167
- const FormFields = useMemo(() => {
168
- if (FormFieldsView == null) {
169
- return undefined
170
- }
171
- return createUnsafePartialObserverComponent(FormFieldsView, (): FieldsViewProps<F> => {
172
- return {
173
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
174
- fields: model.fields as C['fields'],
175
- onFieldBlur,
176
- onFieldSubmit,
177
- onFieldValueChange,
178
- }
179
- })
180
- }, [
181
- model,
182
- FormFieldsView,
183
- onFieldBlur,
184
- onFieldSubmit,
185
- onFieldValueChange,
186
- ])
91
+ // TODO have option to automatically bind all these callbacks to a FieldsView parameter
187
92
 
188
93
  return {
189
- model,
190
94
  onFieldValueChange,
191
95
  onFieldSubmit,
192
96
  onFieldBlur,
193
97
  onFormSubmit,
194
- FormFields,
195
98
  }
196
99
  }
@@ -6,14 +6,10 @@ import {
6
6
  nullType,
7
7
  numberType,
8
8
  object,
9
- type ReadonlyOfTypeDef,
10
- type ReadonlyTypeOfType,
11
9
  record,
12
10
  stringType,
13
- type Type,
14
11
  union,
15
12
  type ValueOfType,
16
- type ValueOfTypeDef,
17
13
  type ValueToTypePathsOfType,
18
14
  } from '@strictly/define'
19
15
  import { type FieldAdapter } from 'core/mobx/field_adapter'
@@ -24,9 +20,8 @@ import {
24
20
  import {
25
21
  type FlattenedTypePathsToAdaptersOf,
26
22
  FormModel,
27
- FormPresenter,
28
23
  type ValuePathsToAdaptersOf,
29
- } from 'core/mobx/form_presenter'
24
+ } from 'core/mobx/form_model'
30
25
  import { IntegerToStringConverter } from 'field_converters/integer_to_string_converter'
31
26
  import { NullableToBooleanConverter } from 'field_converters/nullable_to_boolean_converter'
32
27
  import { SelectDiscriminatedUnionConverter } from 'field_converters/select_value_type_converter'
@@ -43,21 +38,6 @@ import {
43
38
 
44
39
  const IS_NAN_ERROR = 1
45
40
 
46
- class TestFormPresenter<
47
- T extends Type,
48
- ValueToTypePaths extends Readonly<Record<string, string>>,
49
- TypePathsToAdapters extends FlattenedTypePathsToAdaptersOf<
50
- FlattenedValuesOfType<T, '*'>,
51
- ValueOfType<ReadonlyTypeOfType<T>>
52
- >,
53
- > extends FormPresenter<T, ValueToTypePaths, TypePathsToAdapters> {
54
- override createModel(value: ValueOfTypeDef<ReadonlyOfTypeDef<T['definition']>, {}>): FormModel<T, ValueToTypePaths,
55
- TypePathsToAdapters, ValuePathsToAdaptersOf<TypePathsToAdapters, ValueToTypePaths>>
56
- {
57
- return new FormModel(this.type, value, this.adapters)
58
- }
59
- }
60
-
61
41
  const originalIntegerToStringAdapter = adapterFromTwoWayConverter(
62
42
  new IntegerToStringConverter(IS_NAN_ERROR),
63
43
  prototypingFieldValueFactory(0),
@@ -492,20 +472,12 @@ describe('all', function () {
492
472
  // TODO union
493
473
  })
494
474
 
495
- describe('FormPresenter', function () {
475
+ describe('FormModel', function () {
496
476
  describe('literal', function () {
497
477
  const typeDef = numberType
498
478
  const adapters = {
499
479
  $: integerToStringAdapter,
500
480
  } as const
501
- const presenter = new TestFormPresenter<
502
- typeof typeDef,
503
- ValueToTypePathsOfType<typeof typeDef>,
504
- typeof adapters
505
- >(
506
- typeDef,
507
- adapters,
508
- )
509
481
  const originalValue: ValueOfType<typeof typeDef> = 2
510
482
  let model: FormModel<
511
483
  typeof typeDef,
@@ -513,13 +485,21 @@ describe('all', function () {
513
485
  typeof adapters
514
486
  >
515
487
  beforeEach(function () {
516
- model = presenter.createModel(originalValue)
488
+ model = new FormModel<
489
+ typeof typeDef,
490
+ ValueToTypePathsOfType<typeof typeDef>,
491
+ typeof adapters
492
+ >(
493
+ typeDef,
494
+ originalValue,
495
+ adapters,
496
+ )
517
497
  })
518
498
 
519
499
  describe('setFieldValueAndValidate', function () {
520
500
  describe('success', function () {
521
501
  beforeEach(function () {
522
- presenter.setFieldValueAndValidate<'$'>(model, '$', '1')
502
+ model.setFieldValueAndValidate<'$'>('$', '1')
523
503
  })
524
504
 
525
505
  it('does set the underlying value', function () {
@@ -539,7 +519,7 @@ describe('all', function () {
539
519
  describe('failure', function () {
540
520
  describe('conversion fails', function () {
541
521
  beforeEach(function () {
542
- presenter.setFieldValueAndValidate<'$'>(model, '$', 'x')
522
+ model.setFieldValueAndValidate<'$'>('$', 'x')
543
523
  })
544
524
 
545
525
  it('does not set the underlying value', function () {
@@ -565,7 +545,7 @@ describe('all', function () {
565
545
  error: errorCode,
566
546
  value: [newValue],
567
547
  })
568
- presenter.setFieldValueAndValidate<'$'>(model, '$', '-1')
548
+ model.setFieldValueAndValidate<'$'>('$', '-1')
569
549
  })
570
550
 
571
551
  it('does set the underlying value', function () {
@@ -596,7 +576,7 @@ describe('all', function () {
596
576
  ],
597
577
  ] as const)('setFieldValue to %s', function (newValue, expectedValue) {
598
578
  beforeEach(function () {
599
- presenter.setFieldValue<'$'>(model, '$', newValue)
579
+ model.setFieldValue<'$'>('$', newValue)
600
580
  })
601
581
 
602
582
  it('does set the underlying value', function () {
@@ -619,14 +599,6 @@ describe('all', function () {
619
599
  const converters = {
620
600
  '$.*': integerToStringAdapter,
621
601
  } as const
622
- const presenter = new TestFormPresenter<
623
- typeof typeDef,
624
- ValueToTypePathsOfType<typeof typeDef>,
625
- typeof converters
626
- >(
627
- typeDef,
628
- converters,
629
- )
630
602
  let originalValue: ValueOfType<typeof typeDef>
631
603
  let model: FormModel<
632
604
  typeof typeDef,
@@ -639,13 +611,21 @@ describe('all', function () {
639
611
  3,
640
612
  7,
641
613
  ]
642
- model = presenter.createModel(originalValue)
614
+ model = new FormModel<
615
+ typeof typeDef,
616
+ ValueToTypePathsOfType<typeof typeDef>,
617
+ typeof converters
618
+ >(
619
+ typeDef,
620
+ originalValue,
621
+ converters,
622
+ )
643
623
  })
644
624
 
645
625
  describe('setFieldValueAndValidate', function () {
646
626
  describe('success', function () {
647
627
  beforeEach(function () {
648
- presenter.setFieldValueAndValidate<'$.0'>(model, '$.0', '100')
628
+ model.setFieldValueAndValidate<'$.0'>('$.0', '100')
649
629
  })
650
630
 
651
631
  it('sets the underlying value', function () {
@@ -668,7 +648,7 @@ describe('all', function () {
668
648
 
669
649
  describe('failure', function () {
670
650
  beforeEach(function () {
671
- presenter.setFieldValueAndValidate<'$.0'>(model, '$.0', 'x')
651
+ model.setFieldValueAndValidate<'$.0'>('$.0', 'x')
672
652
  })
673
653
 
674
654
  it('does not set the underlying value', function () {
@@ -691,7 +671,7 @@ describe('all', function () {
691
671
  'x',
692
672
  ])('setFieldValue to %s', function (newValue) {
693
673
  beforeEach(function () {
694
- presenter.setFieldValue(model, '$.0', newValue)
674
+ model.setFieldValue('$.0', newValue)
695
675
  })
696
676
 
697
677
  it('does not set the underlying value', function () {
@@ -710,10 +690,10 @@ describe('all', function () {
710
690
 
711
691
  describe('validate', function () {
712
692
  beforeEach(function () {
713
- presenter.setFieldValue(model, '$.0', 'x')
714
- presenter.setFieldValue(model, '$.1', '2')
715
- presenter.setFieldValue(model, '$.2', 'z')
716
- presenter.validateAll(model)
693
+ model.setFieldValue('$.0', 'x')
694
+ model.setFieldValue('$.1', '2')
695
+ model.setFieldValue('$.2', 'z')
696
+ model.validateAll()
717
697
  })
718
698
 
719
699
  it('contains errors for all invalid fields', function () {
@@ -756,7 +736,7 @@ describe('all', function () {
756
736
  })
757
737
 
758
738
  it('supplies the full, previous context when converting', function () {
759
- presenter.setFieldValueAndValidate(model, '$.2', '4')
739
+ model.setFieldValueAndValidate('$.2', '4')
760
740
 
761
741
  expect(integerToStringAdapter.revert).toHaveBeenCalledOnce()
762
742
  expect(integerToStringAdapter.revert).toHaveBeenCalledWith(
@@ -782,7 +762,7 @@ describe('all', function () {
782
762
  model.errors['$.0'] = 0
783
763
  model.errors['$.1'] = 1
784
764
  model.errors['$.2'] = 2
785
- presenter.addListItem(model, '$', null, 0)
765
+ model.addListItem('$', null, 0)
786
766
  })
787
767
 
788
768
  it('adds the list item to the underlying value', function () {
@@ -839,7 +819,7 @@ describe('all', function () {
839
819
 
840
820
  describe('add defined value', function () {
841
821
  beforeEach(function () {
842
- presenter.addListItem(model, '$', [5])
822
+ model.addListItem('$', [5])
843
823
  })
844
824
 
845
825
  it('adds the expected value at the end', function () {
@@ -881,7 +861,7 @@ describe('all', function () {
881
861
 
882
862
  describe('remove first item', function () {
883
863
  beforeEach(function () {
884
- presenter.removeListItem(model, '$.0')
864
+ model.removeListItem('$.0')
885
865
  })
886
866
 
887
867
  it('updates the underlying value', function () {
@@ -907,7 +887,7 @@ describe('all', function () {
907
887
 
908
888
  describe('remove second item', function () {
909
889
  beforeEach(function () {
910
- presenter.removeListItem(model, '$.1')
890
+ model.removeListItem('$.1')
911
891
  })
912
892
 
913
893
  it('updates the underlying value', function () {
@@ -930,6 +910,25 @@ describe('all', function () {
930
910
  })
931
911
  })
932
912
  })
913
+
914
+ describe('remove two items', function () {
915
+ beforeEach(function () {
916
+ model.removeListItem('$.0', '$.1')
917
+ })
918
+
919
+ it('updates the underlying value', function () {
920
+ expect(model.value).toEqual([7])
921
+ })
922
+
923
+ it('updates the field values and errors', function () {
924
+ expect(model.fields).toEqual({
925
+ '$.0': expect.objectContaining({
926
+ value: '7',
927
+ error: 2,
928
+ }),
929
+ })
930
+ })
931
+ })
933
932
  })
934
933
  })
935
934
 
@@ -946,14 +945,6 @@ describe('all', function () {
946
945
  '$.*': integerToStringAdapter,
947
946
  } as const
948
947
  type ValueToTypePaths = ValueToTypePathsOfType<typeof type>
949
- const presenter = new TestFormPresenter<
950
- typeof type,
951
- ValueToTypePaths,
952
- typeof adapters
953
- >(
954
- type,
955
- adapters,
956
- )
957
948
  let originalValue: ValueOfType<typeof type>
958
949
  let model: FormModel<
959
950
  typeof type,
@@ -962,7 +953,15 @@ describe('all', function () {
962
953
  >
963
954
  beforeEach(function () {
964
955
  originalValue = null
965
- model = presenter.createModel(originalValue)
956
+ model = new FormModel<
957
+ typeof type,
958
+ ValueToTypePaths,
959
+ typeof adapters
960
+ >(
961
+ type,
962
+ originalValue,
963
+ adapters,
964
+ )
966
965
  })
967
966
 
968
967
  it('has the expected fields', function () {
@@ -979,7 +978,7 @@ describe('all', function () {
979
978
  describe('setFieldValueAndValidate', function () {
980
979
  describe('success', function () {
981
980
  beforeEach(function () {
982
- presenter.setFieldValueAndValidate<'$'>(model, '$', true)
981
+ model.setFieldValueAndValidate<'$'>('$', true)
983
982
  })
984
983
 
985
984
  it('sets the underlying value', function () {
@@ -1016,21 +1015,21 @@ describe('all', function () {
1016
1015
  '$.x:a': identityAdapter(0).narrow,
1017
1016
  '$.y:b': identityAdapter(false).narrow,
1018
1017
  } as const
1019
- const presenter = new TestFormPresenter<
1020
- typeof type,
1021
- ValueToTypePaths,
1022
- typeof adapters
1023
- >(
1024
- type,
1025
- adapters,
1026
- )
1027
1018
 
1028
1019
  describe('isValuePathActive', function () {
1029
1020
  describe('discriminator x', function () {
1030
- const model = presenter.createModel({
1031
- d: 'x',
1032
- a: 1,
1033
- })
1021
+ const model = new FormModel<
1022
+ typeof type,
1023
+ ValueToTypePaths,
1024
+ typeof adapters
1025
+ >(
1026
+ type,
1027
+ {
1028
+ d: 'x',
1029
+ a: 1,
1030
+ },
1031
+ adapters,
1032
+ )
1034
1033
  it.each([
1035
1034
  [
1036
1035
  '$',
@@ -1045,16 +1044,24 @@ describe('all', function () {
1045
1044
  false,
1046
1045
  ],
1047
1046
  ] as const)('value path %s is active %s', function (path, expected) {
1048
- const isValid = presenter.isValuePathActive(model, path)
1047
+ const isValid = model.isValuePathActive(path)
1049
1048
  expect(isValid).toBe(expected)
1050
1049
  })
1051
1050
  })
1052
1051
 
1053
1052
  describe('discriminator y', function () {
1054
- const model = presenter.createModel({
1055
- d: 'y',
1056
- b: false,
1057
- })
1053
+ const model = new FormModel<
1054
+ typeof type,
1055
+ ValueToTypePaths,
1056
+ typeof adapters
1057
+ >(
1058
+ type,
1059
+ {
1060
+ d: 'y',
1061
+ b: false,
1062
+ },
1063
+ adapters,
1064
+ )
1058
1065
  it.each([
1059
1066
  [
1060
1067
  '$',
@@ -1069,7 +1076,7 @@ describe('all', function () {
1069
1076
  true,
1070
1077
  ],
1071
1078
  ] as const)('value path %s is active %s', function (path, expected) {
1072
- const isValid = presenter.isValuePathActive(model, path)
1079
+ const isValid = model.isValuePathActive(path)
1073
1080
  expect(isValid).toBe(expected)
1074
1081
  })
1075
1082
  })
@@ -1087,14 +1094,6 @@ describe('all', function () {
1087
1094
  $: '$',
1088
1095
  '$.fake': '$.fake',
1089
1096
  }
1090
- const presenter = new TestFormPresenter<
1091
- typeof typeDef,
1092
- JsonPaths,
1093
- typeof converters
1094
- >(
1095
- typeDef,
1096
- converters,
1097
- )
1098
1097
  let originalValue: ValueOfType<typeof typeDef>
1099
1098
  let model: FormModel<
1100
1099
  typeof typeDef,
@@ -1103,7 +1102,15 @@ describe('all', function () {
1103
1102
  >
1104
1103
  beforeEach(function () {
1105
1104
  originalValue = 1
1106
- model = presenter.createModel(originalValue)
1105
+ model = new FormModel<
1106
+ typeof typeDef,
1107
+ JsonPaths,
1108
+ typeof converters
1109
+ >(
1110
+ typeDef,
1111
+ originalValue,
1112
+ converters,
1113
+ )
1107
1114
  })
1108
1115
 
1109
1116
  it('returns the default value for the fake field', function () {
@@ -1114,7 +1121,7 @@ describe('all', function () {
1114
1121
 
1115
1122
  describe('setting fake field', function () {
1116
1123
  beforeEach(function () {
1117
- presenter.setFieldValue(model, '$.fake', true)
1124
+ model.setFieldValue('$.fake', true)
1118
1125
  })
1119
1126
 
1120
1127
  it('stores the new value', function () {
@@ -2,16 +2,16 @@
2
2
  import { type ToOfFieldAdapter } from './field_adapter'
3
3
  import {
4
4
  type FlattenedConvertedFieldsOf,
5
- type FormPresenter,
6
- } from './form_presenter'
5
+ type FormModel,
6
+ } from './form_model'
7
7
 
8
8
  /**
9
9
  * Used to extract the supported value paths from a presenter
10
10
  */
11
- export type ValuePathsOfPresenter<
11
+ export type ValuePathsOfModel<
12
12
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
- Presenter extends FormPresenter<any, any, any, any>,
14
- > = Presenter extends FormPresenter<
13
+ Presenter extends FormModel<any, any, any, any>,
14
+ > = Presenter extends FormModel<
15
15
  infer _1,
16
16
  infer _2,
17
17
  infer _3,
@@ -23,11 +23,11 @@ export type ValuePathsOfPresenter<
23
23
  * Used to extract the render type (so the value that is passed to the view) of a given value path
24
24
  * from a presenter
25
25
  */
26
- export type ToValueOfPresenterValuePath<
26
+ export type ToValueOfModelValuePath<
27
27
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- Presenter extends FormPresenter<any, any, any, any>,
29
- K extends ValuePathsOfPresenter<Presenter>,
30
- > = Presenter extends FormPresenter<
28
+ Presenter extends FormModel<any, any, any, any>,
29
+ K extends ValuePathsOfModel<Presenter>,
30
+ > = Presenter extends FormModel<
31
31
  infer _1,
32
32
  infer _2,
33
33
  infer _3,
@@ -42,10 +42,10 @@ export type ToValueOfPresenterValuePath<
42
42
  * is less typing, albeit at the cost of potentially getting type errors
43
43
  * reported a long way away from the source
44
44
  */
45
- export type FormFieldsOfPresenter<
45
+ export type FormFieldsOfModel<
46
46
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- Presenter extends FormPresenter<any, any, any, any>,
48
- > = Presenter extends FormPresenter<
47
+ Presenter extends FormModel<any, any, any, any>,
48
+ > = Presenter extends FormModel<
49
49
  infer _1,
50
50
  infer _2,
51
51
  infer _3,