@formisch/solid 0.9.5 → 0.10.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/README.md CHANGED
@@ -59,7 +59,13 @@ In addition, Formisch offers several functions (we call them "methods") that can
59
59
 
60
60
  ## Comparison
61
61
 
62
- What makes Formisch unique is its framework-agnostic core, which is fully native to the framework you are using. It works by inserting framework-specific reactivity blocks when the core package is built. The result is a small bundle size and native performance for any UI update. This feature, along with a few others, distinguishes Formisch from other form libraries. My vision for Formisch is to create a framework-agnostic platform similar to [Vite](https://vite.dev/), but for forms.
62
+ What makes Formisch unique is its framework-agnostic core, which is fully native to the framework you are using. It works by inserting framework-specific reactivity blocks when the core package is built, giving you native performance for any UI update. A modular methods API keeps bundles starting at just ~2.5 kB by only including the methods you import, and end-to-end type safety covers deeply nested paths and field arrays with TypeScript inference that stays fast even as forms grow.
63
+
64
+ For a side-by-side look at how Formisch compares to Felte and TanStack Form, see the [comparison guide](https://formisch.dev/solid/guides/comparison/).
65
+
66
+ ## Vision
67
+
68
+ My vision for Formisch is to create a framework-agnostic platform similar to [Vite](https://vite.dev/), but for forms — a shared core that lets the same mental model and codebase work natively across every modern UI framework.
63
69
 
64
70
  ## Partners
65
71
 
package/dist/dev.js CHANGED
@@ -64,7 +64,7 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
64
64
  if (internalFieldStore.kind === "object") {
65
65
  internalFieldStore.children ??= {};
66
66
  for (const key in schema.entries) {
67
- internalFieldStore.children[key] = {};
67
+ internalFieldStore.children[key] ??= {};
68
68
  path.push(key);
69
69
  initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput?.[key], path);
70
70
  path.pop();
@@ -75,6 +75,7 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
75
75
  internalFieldStore.input = /* @__PURE__ */ createSignal(objectInput);
76
76
  }
77
77
  } else {
78
+ if (internalFieldStore.kind && internalFieldStore.kind !== "value") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "value"`);
78
79
  internalFieldStore.kind = "value";
79
80
  if (internalFieldStore.kind === "value") {
80
81
  internalFieldStore.initialInput = /* @__PURE__ */ createSignal(initialInput);
@@ -192,6 +193,43 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
192
193
  });
193
194
  }
194
195
  // @__NO_SIDE_EFFECTS__
196
+ function getFieldBool(internalFieldStore, type) {
197
+ if (internalFieldStore[type].value) return true;
198
+ if (internalFieldStore.kind === "array") {
199
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
200
+ return false;
201
+ }
202
+ if (internalFieldStore.kind == "object") {
203
+ for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
204
+ return false;
205
+ }
206
+ return false;
207
+ }
208
+ // @__NO_SIDE_EFFECTS__
209
+ function getDirtyFieldInput(internalFieldStore, dirtyOnly = true) {
210
+ if (dirtyOnly && !/* @__PURE__ */ getFieldBool(internalFieldStore, "isDirty")) return;
211
+ if (internalFieldStore.kind === "array") {
212
+ if (internalFieldStore.input.value) {
213
+ const value = [];
214
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = /* @__PURE__ */ getDirtyFieldInput(internalFieldStore.children[index], false);
215
+ return value;
216
+ }
217
+ return internalFieldStore.input.value;
218
+ }
219
+ if (internalFieldStore.kind === "object") {
220
+ if (internalFieldStore.input.value) {
221
+ const value = {};
222
+ for (const key in internalFieldStore.children) {
223
+ const child = internalFieldStore.children[key];
224
+ if (!dirtyOnly || /* @__PURE__ */ getFieldBool(child, "isDirty")) value[key] = /* @__PURE__ */ getDirtyFieldInput(child, dirtyOnly);
225
+ }
226
+ return value;
227
+ }
228
+ return internalFieldStore.input.value;
229
+ }
230
+ return internalFieldStore.input.value;
231
+ }
232
+ // @__NO_SIDE_EFFECTS__
195
233
  function getFieldInput(internalFieldStore) {
196
234
  if (internalFieldStore.kind === "array") {
197
235
  if (internalFieldStore.input.value) {
@@ -230,19 +268,6 @@ function getElementInput(element, internalFieldStore) {
230
268
  return element.value;
231
269
  }
232
270
  // @__NO_SIDE_EFFECTS__
233
- function getFieldBool(internalFieldStore, type) {
234
- if (internalFieldStore[type].value) return true;
235
- if (internalFieldStore.kind === "array") {
236
- for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
237
- return false;
238
- }
239
- if (internalFieldStore.kind == "object") {
240
- for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
241
- return false;
242
- }
243
- return false;
244
- }
245
- // @__NO_SIDE_EFFECTS__
246
271
  function getFieldStore(internalFormStore, path) {
247
272
  let internalFieldStore = internalFormStore;
248
273
  for (const key of path) internalFieldStore = internalFieldStore.children[key];
@@ -402,6 +427,17 @@ function getAllErrors(form) {
402
427
  return allErrors;
403
428
  }
404
429
  // @__NO_SIDE_EFFECTS__
430
+ function getDirtyInput(form, config) {
431
+ return getDirtyFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
432
+ }
433
+ // @__NO_SIDE_EFFECTS__
434
+ function getDirtyPaths(form, config) {
435
+ config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL];
436
+ const paths = [];
437
+ config?.path && [...config.path];
438
+ return paths;
439
+ }
440
+ // @__NO_SIDE_EFFECTS__
405
441
  function getErrors(form, config) {
406
442
  return (config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]).errors.value;
407
443
  }
@@ -480,6 +516,24 @@ function move(form, config) {
480
516
  validateIfRequired(internalFormStore, internalArrayStore, "input");
481
517
  });
482
518
  }
519
+ // @__NO_SIDE_EFFECTS__
520
+ function pickDirty(form, config) {
521
+ if (!getFieldBool(form[INTERNAL], "isDirty")) return;
522
+ const result = /* @__PURE__ */ pickFieldValue(form[INTERNAL], config.from);
523
+ return Object.keys(result).length ? result : void 0;
524
+ }
525
+ // @__NO_SIDE_EFFECTS__
526
+ function pickFieldValue(internalFieldStore, value) {
527
+ if (internalFieldStore.kind === "object" && internalFieldStore.input.value && value && typeof value === "object" && !Array.isArray(value)) {
528
+ const result = {};
529
+ for (const key in internalFieldStore.children) {
530
+ const child = internalFieldStore.children[key];
531
+ if (getFieldBool(child, "isDirty") && key in value) result[key] = /* @__PURE__ */ pickFieldValue(child, value[key]);
532
+ }
533
+ return result;
534
+ }
535
+ return value;
536
+ }
483
537
  function remove(form, config) {
484
538
  const internalFormStore = form[INTERNAL];
485
539
  const internalArrayStore = getFieldStore(internalFormStore, config.path);
@@ -513,7 +567,7 @@ function reset(form, config) {
513
567
  untrack(() => {
514
568
  const internalFormStore = form[INTERNAL];
515
569
  const internalFieldStore = config?.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
516
- if (config?.initialInput) setInitialFieldInput(internalFieldStore, config.initialInput);
570
+ if (config && "initialInput" in config) setInitialFieldInput(internalFieldStore, config.initialInput);
517
571
  walkFieldStore(internalFieldStore, (internalFieldStore$1) => {
518
572
  internalFieldStore$1.elements = internalFieldStore$1.initialElements;
519
573
  if (!config?.keepErrors) internalFieldStore$1.errors.value = null;
@@ -789,4 +843,4 @@ function Form(props) {
789
843
  })();
790
844
  }
791
845
 
792
- export { Field, FieldArray, Form, createForm, focus, getAllErrors, getErrors, getInput, handleSubmit, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, validate };
846
+ export { Field, FieldArray, Form, createForm, focus, getAllErrors, getDirtyInput, getDirtyPaths, getErrors, getInput, handleSubmit, insert, move, pickDirty, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, validate };
package/dist/dev.jsx CHANGED
@@ -62,7 +62,7 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
62
62
  if (internalFieldStore.kind === "object") {
63
63
  internalFieldStore.children ??= {};
64
64
  for (const key in schema.entries) {
65
- internalFieldStore.children[key] = {};
65
+ internalFieldStore.children[key] ??= {};
66
66
  path.push(key);
67
67
  initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput?.[key], path);
68
68
  path.pop();
@@ -73,6 +73,7 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
73
73
  internalFieldStore.input = /* @__PURE__ */ createSignal(objectInput);
74
74
  }
75
75
  } else {
76
+ if (internalFieldStore.kind && internalFieldStore.kind !== "value") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "value"`);
76
77
  internalFieldStore.kind = "value";
77
78
  if (internalFieldStore.kind === "value") {
78
79
  internalFieldStore.initialInput = /* @__PURE__ */ createSignal(initialInput);
@@ -190,6 +191,43 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
190
191
  });
191
192
  }
192
193
  // @__NO_SIDE_EFFECTS__
194
+ function getFieldBool(internalFieldStore, type) {
195
+ if (internalFieldStore[type].value) return true;
196
+ if (internalFieldStore.kind === "array") {
197
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
198
+ return false;
199
+ }
200
+ if (internalFieldStore.kind == "object") {
201
+ for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
202
+ return false;
203
+ }
204
+ return false;
205
+ }
206
+ // @__NO_SIDE_EFFECTS__
207
+ function getDirtyFieldInput(internalFieldStore, dirtyOnly = true) {
208
+ if (dirtyOnly && !/* @__PURE__ */ getFieldBool(internalFieldStore, "isDirty")) return;
209
+ if (internalFieldStore.kind === "array") {
210
+ if (internalFieldStore.input.value) {
211
+ const value = [];
212
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = /* @__PURE__ */ getDirtyFieldInput(internalFieldStore.children[index], false);
213
+ return value;
214
+ }
215
+ return internalFieldStore.input.value;
216
+ }
217
+ if (internalFieldStore.kind === "object") {
218
+ if (internalFieldStore.input.value) {
219
+ const value = {};
220
+ for (const key in internalFieldStore.children) {
221
+ const child = internalFieldStore.children[key];
222
+ if (!dirtyOnly || /* @__PURE__ */ getFieldBool(child, "isDirty")) value[key] = /* @__PURE__ */ getDirtyFieldInput(child, dirtyOnly);
223
+ }
224
+ return value;
225
+ }
226
+ return internalFieldStore.input.value;
227
+ }
228
+ return internalFieldStore.input.value;
229
+ }
230
+ // @__NO_SIDE_EFFECTS__
193
231
  function getFieldInput(internalFieldStore) {
194
232
  if (internalFieldStore.kind === "array") {
195
233
  if (internalFieldStore.input.value) {
@@ -228,19 +266,6 @@ function getElementInput(element, internalFieldStore) {
228
266
  return element.value;
229
267
  }
230
268
  // @__NO_SIDE_EFFECTS__
231
- function getFieldBool(internalFieldStore, type) {
232
- if (internalFieldStore[type].value) return true;
233
- if (internalFieldStore.kind === "array") {
234
- for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
235
- return false;
236
- }
237
- if (internalFieldStore.kind == "object") {
238
- for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
239
- return false;
240
- }
241
- return false;
242
- }
243
- // @__NO_SIDE_EFFECTS__
244
269
  function getFieldStore(internalFormStore, path) {
245
270
  let internalFieldStore = internalFormStore;
246
271
  for (const key of path) internalFieldStore = internalFieldStore.children[key];
@@ -400,6 +425,17 @@ function getAllErrors(form) {
400
425
  return allErrors;
401
426
  }
402
427
  // @__NO_SIDE_EFFECTS__
428
+ function getDirtyInput(form, config) {
429
+ return getDirtyFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
430
+ }
431
+ // @__NO_SIDE_EFFECTS__
432
+ function getDirtyPaths(form, config) {
433
+ config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL];
434
+ const paths = [];
435
+ config?.path && [...config.path];
436
+ return paths;
437
+ }
438
+ // @__NO_SIDE_EFFECTS__
403
439
  function getErrors(form, config) {
404
440
  return (config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]).errors.value;
405
441
  }
@@ -478,6 +514,24 @@ function move(form, config) {
478
514
  validateIfRequired(internalFormStore, internalArrayStore, "input");
479
515
  });
480
516
  }
517
+ // @__NO_SIDE_EFFECTS__
518
+ function pickDirty(form, config) {
519
+ if (!getFieldBool(form[INTERNAL], "isDirty")) return;
520
+ const result = /* @__PURE__ */ pickFieldValue(form[INTERNAL], config.from);
521
+ return Object.keys(result).length ? result : void 0;
522
+ }
523
+ // @__NO_SIDE_EFFECTS__
524
+ function pickFieldValue(internalFieldStore, value) {
525
+ if (internalFieldStore.kind === "object" && internalFieldStore.input.value && value && typeof value === "object" && !Array.isArray(value)) {
526
+ const result = {};
527
+ for (const key in internalFieldStore.children) {
528
+ const child = internalFieldStore.children[key];
529
+ if (getFieldBool(child, "isDirty") && key in value) result[key] = /* @__PURE__ */ pickFieldValue(child, value[key]);
530
+ }
531
+ return result;
532
+ }
533
+ return value;
534
+ }
481
535
  function remove(form, config) {
482
536
  const internalFormStore = form[INTERNAL];
483
537
  const internalArrayStore = getFieldStore(internalFormStore, config.path);
@@ -511,7 +565,7 @@ function reset(form, config) {
511
565
  untrack(() => {
512
566
  const internalFormStore = form[INTERNAL];
513
567
  const internalFieldStore = config?.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
514
- if (config?.initialInput) setInitialFieldInput(internalFieldStore, config.initialInput);
568
+ if (config && "initialInput" in config) setInitialFieldInput(internalFieldStore, config.initialInput);
515
569
  walkFieldStore(internalFieldStore, (internalFieldStore$1) => {
516
570
  internalFieldStore$1.elements = internalFieldStore$1.initialElements;
517
571
  if (!config?.keepErrors) internalFieldStore$1.errors.value = null;
@@ -806,11 +860,14 @@ export {
806
860
  createForm,
807
861
  focus,
808
862
  getAllErrors,
863
+ getDirtyInput,
864
+ getDirtyPaths,
809
865
  getErrors,
810
866
  getInput,
811
867
  handleSubmit,
812
868
  insert,
813
869
  move,
870
+ pickDirty,
814
871
  remove,
815
872
  replace,
816
873
  reset,