@logixjs/form 0.0.2 → 1.0.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/dist/index.cjs CHANGED
@@ -52,7 +52,7 @@ module.exports = __toCommonJS(index_exports);
52
52
 
53
53
  // src/internal/form/impl.ts
54
54
  var Logix4 = __toESM(require("@logixjs/core"), 1);
55
- var import_effect4 = require("effect");
55
+ var import_effect3 = require("effect");
56
56
 
57
57
  // src/internal/form/traits.ts
58
58
  var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1092,8 +1092,14 @@ var makeFormController = (params) => {
1092
1092
  });
1093
1093
  const state = yield* runtime.getState;
1094
1094
  const { errors: _errors, ui: _ui, $form: _meta, ...values } = state;
1095
- const decoded = import_effect.Schema.decodeUnknownEither(params.valuesSchema)(values);
1096
- const schemaTree = decoded._tag === "Right" ? {} : toSchemaErrorTree(decoded.left);
1095
+ const schemaTree = (() => {
1096
+ try {
1097
+ import_effect.Schema.decodeUnknownSync(params.valuesSchema)(values);
1098
+ return {};
1099
+ } catch (error) {
1100
+ return toSchemaErrorTree(error);
1101
+ }
1102
+ })();
1097
1103
  yield* runtime.dispatch({
1098
1104
  _tag: "setValue",
1099
1105
  payload: { path: "errors.$schema", value: schemaTree }
@@ -1135,8 +1141,14 @@ var makeFormController = (params) => {
1135
1141
  $form: _metaAfterRules,
1136
1142
  ...valuesAfterRules
1137
1143
  } = stateAfterRules;
1138
- const decoded = import_effect.Schema.decodeUnknownEither(params.valuesSchema)(valuesAfterRules);
1139
- const schemaTree = decoded._tag === "Right" ? {} : toSchemaErrorTree(decoded.left);
1144
+ const schemaTree = (() => {
1145
+ try {
1146
+ import_effect.Schema.decodeUnknownSync(params.valuesSchema)(valuesAfterRules);
1147
+ return {};
1148
+ } catch (error) {
1149
+ return toSchemaErrorTree(error);
1150
+ }
1151
+ })();
1140
1152
  yield* runtime.dispatch({
1141
1153
  _tag: "setValue",
1142
1154
  payload: { path: "errors.$schema", value: schemaTree }
@@ -1252,7 +1264,7 @@ var install = (module2, config) => module2.logic(($) => {
1252
1264
  const prev = pending.get(path);
1253
1265
  if (!prev) return;
1254
1266
  pending.delete(path);
1255
- yield* import_effect2.Fiber.interruptFork(prev);
1267
+ yield* import_effect2.Fiber.interrupt(prev);
1256
1268
  });
1257
1269
  const scheduleDebouncedValidate = (path) => import_effect2.Effect.gen(function* () {
1258
1270
  const ms = debounceMs ?? 0;
@@ -1263,9 +1275,9 @@ var install = (module2, config) => module2.logic(($) => {
1263
1275
  yield* cancelPending(path);
1264
1276
  const fiber = yield* import_effect2.Effect.forkScoped(
1265
1277
  import_effect2.Effect.sleep(import_effect2.Duration.millis(ms)).pipe(
1266
- import_effect2.Effect.zipRight(validate("valueChange", path)),
1278
+ import_effect2.Effect.flatMap(() => validate("valueChange", path)),
1267
1279
  import_effect2.Effect.ensuring(import_effect2.Effect.sync(() => pending.delete(path))),
1268
- import_effect2.Effect.catchAllCause(() => import_effect2.Effect.void)
1280
+ import_effect2.Effect.catchCause(() => import_effect2.Effect.void)
1269
1281
  )
1270
1282
  );
1271
1283
  pending.set(path, fiber);
@@ -1421,7 +1433,6 @@ __export(Rule_exports, {
1421
1433
  });
1422
1434
 
1423
1435
  // src/internal/validators/index.ts
1424
- var import_effect3 = require("effect");
1425
1436
  var ERROR_VALUE_MAX_BYTES = 256;
1426
1437
  var textEncoder = new TextEncoder();
1427
1438
  var jsonByteSize = (value) => {
@@ -1516,7 +1527,7 @@ var pattern = (decl) => {
1516
1527
  var schemaErrorMessage = (schemaError) => {
1517
1528
  let message;
1518
1529
  try {
1519
- message = import_effect3.ParseResult.TreeFormatter.formatErrorSync(schemaError);
1530
+ message = schemaError instanceof Error ? schemaError.message || "schema invalid" : String(schemaError);
1520
1531
  } catch {
1521
1532
  message = "schema invalid";
1522
1533
  }
@@ -1695,28 +1706,28 @@ var fields = (...decls) => {
1695
1706
 
1696
1707
  // src/internal/form/impl.ts
1697
1708
  var FormActions = {
1698
- setValue: import_effect4.Schema.Struct({ path: import_effect4.Schema.String, value: import_effect4.Schema.Unknown }),
1699
- blur: import_effect4.Schema.Struct({ path: import_effect4.Schema.String }),
1700
- submit: import_effect4.Schema.Void,
1701
- validate: import_effect4.Schema.Void,
1702
- validatePaths: import_effect4.Schema.Array(import_effect4.Schema.String),
1703
- submitAttempt: import_effect4.Schema.Void,
1704
- setSubmitting: import_effect4.Schema.Boolean,
1705
- reset: import_effect4.Schema.UndefinedOr(import_effect4.Schema.Unknown),
1706
- setError: import_effect4.Schema.Struct({ path: import_effect4.Schema.String, error: import_effect4.Schema.Unknown }),
1707
- clearErrors: import_effect4.Schema.UndefinedOr(import_effect4.Schema.Array(import_effect4.Schema.String)),
1708
- arrayAppend: import_effect4.Schema.Struct({ path: import_effect4.Schema.String, value: import_effect4.Schema.Unknown }),
1709
- arrayPrepend: import_effect4.Schema.Struct({ path: import_effect4.Schema.String, value: import_effect4.Schema.Unknown }),
1710
- arrayRemove: import_effect4.Schema.Struct({ path: import_effect4.Schema.String, index: import_effect4.Schema.Number }),
1711
- arraySwap: import_effect4.Schema.Struct({
1712
- path: import_effect4.Schema.String,
1713
- indexA: import_effect4.Schema.Number,
1714
- indexB: import_effect4.Schema.Number
1709
+ setValue: import_effect3.Schema.Struct({ path: import_effect3.Schema.String, value: import_effect3.Schema.Unknown }),
1710
+ blur: import_effect3.Schema.Struct({ path: import_effect3.Schema.String }),
1711
+ submit: import_effect3.Schema.Void,
1712
+ validate: import_effect3.Schema.Void,
1713
+ validatePaths: import_effect3.Schema.Array(import_effect3.Schema.String),
1714
+ submitAttempt: import_effect3.Schema.Void,
1715
+ setSubmitting: import_effect3.Schema.Boolean,
1716
+ reset: import_effect3.Schema.UndefinedOr(import_effect3.Schema.Unknown),
1717
+ setError: import_effect3.Schema.Struct({ path: import_effect3.Schema.String, error: import_effect3.Schema.Unknown }),
1718
+ clearErrors: import_effect3.Schema.UndefinedOr(import_effect3.Schema.Array(import_effect3.Schema.String)),
1719
+ arrayAppend: import_effect3.Schema.Struct({ path: import_effect3.Schema.String, value: import_effect3.Schema.Unknown }),
1720
+ arrayPrepend: import_effect3.Schema.Struct({ path: import_effect3.Schema.String, value: import_effect3.Schema.Unknown }),
1721
+ arrayRemove: import_effect3.Schema.Struct({ path: import_effect3.Schema.String, index: import_effect3.Schema.Number }),
1722
+ arraySwap: import_effect3.Schema.Struct({
1723
+ path: import_effect3.Schema.String,
1724
+ indexA: import_effect3.Schema.Number,
1725
+ indexB: import_effect3.Schema.Number
1715
1726
  }),
1716
- arrayMove: import_effect4.Schema.Struct({
1717
- path: import_effect4.Schema.String,
1718
- from: import_effect4.Schema.Number,
1719
- to: import_effect4.Schema.Number
1727
+ arrayMove: import_effect3.Schema.Struct({
1728
+ path: import_effect3.Schema.String,
1729
+ from: import_effect3.Schema.Number,
1730
+ to: import_effect3.Schema.Number
1720
1731
  })
1721
1732
  };
1722
1733
  var initialMeta2 = () => ({
@@ -1726,22 +1737,20 @@ var initialMeta2 = () => ({
1726
1737
  errorCount: 0
1727
1738
  });
1728
1739
  var make2 = (id, config, extend) => {
1729
- const ErrorsSchema = import_effect4.Schema.Unknown;
1730
- const UiSchema = import_effect4.Schema.Unknown;
1731
- const MetaSchema = import_effect4.Schema.Struct({
1732
- submitCount: import_effect4.Schema.Number,
1733
- isSubmitting: import_effect4.Schema.Boolean,
1734
- isDirty: import_effect4.Schema.Boolean,
1735
- errorCount: import_effect4.Schema.Number
1740
+ const ErrorsSchema = import_effect3.Schema.Unknown;
1741
+ const UiSchema = import_effect3.Schema.Unknown;
1742
+ const MetaSchema = import_effect3.Schema.Struct({
1743
+ submitCount: import_effect3.Schema.Number,
1744
+ isSubmitting: import_effect3.Schema.Boolean,
1745
+ isDirty: import_effect3.Schema.Boolean,
1746
+ errorCount: import_effect3.Schema.Number
1747
+ });
1748
+ const StateSchema = import_effect3.Schema.Struct({
1749
+ ...config.values.fields ?? {},
1750
+ errors: ErrorsSchema,
1751
+ ui: UiSchema,
1752
+ $form: MetaSchema
1736
1753
  });
1737
- const StateSchema = import_effect4.Schema.extend(
1738
- config.values,
1739
- import_effect4.Schema.Struct({
1740
- errors: ErrorsSchema,
1741
- ui: UiSchema,
1742
- $form: MetaSchema
1743
- })
1744
- );
1745
1754
  const Actions = FormActions;
1746
1755
  const reducers = makeFormReducers({
1747
1756
  initialValues: config.initialValues
@@ -1783,67 +1792,60 @@ var make2 = (id, config, extend) => {
1783
1792
  if (mode === "store" || mode === "index") return;
1784
1793
  throw new Error(`[Form.make] Invalid identity.mode for "${listPath}" (got "${String(mode)}")`);
1785
1794
  };
1795
+ const isRelativeRuleDep = (dep, options) => {
1796
+ const allowNumericRelativeDep = options?.allowNumericRelativeDep ?? true;
1797
+ if (dep === "$root") return false;
1798
+ if (dep.includes("[") || dep.includes("]") || dep.includes(".")) return false;
1799
+ if (!allowNumericRelativeDep && /^[0-9]+$/.test(dep)) return false;
1800
+ return true;
1801
+ };
1802
+ const prefixRuleDeps = (deps, prefix, options) => {
1803
+ if (!Array.isArray(deps)) return void 0;
1804
+ const out = [];
1805
+ for (const raw of deps) {
1806
+ if (typeof raw !== "string") continue;
1807
+ const dep = raw.trim();
1808
+ if (!dep) continue;
1809
+ out.push(isRelativeRuleDep(dep, options) && prefix ? `${prefix}.${dep}` : dep);
1810
+ }
1811
+ return out;
1812
+ };
1813
+ const prefixRuleInputDeps = (input, prefix, options) => {
1814
+ if (!input || typeof input !== "object") return input;
1815
+ if (Array.isArray(input)) return input;
1816
+ const anyInput = input;
1817
+ const deps = prefixRuleDeps(anyInput.deps, prefix, options);
1818
+ const validate = anyInput.validate;
1819
+ if (typeof validate === "function") {
1820
+ return deps !== void 0 ? { ...anyInput, deps } : input;
1821
+ }
1822
+ if (validate && typeof validate === "object" && !Array.isArray(validate)) {
1823
+ const nextValidate = { ...validate };
1824
+ for (const [name, raw] of Object.entries(validate)) {
1825
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
1826
+ const entryDeps = prefixRuleDeps(raw.deps, prefix, options);
1827
+ if (entryDeps !== void 0) {
1828
+ nextValidate[name] = { ...raw, deps: entryDeps };
1829
+ }
1830
+ }
1831
+ return {
1832
+ ...anyInput,
1833
+ ...deps !== void 0 ? { deps } : {},
1834
+ validate: nextValidate
1835
+ };
1836
+ }
1837
+ return deps !== void 0 ? { ...anyInput, deps } : input;
1838
+ };
1786
1839
  const compileRulesToTraitSpec = (rulesSpec2) => {
1787
1840
  if (!rulesSpec2 || rulesSpec2._tag !== "FormRulesSpec") {
1788
1841
  throw new Error(`[Form.make] "rules" must be a FormRulesSpec (from Form.rules(...)/rules.schema(...))`);
1789
1842
  }
1790
- const joinPath2 = (prefix, suffix) => {
1791
- if (!prefix) return suffix;
1792
- if (!suffix) return prefix;
1793
- return `${prefix}.${suffix}`;
1794
- };
1795
1843
  const dirnamePath = (path) => {
1796
1844
  const p = String(path ?? "").trim();
1797
1845
  if (!p) return "";
1798
1846
  const idx = p.lastIndexOf(".");
1799
1847
  return idx >= 0 ? p.slice(0, idx) : "";
1800
1848
  };
1801
- const isRelativeDep = (dep) => {
1802
- if (typeof dep !== "string") return false;
1803
- const d = dep.trim();
1804
- if (!d) return false;
1805
- if (d === "$root") return false;
1806
- if (d.includes("[") || d.includes("]")) return false;
1807
- if (d.includes(".")) return false;
1808
- return true;
1809
- };
1810
- const prefixDeps = (deps, prefix) => {
1811
- if (!Array.isArray(deps)) return void 0;
1812
- const out = [];
1813
- for (const raw of deps) {
1814
- if (typeof raw !== "string") continue;
1815
- const d = raw.trim();
1816
- if (!d) continue;
1817
- out.push(isRelativeDep(d) ? joinPath2(prefix, d) : d);
1818
- }
1819
- return out;
1820
- };
1821
- const prefixRuleInputDeps = (input, prefix) => {
1822
- if (!input || typeof input !== "object") return input;
1823
- if (Array.isArray(input)) return input;
1824
- const anyInput = input;
1825
- const deps = prefixDeps(anyInput.deps, prefix);
1826
- const validate = anyInput.validate;
1827
- if (typeof validate === "function") {
1828
- return deps !== void 0 ? { ...anyInput, deps } : input;
1829
- }
1830
- if (validate && typeof validate === "object" && !Array.isArray(validate)) {
1831
- const nextValidate = { ...validate };
1832
- for (const [name, raw] of Object.entries(validate)) {
1833
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
1834
- const entryDeps = prefixDeps(raw.deps, prefix);
1835
- if (entryDeps !== void 0) {
1836
- nextValidate[name] = { ...raw, deps: entryDeps };
1837
- }
1838
- }
1839
- return {
1840
- ...anyInput,
1841
- ...deps !== void 0 ? { deps } : {},
1842
- validate: nextValidate
1843
- };
1844
- }
1845
- return deps !== void 0 ? { ...anyInput, deps } : input;
1846
- };
1847
1849
  const decls = Array.isArray(rulesSpec2.decls) ? rulesSpec2.decls : [];
1848
1850
  const spec = {};
1849
1851
  const declared = /* @__PURE__ */ new Set();
@@ -2018,45 +2020,9 @@ var make2 = (id, config, extend) => {
2018
2020
  const idx = valuePath.lastIndexOf(".");
2019
2021
  return idx >= 0 ? valuePath.slice(0, idx) : "";
2020
2022
  })();
2021
- const prefixDeps = (deps, prefix) => {
2022
- if (!Array.isArray(deps)) return void 0;
2023
- const out = [];
2024
- for (const raw of deps) {
2025
- if (typeof raw !== "string") continue;
2026
- const d = raw.trim();
2027
- if (!d) continue;
2028
- const isRelative = d !== "$root" && !d.includes("[") && !d.includes("]") && !d.includes(".") && !/^[0-9]+$/.test(d);
2029
- out.push(isRelative && prefix ? `${prefix}.${d}` : d);
2030
- }
2031
- return out;
2032
- };
2033
- const prefixRuleInputDeps = (input, prefix) => {
2034
- if (!input || typeof input !== "object") return input;
2035
- if (Array.isArray(input)) return input;
2036
- const anyInput = input;
2037
- const deps = prefixDeps(anyInput.deps, prefix);
2038
- const validate = anyInput.validate;
2039
- if (typeof validate === "function") {
2040
- return deps !== void 0 ? { ...anyInput, deps } : input;
2041
- }
2042
- if (validate && typeof validate === "object" && !Array.isArray(validate)) {
2043
- const nextValidate = { ...validate };
2044
- for (const [ruleName, raw] of Object.entries(validate)) {
2045
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
2046
- const entryDeps = prefixDeps(raw.deps, prefix);
2047
- if (entryDeps !== void 0) {
2048
- nextValidate[ruleName] = { ...raw, deps: entryDeps };
2049
- }
2050
- }
2051
- return {
2052
- ...anyInput,
2053
- ...deps !== void 0 ? { deps } : {},
2054
- validate: nextValidate
2055
- };
2056
- }
2057
- return deps !== void 0 ? { ...anyInput, deps } : input;
2058
- };
2059
- const ruleInput = prefixRuleInputDeps(decl.rule, depsPrefix);
2023
+ const ruleInput = prefixRuleInputDeps(decl.rule, depsPrefix, {
2024
+ allowNumericRelativeDep: false
2025
+ });
2060
2026
  const rules3 = make(ruleInput);
2061
2027
  emitRuleSet({
2062
2028
  source: "rules",
@@ -2283,7 +2249,7 @@ var derived = (_valuesSchema) => {
2283
2249
  };
2284
2250
 
2285
2251
  // src/internal/dsl/rules.ts
2286
- var import_effect5 = require("effect");
2252
+ var import_effect4 = require("effect");
2287
2253
  var normalizePrefix = (prefix) => {
2288
2254
  const p = String(prefix ?? "").trim();
2289
2255
  if (!p) return "";
@@ -2336,8 +2302,12 @@ var makeFieldNode = (rule) => ({
2336
2302
  var fieldFromSchema = (schema) => ({
2337
2303
  validate: {
2338
2304
  schema: (value) => {
2339
- const decoded = import_effect5.Schema.decodeUnknownEither(schema)(value);
2340
- return decoded._tag === "Right" ? void 0 : schemaErrorMessage(decoded.left);
2305
+ try {
2306
+ import_effect4.Schema.decodeUnknownSync(schema)(value);
2307
+ return void 0;
2308
+ } catch (error) {
2309
+ return schemaErrorMessage(error);
2310
+ }
2341
2311
  }
2342
2312
  }
2343
2313
  });
@@ -2561,7 +2531,7 @@ var rules = (_valuesSchema) => {
2561
2531
  return field(args[0], args[1], args[2]);
2562
2532
  }
2563
2533
  const input = args[0];
2564
- if (import_effect5.Schema.isSchema(input)) return makeFieldNode(fieldFromSchema(input));
2534
+ if (import_effect4.Schema.isSchema(input)) return makeFieldNode(fieldFromSchema(input));
2565
2535
  return makeFieldNode(input);
2566
2536
  }
2567
2537
  build.field = field2;