@vielzeug/forge 1.2.1 → 1.3.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
@@ -58,6 +58,14 @@ if (!submission.ok && submission.type === 'validation') {
58
58
  }
59
59
  ```
60
60
 
61
+ ## Scoped Forms Semantics
62
+
63
+ `form.scope(prefix)` is memoized and returns a sub-form with **relative** field paths for its APIs and state projection.
64
+
65
+ - Root form state paths are absolute (for example, `address.city`).
66
+ - Scoped form state paths are relative (for example, `city` within `form.scope('address')`).
67
+ - Prefer `scoped.validate()` / `scoped.submit()` instead of manually passing touched field arrays across root/scoped boundaries.
68
+
61
69
  ## Documentation
62
70
 
63
71
  - [Overview](https://vielzeug.dev/forge/)
package/dist/_dev.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=!globalThis.__FORGE_PROD__;function t(t){e&&console.warn(`[@vielzeug/forge] ${t}`)}exports.warn=t;
1
+ var e=!globalThis.__FORGE_PROD__;function t(t){e&&console.warn(`[@vielzeug/forge] ${t}`)}function n(t){e&&t()}exports.devOnly=n,exports.warn=t;
2
2
  //# sourceMappingURL=_dev.cjs.map
package/dist/_dev.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __FORGE_PROD__?: boolean }).__FORGE_PROD__;\n\n/** @internal @security Messages may include user-supplied form field paths. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/forge] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"AAAA,IAAM,EAAQ,CAAE,WAA4C,eAG5D,SAAgB,EAAK,EAAmB,CAClC,GAAO,QAAQ,KAAK,qBAAqB,GAAK,CACpD"}
1
+ {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __FORGE_PROD__?: boolean }).__FORGE_PROD__;\n\n/** @internal @security Messages may include user-supplied form field paths. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/forge] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"AAAA,IAAM,EAAQ,CAAE,WAA4C,eAG5D,SAAgB,EAAK,EAAmB,CAClC,GAAO,QAAQ,KAAK,qBAAqB,GAAK,CACpD,CAGA,SAAgB,EAAQ,EAAsB,CACxC,GAAO,EAAG,CAChB"}
package/dist/_dev.js CHANGED
@@ -3,7 +3,10 @@ var e = !globalThis.__FORGE_PROD__;
3
3
  function t(t) {
4
4
  e && console.warn(`[@vielzeug/forge] ${t}`);
5
5
  }
6
+ function n(t) {
7
+ e && t();
8
+ }
6
9
  //#endregion
7
- export { t as warn };
10
+ export { n as devOnly, t as warn };
8
11
 
9
12
  //# sourceMappingURL=_dev.js.map
package/dist/_dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __FORGE_PROD__?: boolean }).__FORGE_PROD__;\n\n/** @internal @security Messages may include user-supplied form field paths. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/forge] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":";AAAA,IAAM,IAAQ,CAAE,WAA4C;AAG5D,SAAgB,EAAK,GAAmB;CACtC,AAAI,KAAO,QAAQ,KAAK,qBAAqB,GAAK;AACpD"}
1
+ {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __FORGE_PROD__?: boolean }).__FORGE_PROD__;\n\n/** @internal @security Messages may include user-supplied form field paths. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/forge] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":";AAAA,IAAM,IAAQ,CAAE,WAA4C;AAG5D,SAAgB,EAAK,GAAmB;CACtC,AAAI,KAAO,QAAQ,KAAK,qBAAqB,GAAK;AACpD;AAGA,SAAgB,EAAQ,GAAsB;CAC5C,AAAI,KAAO,EAAG;AAChB"}
package/dist/_utils.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs");require("@vielzeug/arsenal");var t=new Set([`__proto__`,`constructor`,`prototype`]);function n(e){return e.split(`.`).every(e=>!t.has(e))}function r(t){if(!n(t))throw new e.ForgeConfigError(`Unsafe key '${t}': segments __proto__, constructor, and prototype are reserved.`)}function i(e,t=200){return e.replace(/\p{C}/gu,`?`).slice(0,t)}function a(...e){let t=e.filter(e=>e!=null);if(t.length!==0)return t.length===1?t[0]:AbortSignal.any(t)}exports.anySignal=a,exports.assertSafeKey=r,exports.isSafeKey=n,exports.sanitizeForLog=i;
1
+ const e=require("./_dev.cjs"),t=require("./errors.cjs");require("@vielzeug/arsenal");var n=new Set([`__proto__`,`constructor`,`prototype`]);function r(e){return e.split(`.`).every(e=>!n.has(e))}function i(e){if(o(e),!r(e))throw new t.ForgeConfigError(`Unsafe key '${e}': segments __proto__, constructor, and prototype are reserved.`)}var a=new Set;function o(t){t.includes(`.`)&&(t.split(`.`).length<=5||a.has(t)||(a.add(t),e.devOnly(()=>{e.warn(`Path '${s(t,120)}' exceeds typed depth limits and may be treated as an untyped string path.`)})))}function s(e,t=200){return e.replace(/\p{C}/gu,`?`).slice(0,t)}function c(...e){let t=e.filter(e=>e!=null);if(t.length!==0)return t.length===1?t[0]:AbortSignal.any(t)}exports.anySignal=c,exports.assertSafeKey=i,exports.isSafeKey=r,exports.sanitizeForLog=s;
2
2
  //# sourceMappingURL=_utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"_utils.cjs","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { ForgeConfigError } from './errors';\n\nexport { flattenPaths as flattenValues, isPlainObject, unflattenPaths as unflattenValues } from '@vielzeug/arsenal';\n\nconst UNSAFE = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** Returns `true` when a dot-notation path contains no prototype-polluting segments. */\nexport function isSafeKey(path: string): boolean {\n return path.split('.').every((segment) => !UNSAFE.has(segment));\n}\n\n/** R2: Single assertion helper — replaces 5 copy-pasted guard blocks. */\nexport function assertSafeKey(key: string): void {\n if (!isSafeKey(key))\n throw new ForgeConfigError(`Unsafe key '${key}': segments __proto__, constructor, and prototype are reserved.`);\n}\n\n/**\n * Strips control characters (which could otherwise inject terminal escape sequences into\n * `console.warn` output) and caps length before interpolating caller-controlled text into a\n * dev warning. Mirrors the sanitization already applied to field keys in `warnIfArrayItemKey`.\n */\nexport function sanitizeForLog(text: string, maxLength = 200): string {\n return text.replace(/\\p{C}/gu, '?').slice(0, maxLength);\n}\n\n/**\n * Merges multiple AbortSignals into one that aborts when any of them aborts.\n * Nullish values are silently ignored.\n * Returns `undefined` when no non-null signals are provided.\n *\n * @internal Inlined here — `anySignal` was removed from `@vielzeug/arsenal`.\n */\nexport function anySignal(...signals: ReadonlyArray<AbortSignal | null | undefined>): AbortSignal | undefined {\n const active = signals.filter((s): s is AbortSignal => s != null);\n\n if (active.length === 0) return undefined;\n\n if (active.length === 1) return active[0];\n\n return AbortSignal.any(active);\n}\n"],"mappings":"6DAIA,IAAM,EAAS,IAAI,IAAI,CAAC,YAAa,cAAe,WAAW,CAAC,EAGhE,SAAgB,EAAU,EAAuB,CAC/C,OAAO,EAAK,MAAM,GAAG,CAAC,CAAC,MAAO,GAAY,CAAC,EAAO,IAAI,CAAO,CAAC,CAChE,CAGA,SAAgB,EAAc,EAAmB,CAC/C,GAAI,CAAC,EAAU,CAAG,EAChB,MAAM,IAAI,EAAA,iBAAiB,eAAe,EAAI,gEAAgE,CAClH,CAOA,SAAgB,EAAe,EAAc,EAAY,IAAa,CACpE,OAAO,EAAK,QAAQ,UAAW,GAAG,CAAC,CAAC,MAAM,EAAG,CAAS,CACxD,CASA,SAAgB,EAAU,GAAG,EAAiF,CAC5G,IAAM,EAAS,EAAQ,OAAQ,GAAwB,GAAK,IAAI,EAE5D,KAAO,SAAW,EAItB,OAFI,EAAO,SAAW,EAAU,EAAO,GAEhC,YAAY,IAAI,CAAM,CAC/B"}
1
+ {"version":3,"file":"_utils.cjs","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { devOnly, warn } from './_dev';\nimport { ForgeConfigError } from './errors';\n\nexport { flattenPaths as flattenValues, isPlainObject, unflattenPaths as unflattenValues } from '@vielzeug/arsenal';\n\nconst UNSAFE = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** Returns `true` when a dot-notation path contains no prototype-polluting segments. */\nexport function isSafeKey(path: string): boolean {\n return path.split('.').every((segment) => !UNSAFE.has(segment));\n}\n\n/** R2: Single assertion helper — replaces 5 copy-pasted guard blocks. */\nexport function assertSafeKey(key: string): void {\n warnIfDeepPathTypeFallback(key);\n\n if (!isSafeKey(key))\n throw new ForgeConfigError(`Unsafe key '${key}': segments __proto__, constructor, and prototype are reserved.`);\n}\n\nconst warnedDeepPaths = new Set<string>();\n\n/**\n * FlatKeyOf intentionally caps recursive path typing depth for TS performance.\n * Warn once per deep key in dev so callers notice when path type inference likely fell back to `string`.\n */\nfunction warnIfDeepPathTypeFallback(key: string): void {\n if (!key.includes('.')) return;\n\n const depth = key.split('.').length;\n\n if (depth <= 5 || warnedDeepPaths.has(key)) return;\n\n warnedDeepPaths.add(key);\n\n devOnly(() => {\n warn(`Path '${sanitizeForLog(key, 120)}' exceeds typed depth limits and may be treated as an untyped string path.`);\n });\n}\n\n/**\n * Strips control characters (which could otherwise inject terminal escape sequences into\n * `console.warn` output) and caps length before interpolating caller-controlled text into a\n * dev warning. Mirrors the sanitization already applied to field keys in `warnIfArrayItemKey`.\n */\nexport function sanitizeForLog(text: string, maxLength = 200): string {\n return text.replace(/\\p{C}/gu, '?').slice(0, maxLength);\n}\n\n/**\n * Merges multiple AbortSignals into one that aborts when any of them aborts.\n * Nullish values are silently ignored.\n * Returns `undefined` when no non-null signals are provided.\n *\n * @internal Inlined here — `anySignal` was removed from `@vielzeug/arsenal`.\n */\nexport function anySignal(...signals: ReadonlyArray<AbortSignal | null | undefined>): AbortSignal | undefined {\n const active = signals.filter((s): s is AbortSignal => s != null);\n\n if (active.length === 0) return undefined;\n\n if (active.length === 1) return active[0];\n\n return AbortSignal.any(active);\n}\n"],"mappings":"qFAKA,IAAM,EAAS,IAAI,IAAI,CAAC,YAAa,cAAe,WAAW,CAAC,EAGhE,SAAgB,EAAU,EAAuB,CAC/C,OAAO,EAAK,MAAM,GAAG,CAAC,CAAC,MAAO,GAAY,CAAC,EAAO,IAAI,CAAO,CAAC,CAChE,CAGA,SAAgB,EAAc,EAAmB,CAG/C,GAFA,EAA2B,CAAG,EAE1B,CAAC,EAAU,CAAG,EAChB,MAAM,IAAI,EAAA,iBAAiB,eAAe,EAAI,gEAAgE,CAClH,CAEA,IAAM,EAAkB,IAAI,IAM5B,SAAS,EAA2B,EAAmB,CAChD,EAAI,SAAS,GAAG,IAEP,EAAI,MAAM,GAAG,CAAC,CAAC,QAEhB,GAAK,EAAgB,IAAI,CAAG,IAEzC,EAAgB,IAAI,CAAG,EAEvB,EAAA,YAAc,CACZ,EAAA,KAAK,SAAS,EAAe,EAAK,GAAG,EAAE,2EAA2E,CACpH,CAAC,GACH,CAOA,SAAgB,EAAe,EAAc,EAAY,IAAa,CACpE,OAAO,EAAK,QAAQ,UAAW,GAAG,CAAC,CAAC,MAAM,EAAG,CAAS,CACxD,CASA,SAAgB,EAAU,GAAG,EAAiF,CAC5G,IAAM,EAAS,EAAQ,OAAQ,GAAwB,GAAK,IAAI,EAE5D,KAAO,SAAW,EAItB,OAFI,EAAO,SAAW,EAAU,EAAO,GAEhC,YAAY,IAAI,CAAM,CAC/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"_utils.d.ts","sourceRoot":"","sources":["../src/_utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,IAAI,aAAa,EAAE,aAAa,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpH,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAG/C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAEpE"}
1
+ {"version":3,"file":"_utils.d.ts","sourceRoot":"","sources":["../src/_utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,IAAI,aAAa,EAAE,aAAa,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpH,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAK/C;AAsBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAEpE"}
package/dist/_utils.js CHANGED
@@ -1,25 +1,32 @@
1
- import { ForgeConfigError as e } from "./errors.js";
2
- import { flattenPaths as t, unflattenPaths as n } from "@vielzeug/arsenal";
1
+ import { devOnly as e, warn as t } from "./_dev.js";
2
+ import { ForgeConfigError as n } from "./errors.js";
3
+ import { flattenPaths as r, unflattenPaths as i } from "@vielzeug/arsenal";
3
4
  //#region src/_utils.ts
4
- var r = /* @__PURE__ */ new Set([
5
+ var a = /* @__PURE__ */ new Set([
5
6
  "__proto__",
6
7
  "constructor",
7
8
  "prototype"
8
9
  ]);
9
- function i(e) {
10
- return e.split(".").every((e) => !r.has(e));
10
+ function o(e) {
11
+ return e.split(".").every((e) => !a.has(e));
11
12
  }
12
- function a(t) {
13
- if (!i(t)) throw new e(`Unsafe key '${t}': segments __proto__, constructor, and prototype are reserved.`);
13
+ function s(e) {
14
+ if (l(e), !o(e)) throw new n(`Unsafe key '${e}': segments __proto__, constructor, and prototype are reserved.`);
14
15
  }
15
- function o(e, t = 200) {
16
+ var c = /* @__PURE__ */ new Set();
17
+ function l(n) {
18
+ n.includes(".") && (n.split(".").length <= 5 || c.has(n) || (c.add(n), e(() => {
19
+ t(`Path '${u(n, 120)}' exceeds typed depth limits and may be treated as an untyped string path.`);
20
+ })));
21
+ }
22
+ function u(e, t = 200) {
16
23
  return e.replace(/\p{C}/gu, "?").slice(0, t);
17
24
  }
18
- function s(...e) {
25
+ function d(...e) {
19
26
  let t = e.filter((e) => e != null);
20
27
  if (t.length !== 0) return t.length === 1 ? t[0] : AbortSignal.any(t);
21
28
  }
22
29
  //#endregion
23
- export { s as anySignal, a as assertSafeKey, t as flattenValues, i as isSafeKey, o as sanitizeForLog, n as unflattenValues };
30
+ export { d as anySignal, s as assertSafeKey, r as flattenValues, o as isSafeKey, u as sanitizeForLog, i as unflattenValues };
24
31
 
25
32
  //# sourceMappingURL=_utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_utils.js","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { ForgeConfigError } from './errors';\n\nexport { flattenPaths as flattenValues, isPlainObject, unflattenPaths as unflattenValues } from '@vielzeug/arsenal';\n\nconst UNSAFE = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** Returns `true` when a dot-notation path contains no prototype-polluting segments. */\nexport function isSafeKey(path: string): boolean {\n return path.split('.').every((segment) => !UNSAFE.has(segment));\n}\n\n/** R2: Single assertion helper — replaces 5 copy-pasted guard blocks. */\nexport function assertSafeKey(key: string): void {\n if (!isSafeKey(key))\n throw new ForgeConfigError(`Unsafe key '${key}': segments __proto__, constructor, and prototype are reserved.`);\n}\n\n/**\n * Strips control characters (which could otherwise inject terminal escape sequences into\n * `console.warn` output) and caps length before interpolating caller-controlled text into a\n * dev warning. Mirrors the sanitization already applied to field keys in `warnIfArrayItemKey`.\n */\nexport function sanitizeForLog(text: string, maxLength = 200): string {\n return text.replace(/\\p{C}/gu, '?').slice(0, maxLength);\n}\n\n/**\n * Merges multiple AbortSignals into one that aborts when any of them aborts.\n * Nullish values are silently ignored.\n * Returns `undefined` when no non-null signals are provided.\n *\n * @internal Inlined here — `anySignal` was removed from `@vielzeug/arsenal`.\n */\nexport function anySignal(...signals: ReadonlyArray<AbortSignal | null | undefined>): AbortSignal | undefined {\n const active = signals.filter((s): s is AbortSignal => s != null);\n\n if (active.length === 0) return undefined;\n\n if (active.length === 1) return active[0];\n\n return AbortSignal.any(active);\n}\n"],"mappings":";;;AAIA,IAAM,oBAAS,IAAI,IAAI;CAAC;CAAa;CAAe;AAAW,CAAC;AAGhE,SAAgB,EAAU,GAAuB;CAC/C,OAAO,EAAK,MAAM,GAAG,CAAC,CAAC,OAAO,MAAY,CAAC,EAAO,IAAI,CAAO,CAAC;AAChE;AAGA,SAAgB,EAAc,GAAmB;CAC/C,IAAI,CAAC,EAAU,CAAG,GAChB,MAAM,IAAI,EAAiB,eAAe,EAAI,gEAAgE;AAClH;AAOA,SAAgB,EAAe,GAAc,IAAY,KAAa;CACpE,OAAO,EAAK,QAAQ,WAAW,GAAG,CAAC,CAAC,MAAM,GAAG,CAAS;AACxD;AASA,SAAgB,EAAU,GAAG,GAAiF;CAC5G,IAAM,IAAS,EAAQ,QAAQ,MAAwB,KAAK,IAAI;CAE5D,MAAO,WAAW,GAItB,OAFI,EAAO,WAAW,IAAU,EAAO,KAEhC,YAAY,IAAI,CAAM;AAC/B"}
1
+ {"version":3,"file":"_utils.js","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { devOnly, warn } from './_dev';\nimport { ForgeConfigError } from './errors';\n\nexport { flattenPaths as flattenValues, isPlainObject, unflattenPaths as unflattenValues } from '@vielzeug/arsenal';\n\nconst UNSAFE = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** Returns `true` when a dot-notation path contains no prototype-polluting segments. */\nexport function isSafeKey(path: string): boolean {\n return path.split('.').every((segment) => !UNSAFE.has(segment));\n}\n\n/** R2: Single assertion helper — replaces 5 copy-pasted guard blocks. */\nexport function assertSafeKey(key: string): void {\n warnIfDeepPathTypeFallback(key);\n\n if (!isSafeKey(key))\n throw new ForgeConfigError(`Unsafe key '${key}': segments __proto__, constructor, and prototype are reserved.`);\n}\n\nconst warnedDeepPaths = new Set<string>();\n\n/**\n * FlatKeyOf intentionally caps recursive path typing depth for TS performance.\n * Warn once per deep key in dev so callers notice when path type inference likely fell back to `string`.\n */\nfunction warnIfDeepPathTypeFallback(key: string): void {\n if (!key.includes('.')) return;\n\n const depth = key.split('.').length;\n\n if (depth <= 5 || warnedDeepPaths.has(key)) return;\n\n warnedDeepPaths.add(key);\n\n devOnly(() => {\n warn(`Path '${sanitizeForLog(key, 120)}' exceeds typed depth limits and may be treated as an untyped string path.`);\n });\n}\n\n/**\n * Strips control characters (which could otherwise inject terminal escape sequences into\n * `console.warn` output) and caps length before interpolating caller-controlled text into a\n * dev warning. Mirrors the sanitization already applied to field keys in `warnIfArrayItemKey`.\n */\nexport function sanitizeForLog(text: string, maxLength = 200): string {\n return text.replace(/\\p{C}/gu, '?').slice(0, maxLength);\n}\n\n/**\n * Merges multiple AbortSignals into one that aborts when any of them aborts.\n * Nullish values are silently ignored.\n * Returns `undefined` when no non-null signals are provided.\n *\n * @internal Inlined here — `anySignal` was removed from `@vielzeug/arsenal`.\n */\nexport function anySignal(...signals: ReadonlyArray<AbortSignal | null | undefined>): AbortSignal | undefined {\n const active = signals.filter((s): s is AbortSignal => s != null);\n\n if (active.length === 0) return undefined;\n\n if (active.length === 1) return active[0];\n\n return AbortSignal.any(active);\n}\n"],"mappings":";;;;AAKA,IAAM,oBAAS,IAAI,IAAI;CAAC;CAAa;CAAe;AAAW,CAAC;AAGhE,SAAgB,EAAU,GAAuB;CAC/C,OAAO,EAAK,MAAM,GAAG,CAAC,CAAC,OAAO,MAAY,CAAC,EAAO,IAAI,CAAO,CAAC;AAChE;AAGA,SAAgB,EAAc,GAAmB;CAG/C,IAFA,EAA2B,CAAG,GAE1B,CAAC,EAAU,CAAG,GAChB,MAAM,IAAI,EAAiB,eAAe,EAAI,gEAAgE;AAClH;AAEA,IAAM,oBAAkB,IAAI,IAAY;AAMxC,SAAS,EAA2B,GAAmB;CAChD,EAAI,SAAS,GAAG,MAEP,EAAI,MAAM,GAAG,CAAC,CAAC,UAEhB,KAAK,EAAgB,IAAI,CAAG,MAEzC,EAAgB,IAAI,CAAG,GAEvB,QAAc;EACZ,EAAK,SAAS,EAAe,GAAK,GAAG,EAAE,2EAA2E;CACpH,CAAC;AACH;AAOA,SAAgB,EAAe,GAAc,IAAY,KAAa;CACpE,OAAO,EAAK,QAAQ,WAAW,GAAG,CAAC,CAAC,MAAM,GAAG,CAAS;AACxD;AASA,SAAgB,EAAU,GAAG,GAAiF;CAC5G,IAAM,IAAS,EAAQ,QAAQ,MAAwB,KAAK,IAAI;CAE5D,MAAO,WAAW,GAItB,OAFI,EAAO,WAAW,IAAU,EAAO,KAEhC,YAAY,IAAI,CAAM;AAC/B"}
@@ -1,2 +1,2 @@
1
- const e=require("../errors.cjs");require("../_utils.cjs");let t=require("@vielzeug/arsenal");function n(r,i){let a=`${i}.`;function o(e){return`${i}.${e}`}function s(e){return e===i||e.startsWith(a)}function c(e){return e.startsWith(a)?e.slice(a.length):e}function l(){let e=r.getStateSnapshot(),t=Object.fromEntries(Object.entries(e.errors).filter(([e])=>s(e)).map(([e,t])=>[c(e),t])),n=e.touchedFields.filter(s).map(c),i=e.validatingFields.filter(s).map(c),a=Object.keys(t).length===0,o=[...r.dirty].some(s),l=[...r.touched].some(s),u=i.length>0;return Object.freeze({errors:Object.freeze(t),isDirty:o,isLoading:e.isLoading,isSubmitting:e.isSubmitting,isTouched:l,isValid:a,isValidating:u,submitCount:e.submitCount,touchedFields:Object.freeze(n),validatingFields:Object.freeze(i)})}function u(){let e={};for(let[t,n]of r.store)t.startsWith(a)&&(e[t.slice(a.length)]=n);return(0,t.unflattenPaths)(e)}function d(){let e=new Set;for(let t of r.store.keys())s(t)&&e.add(c(t));for(let t of r.validators.keys())s(t)&&e.add(c(t));return Object.freeze([...e])}function f(){r.ensureNotDisposed();for(let e of r.store.keys())s(e)&&r.touched.add(e);for(let e of r.validators.keys())s(e)&&r.touched.add(e);r.requestNotify()}function p(){r.ensureNotDisposed();for(let e of[...r.touched])s(e)&&r.touched.delete(e);r.requestNotify()}function m(){r.ensureNotDisposed();for(let e of[...r.store.keys()])s(e)&&(r.fieldCtrls.get(e)?.abort(),r.fieldCtrls.delete(e),r.store.set(e,r.baseline.get(e)),r.dirty.delete(e),r.touched.delete(e),r.fieldErrors.delete(e)&&r.invalidateErrors());r.requestNotify()}function h(e){r.ensureNotDisposed();for(let e of[...r.fieldCtrls.keys()])s(e)&&(r.fieldCtrls.get(e)?.abort(),r.fieldCtrls.delete(e));let n=(0,t.flattenPaths)(e);for(let e of[...r.store.keys()])s(e)&&(r.store.delete(e),r.baseline.delete(e),r.dirty.delete(e),r.touched.delete(e),r.fieldErrors.delete(e));r.invalidateErrors();for(let[e,t]of Object.entries(n)){let n=o(e);r.store.set(n,t),r.baseline.set(n,t)}r.requestNotify()}function g(e){r.ensureNotDisposed();let n=(0,t.flattenPaths)(e),i=[];for(let[e,t]of Object.entries(n)){let n=o(e);r.baseline.set(n,t),r.store.set(n,t),r.dirty.delete(n),i.push(n)}r.requestNotify(i)}function _(e){r.ensureNotDisposed();for(let e of[...r.fieldErrors.keys()])s(e)&&r.fieldErrors.delete(e);if(e)for(let[t,n]of Object.entries(e))typeof n==`string`&&r.fieldErrors.set(o(t),n);r.invalidateErrors(),r.requestNotify()}async function v(e,t){if(r.ensureNotDisposed(),e!==void 0&&!Array.isArray(e)&&!(e instanceof AbortSignal)){let n=o(e);await r.runValidationCore([n],`partial`,t);let i=r.fieldErrors.get(n);return{errors:i===void 0?{}:{[e]:i},valid:i===void 0}}if(Array.isArray(e)){let n=e.map(e=>o(e));await r.runValidationCore(n,`partial`,t);let i={};for(let e of n){let t=r.fieldErrors.get(e);t!==void 0&&(i[c(e)]=t)}return{errors:i,valid:Object.keys(i).length===0}}let n=e,i=[...r.validators.keys()].filter(s);await r.runValidationCore(i,`partial`,n);let a={};for(let[e,t]of r.fieldErrors)s(e)&&(a[c(e)]=t);return{errors:a,valid:Object.keys(a).length===0}}async function y(t){if(r.ensureNotDisposed(),r.isSubmitting())throw new e.ForgeSubmitError(`submit() called while a submission is already in progress`);r.root.batch(()=>{r.incrementSubmitCount(),r.setSubmitting(!0),f()});try{let e=[...r.validators.keys()].filter(s);await r.runValidationCore(e,`partial`),r.ensureNotDisposed();let n={};for(let[e,t]of r.fieldErrors)s(e)&&(n[c(e)]=t);return Object.keys(n).length>0?{errors:n,ok:!1,type:`validation`}:{ok:!0,value:await t(u())}}finally{r.setSubmitting(!1),r.isDisposed()||r.requestNotify()}}function b(e,t){let n=null;return r.root.subscribe(()=>{let t=l();if(n){let e=n,r=Object.keys(t.errors),i=Object.keys(e.errors),a=r.length===i.length&&r.every(n=>t.errors[n]===e.errors[n]),o=t.touchedFields.length===e.touchedFields.length&&t.touchedFields.every((t,n)=>t===e.touchedFields[n]),s=t.validatingFields.length===e.validatingFields.length&&t.validatingFields.every((t,n)=>t===e.validatingFields[n]);if(t.isDirty===e.isDirty&&t.isLoading===e.isLoading&&t.isSubmitting===e.isSubmitting&&t.isTouched===e.isTouched&&t.isValid===e.isValid&&t.isValidating===e.isValidating&&t.submitCount===e.submitCount&&a&&o&&s)return}n=t,e(t)},t)}return{array:e=>r.root.array(o(e)),batch:e=>r.root.batch(e),clearError:e=>r.root.clearError(o(e)),connect:(e,t)=>r.root.connect(o(e),t),get disposalSignal(){return r.root.disposalSignal},dispose:()=>{},get disposed(){return r.isDisposed()},field:e=>r.root.field(o(e)),fields:{list:d,register:(e,t)=>r.root.fields.register(o(e),t),remove:e=>r.root.fields.remove(o(e)),setValidator:(e,t)=>r.root.fields.setValidator(o(e),t)},get:e=>r.root.get(o(e)),get isLoading(){return r.root.isLoading},get isSubmitting(){return r.root.isSubmitting},patch:g,replace:h,reset:m,resetErrors:_,resetField:e=>r.root.resetField(o(e)),restore:e=>r.root.restore(e),scope:e=>n(r,o(e)),set:(e,t,n)=>r.root.set(o(e),t,n),setError:(e,t)=>r.root.setError(o(e),t),snapshot:()=>r.root.snapshot(),get state(){return l()},submit:y,submitOrThrow:async t=>{let n=await y(t);if(!n.ok)throw new e.ForgeValidationError(n.errors);return n.value},subscribe:(e,t)=>r.root.subscribe(e,t),subscribeField:(e,t,n)=>r.root.subscribeField(o(e),t,n),subscribeScoped:b,[Symbol.asyncIterator]:()=>r.root[Symbol.asyncIterator](),[Symbol.dispose](){this.dispose()},touch:e=>r.root.touch(o(e)),touchAll:f,untouch:e=>r.root.untouch(o(e)),untouchAll:p,validate:v,validateStream(e){let t=r.root.validateStream(e);return{async next(){for(;;){let e=await t.next();if(e.done)return e;if(s(e.value.field))return{done:!1,value:{error:e.value.error,field:c(e.value.field)}}}},return(){return t.return?t.return():Promise.resolve({done:!0,value:void 0})},[Symbol.asyncIterator](){return this}}},values:u}}exports.createScopedForm=n;
1
+ const e=require("../errors.cjs");require("../_utils.cjs");let t=require("@vielzeug/arsenal");function n(r,i){let a=`${i}.`;function o(e){return`${i}.${e}`}function s(e){return e===i||e.startsWith(a)}function c(e){return e.startsWith(a)?e.slice(a.length):e}function l(){let e=r.getStateSnapshot(),t=Object.fromEntries(Object.entries(e.errors).filter(([e])=>s(e)).map(([e,t])=>[c(e),t])),n=e.touchedFields.filter(s).map(c),i=e.validatingFields.filter(s).map(c),a=Object.keys(t).length===0,o=[...r.dirty].some(s),l=[...r.touched].some(s),u=i.length>0;return Object.freeze({errors:Object.freeze(t),isDirty:o,isLoading:e.isLoading,isSubmitting:e.isSubmitting,isTouched:l,isValid:a,isValidating:u,submitCount:e.submitCount,touchedFields:Object.freeze(n),validatingFields:Object.freeze(i)})}function u(){let e={};for(let[t,n]of r.store)t.startsWith(a)&&(e[t.slice(a.length)]=n);return(0,t.unflattenPaths)(e)}function d(){let e=new Set;for(let t of r.store.keys())s(t)&&e.add(c(t));for(let t of r.validators.keys())s(t)&&e.add(c(t));return Object.freeze([...e])}function f(){r.ensureNotDisposed();for(let e of r.store.keys())s(e)&&r.touched.add(e);for(let e of r.validators.keys())s(e)&&r.touched.add(e);r.requestNotify()}function p(){r.ensureNotDisposed();for(let e of[...r.touched])s(e)&&r.touched.delete(e);r.requestNotify()}function m(){r.ensureNotDisposed();for(let e of[...r.store.keys()])s(e)&&(r.fieldCtrls.get(e)?.abort(),r.fieldCtrls.delete(e),r.store.set(e,r.baseline.get(e)),r.dirty.delete(e),r.touched.delete(e),r.fieldErrors.delete(e)&&r.invalidateErrors());r.requestNotify()}function h(e){r.ensureNotDisposed();for(let e of[...r.fieldCtrls.keys()])s(e)&&(r.fieldCtrls.get(e)?.abort(),r.fieldCtrls.delete(e));let n=(0,t.flattenPaths)(e);for(let e of[...r.store.keys()])s(e)&&(r.store.delete(e),r.baseline.delete(e),r.dirty.delete(e),r.touched.delete(e),r.fieldErrors.delete(e));r.invalidateErrors();for(let[e,t]of Object.entries(n)){let n=o(e);r.store.set(n,t),r.baseline.set(n,t)}r.requestNotify()}function g(e){r.ensureNotDisposed();let n=(0,t.flattenPaths)(e),i=[];for(let[e,t]of Object.entries(n)){let n=o(e);r.baseline.set(n,t),r.store.set(n,t),r.dirty.delete(n),i.push(n)}r.requestNotify(i)}function _(e){r.ensureNotDisposed();for(let e of[...r.fieldErrors.keys()])s(e)&&r.fieldErrors.delete(e);if(e)for(let[t,n]of Object.entries(e))typeof n==`string`&&r.fieldErrors.set(o(t),n);r.invalidateErrors(),r.requestNotify()}async function v(e,t){if(r.ensureNotDisposed(),e!==void 0&&!Array.isArray(e)&&!(e instanceof AbortSignal)){let n=o(e);await r.runValidationCore([n],`partial`,t);let i=r.fieldErrors.get(n);return{errors:i===void 0?{}:{[e]:i},valid:i===void 0}}if(Array.isArray(e)){let n=e.map(e=>o(e));await r.runValidationCore(n,`partial`,t);let i={};for(let e of n){let t=r.fieldErrors.get(e);t!==void 0&&(i[c(e)]=t)}return{errors:i,valid:Object.keys(i).length===0}}let n=e,i=[...r.validators.keys()].filter(s);await r.runValidationCore(i,`partial`,n);let a={};for(let[e,t]of r.fieldErrors)s(e)&&(a[c(e)]=t);return{errors:a,valid:Object.keys(a).length===0}}async function y(t){if(r.ensureNotDisposed(),r.isSubmitting())throw new e.ForgeSubmitError(`submit() called while a submission is already in progress`);r.root.batch(()=>{r.incrementSubmitCount(),r.setSubmitting(!0),f()});try{let e=[...r.validators.keys()].filter(s);await r.runValidationCore(e,`partial`),r.ensureNotDisposed();let n={};for(let[e,t]of r.fieldErrors)s(e)&&(n[c(e)]=t);return Object.keys(n).length>0?{errors:n,ok:!1,type:`validation`}:{ok:!0,value:await t(u())}}finally{r.setSubmitting(!1),r.isDisposed()||r.requestNotify()}}function b(e,t){let n=null;return r.root.subscribe(()=>{let t=l();if(n){let e=n,r=Object.keys(t.errors),i=Object.keys(e.errors),a=r.length===i.length&&r.every(n=>t.errors[n]===e.errors[n]),o=t.touchedFields.length===e.touchedFields.length&&t.touchedFields.every((t,n)=>t===e.touchedFields[n]),s=t.validatingFields.length===e.validatingFields.length&&t.validatingFields.every((t,n)=>t===e.validatingFields[n]);if(t.isDirty===e.isDirty&&t.isLoading===e.isLoading&&t.isSubmitting===e.isSubmitting&&t.isTouched===e.isTouched&&t.isValid===e.isValid&&t.isValidating===e.isValidating&&t.submitCount===e.submitCount&&a&&o&&s)return}n=t,e(t)},t)}function x(){return{array(e){return r.root.array(o(e))},clearError(e){r.root.clearError(o(e))},connect(e,t){return r.root.connect(o(e),t)},field(e){return r.root.field(o(e))},get(e){return r.root.get(o(e))},register(e,t){return r.root.fields.register(o(e),t)},remove(e){r.root.fields.remove(o(e))},resetField(e){r.root.resetField(o(e))},set(e,t,n){r.root.set(o(e),t,n)},setError(e,t){r.root.setError(o(e),t)},setValidator(e,t){r.root.fields.setValidator(o(e),t)},subscribeField(e,t,n){return r.root.subscribeField(o(e),t,n)},touch(e){r.root.touch(o(e))},untouch(e){r.root.untouch(o(e))}}}let S=x();return{array:e=>S.array(e),batch:e=>r.root.batch(e),clearError:e=>S.clearError(e),connect:(e,t)=>S.connect(e,t),get disposalSignal(){return r.root.disposalSignal},dispose:()=>{},get disposed(){return r.isDisposed()},field:e=>S.field(e),fields:{list:d,register:(e,t)=>S.register(e,t),remove:e=>S.remove(e),setValidator:(e,t)=>S.setValidator(e,t)},get:e=>S.get(e),get isLoading(){return r.root.isLoading},get isSubmitting(){return r.root.isSubmitting},patch:g,replace:h,reset:m,resetErrors:_,resetField:e=>S.resetField(e),restore:e=>r.root.restore(e),scope:e=>n(r,o(e)),set:(e,t,n)=>S.set(e,t,n),setError:(e,t)=>S.setError(e,t),snapshot:()=>r.root.snapshot(),get state(){return l()},submit:y,submitOrThrow:async t=>{let n=await y(t);if(!n.ok)throw new e.ForgeValidationError(n.errors);return n.value},subscribe:(e,t)=>r.root.subscribe(e,t),subscribeField:(e,t,n)=>S.subscribeField(e,t,n),subscribeScoped:b,[Symbol.asyncIterator]:()=>r.root[Symbol.asyncIterator](),[Symbol.dispose](){this.dispose()},touch:e=>S.touch(e),touchAll:f,untouch:e=>S.untouch(e),untouchAll:p,validate:v,validateStream(e){let t=r.root.validateStream(e);return{async next(){for(;;){let e=await t.next();if(e.done)return e;if(s(e.value.field))return{done:!1,value:{error:e.value.error,field:c(e.value.field)}}}},return(){return t.return?t.return():Promise.resolve({done:!0,value:void 0})},[Symbol.asyncIterator](){return this}}},values:u}}exports.createScopedForm=n;
2
2
  //# sourceMappingURL=scope.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.cjs","names":[],"sources":["../../src/core/scope.ts"],"sourcesContent":["import type {\n ArrayField,\n ConnectionResult,\n ErrorKeyOf,\n FieldState,\n FieldValidator,\n FlatKeyOf,\n Form,\n FormSnapshot,\n FormState,\n MaybePromise,\n RegisterFieldOptions,\n ScopedValues,\n SetOptions,\n SubmitResult,\n SubscribeOptions,\n TypeAtPath,\n Unsubscribe,\n ValidateResult,\n} from '../types';\n\nimport { flattenValues, unflattenValues } from '../_utils';\nimport { ForgeSubmitError, ForgeValidationError } from '../errors';\n\n/**\n * R3: Slim ScopeContext — delegates simple operations through `root: Form<TValues>`.\n * Only the Maps/Sets needed for bulk scoped operations are passed directly.\n * @internal\n */\nexport interface ScopeContext<TValues extends Record<string, unknown> = Record<string, unknown>> {\n /** The fully-featured root form — used for all simple one-field delegations. */\n root: Form<TValues>;\n\n /* ---- Shared mutable state (passed by reference, needed by bulk scoped ops) ---- */\n store: Map<string, unknown>;\n baseline: Map<string, unknown>;\n validators: Map<string, FieldValidator<unknown>>;\n fieldErrors: Map<string, string>;\n touched: Set<string>;\n dirty: Set<string>;\n fieldCtrls: Map<string, AbortController>;\n\n /* ---- Scalar state accessors ---- */\n isSubmitting(): boolean;\n setSubmitting(value: boolean): void;\n incrementSubmitCount(): void;\n isDisposed(): boolean;\n\n /* ---- Core helpers ---- */\n ensureNotDisposed(): void;\n invalidateErrors(): void;\n requestNotify(target?: string | Iterable<string>): void;\n getStateSnapshot(): FormState;\n\n /* ---- Validation core (needed for scoped validate/submit) ---- */\n runValidationCore(\n fields: string[],\n scope: 'full' | 'partial',\n signal?: AbortSignal,\n ): Promise<ValidateResult & { aborted: boolean }>;\n}\n\n/**\n * Creates a scoped sub-form whose field paths are relative to `pfx`.\n * All simple single-field operations delegate to `ctx.root`.\n * Only prefix-aware bulk operations (submit, validate, replace, reset, etc.) contain custom code.\n */\nexport function createScopedForm<TValues extends Record<string, unknown>, P extends string>(\n ctx: ScopeContext<TValues>,\n pfx: P,\n): Form<ScopedValues<TValues, P>> {\n const pfxDot = `${pfx}.`;\n\n function pre(name: string): string {\n return `${pfx}.${name}`;\n }\n\n function isScopedKey(key: string): boolean {\n return key === pfx || key.startsWith(pfxDot);\n }\n\n function unscope(key: string): string {\n return key.startsWith(pfxDot) ? key.slice(pfxDot.length) : key;\n }\n\n /* ---- Non-trivial scoped implementations ---- */\n\n /**\n * Compute a scoped projection of FormState from current raw Maps.\n * Errors, touchedFields, validatingFields, isValid, isDirty, isTouched reflect only\n * fields within the prefix. isSubmitting, isLoading, isValidating, submitCount are full-form.\n */\n function getScopedState(): FormState {\n const rootState = ctx.getStateSnapshot();\n const errors = Object.fromEntries(\n Object.entries(rootState.errors)\n .filter(([k]) => isScopedKey(k))\n .map(([k, v]) => [unscope(k), v]),\n );\n const touchedFields = rootState.touchedFields.filter(isScopedKey).map(unscope);\n const validatingFields = rootState.validatingFields.filter(isScopedKey).map(unscope);\n const isValid = Object.keys(errors).length === 0;\n const isDirty = [...ctx.dirty].some(isScopedKey);\n const isTouched = [...ctx.touched].some(isScopedKey);\n const isValidating = validatingFields.length > 0;\n\n return Object.freeze({\n errors: Object.freeze(errors) as FormState['errors'],\n isDirty,\n isLoading: rootState.isLoading,\n isSubmitting: rootState.isSubmitting,\n isTouched,\n isValid,\n isValidating,\n submitCount: rootState.submitCount,\n touchedFields: Object.freeze(touchedFields) as readonly string[],\n validatingFields: Object.freeze(validatingFields) as readonly string[],\n });\n }\n\n function scopedValues(): ScopedValues<TValues, P> {\n const sub: Record<string, unknown> = {};\n\n for (const [key, value] of ctx.store) {\n if (key.startsWith(pfxDot)) sub[key.slice(pfxDot.length)] = value;\n }\n\n return unflattenValues(sub) as ScopedValues<TValues, P>;\n }\n\n /**\n * Enumerate field paths within this scope's prefix, stripped to relative paths —\n * matching `scope.state`'s relative-path convention, not `state.touchedFields`'s\n * absolute-path convention. Same \"known field\" definition `scopedTouchAll()` uses.\n */\n function scopedListFields(): readonly string[] {\n const known = new Set<string>();\n\n for (const key of ctx.store.keys()) {\n if (isScopedKey(key)) known.add(unscope(key));\n }\n\n for (const key of ctx.validators.keys()) {\n if (isScopedKey(key)) known.add(unscope(key));\n }\n\n return Object.freeze([...known]);\n }\n\n function scopedTouchAll(): void {\n ctx.ensureNotDisposed();\n\n for (const name of ctx.store.keys()) {\n if (isScopedKey(name)) ctx.touched.add(name);\n }\n\n for (const name of ctx.validators.keys()) {\n if (isScopedKey(name)) ctx.touched.add(name);\n }\n\n ctx.requestNotify();\n }\n\n function scopedUntouchAll(): void {\n ctx.ensureNotDisposed();\n\n for (const name of [...ctx.touched]) {\n if (isScopedKey(name)) ctx.touched.delete(name);\n }\n\n ctx.requestNotify();\n }\n\n function scopedReset(): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.store.keys()]) {\n if (!isScopedKey(key)) continue;\n\n ctx.fieldCtrls.get(key)?.abort();\n ctx.fieldCtrls.delete(key);\n ctx.store.set(key, ctx.baseline.get(key));\n ctx.dirty.delete(key);\n ctx.touched.delete(key);\n\n if (ctx.fieldErrors.delete(key)) ctx.invalidateErrors();\n }\n\n ctx.requestNotify();\n }\n\n function scopedReplace(newValues: ScopedValues<TValues, P>): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.fieldCtrls.keys()]) {\n if (isScopedKey(key)) {\n ctx.fieldCtrls.get(key)?.abort();\n ctx.fieldCtrls.delete(key);\n }\n }\n\n const flat = flattenValues(newValues as Record<string, unknown>);\n\n for (const key of [...ctx.store.keys()]) {\n if (!isScopedKey(key)) continue;\n\n ctx.store.delete(key);\n ctx.baseline.delete(key);\n ctx.dirty.delete(key);\n ctx.touched.delete(key);\n ctx.fieldErrors.delete(key);\n }\n\n ctx.invalidateErrors();\n\n for (const [key, value] of Object.entries(flat)) {\n const full = pre(key);\n\n ctx.store.set(full, value);\n ctx.baseline.set(full, value);\n }\n\n ctx.requestNotify();\n }\n\n function scopedPatch(partial: Record<string, unknown>): void {\n ctx.ensureNotDisposed();\n\n const flat = flattenValues(partial);\n const changedKeys: string[] = [];\n\n for (const [key, value] of Object.entries(flat)) {\n const full = pre(key);\n\n ctx.baseline.set(full, value);\n ctx.store.set(full, value);\n ctx.dirty.delete(full);\n changedKeys.push(full);\n }\n\n ctx.requestNotify(changedKeys);\n }\n\n function scopedResetErrors(\n nextErrors?: Partial<Record<ErrorKeyOf<ScopedValues<TValues, P>>, string | undefined>>,\n ): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.fieldErrors.keys()]) {\n if (isScopedKey(key)) ctx.fieldErrors.delete(key);\n }\n\n if (nextErrors) {\n for (const [key, message] of Object.entries(nextErrors)) {\n if (typeof message === 'string') ctx.fieldErrors.set(pre(key), message);\n }\n }\n\n ctx.invalidateErrors();\n ctx.requestNotify();\n }\n\n async function scopedValidate(\n nameOrFieldsOrSignal?: FlatKeyOf<ScopedValues<TValues, P>> | FlatKeyOf<ScopedValues<TValues, P>>[] | AbortSignal,\n signal?: AbortSignal,\n ): Promise<ValidateResult> {\n ctx.ensureNotDisposed();\n\n if (\n nameOrFieldsOrSignal !== undefined &&\n !Array.isArray(nameOrFieldsOrSignal) &&\n !(nameOrFieldsOrSignal instanceof AbortSignal)\n ) {\n // validate(name) — single field\n const prefixedName = pre(nameOrFieldsOrSignal as string) as FlatKeyOf<TValues>;\n\n await ctx.runValidationCore([prefixedName as string], 'partial', signal);\n\n const error = ctx.fieldErrors.get(prefixedName as string);\n\n return {\n errors: error !== undefined ? { [nameOrFieldsOrSignal as string]: error } : {},\n valid: error === undefined,\n };\n }\n\n if (Array.isArray(nameOrFieldsOrSignal)) {\n // validate(fields[]) — specific subset\n const prefixedFields = nameOrFieldsOrSignal.map((f) => pre(f as string)) as string[];\n\n await ctx.runValidationCore(prefixedFields, 'partial', signal);\n\n const errors: Record<string, string> = {};\n\n for (const pf of prefixedFields) {\n const msg = ctx.fieldErrors.get(pf);\n\n if (msg !== undefined) errors[unscope(pf)] = msg;\n }\n\n return { errors, valid: Object.keys(errors).length === 0 };\n }\n\n // validate(signal?) — all scoped fields\n const sig = nameOrFieldsOrSignal as AbortSignal | undefined;\n const fields = [...ctx.validators.keys()].filter(isScopedKey);\n\n await ctx.runValidationCore(fields, 'partial', sig);\n\n const errors: Record<string, string> = {};\n\n for (const [key, message] of ctx.fieldErrors) {\n if (isScopedKey(key)) errors[unscope(key)] = message;\n }\n\n return { errors, valid: Object.keys(errors).length === 0 };\n }\n\n async function scopedSubmit<TResult>(\n handler: (values: ScopedValues<TValues, P>) => MaybePromise<TResult>,\n ): Promise<SubmitResult<TResult>> {\n ctx.ensureNotDisposed();\n\n if (ctx.isSubmitting()) throw new ForgeSubmitError('submit() called while a submission is already in progress');\n\n ctx.root.batch(() => {\n ctx.incrementSubmitCount();\n ctx.setSubmitting(true);\n scopedTouchAll();\n });\n\n try {\n const fields = [...ctx.validators.keys()].filter(isScopedKey);\n\n await ctx.runValidationCore(fields, 'partial');\n\n ctx.ensureNotDisposed();\n\n const errors: Record<string, string> = {};\n\n for (const [key, message] of ctx.fieldErrors) {\n if (isScopedKey(key)) errors[unscope(key)] = message;\n }\n\n if (Object.keys(errors).length > 0) {\n return { errors, ok: false, type: 'validation' as const };\n }\n\n return { ok: true as const, value: await handler(scopedValues()) };\n } finally {\n ctx.setSubmitting(false);\n\n if (!ctx.isDisposed()) ctx.requestNotify();\n }\n }\n\n /**\n * Subscribe filtered to scoped fields only.\n * Errors, touchedFields, and validatingFields are remapped to relative paths.\n * `isValid`, `isDirty`, and `isTouched` reflect only fields within this scope's prefix.\n * `isSubmitting`, `isLoading`, `isValidating`, and `submitCount` reflect the full form.\n *\n * The listener fires only when the scoped projection changes — mutations outside this\n * prefix do not fire the listener.\n */\n function subscribeScoped(listener: (state: FormState) => void, options?: SubscribeOptions): Unsubscribe {\n // Track the previous scoped projection for equality comparison.\n let prevState: FormState | null = null;\n\n return ctx.root.subscribe(() => {\n const next = getScopedState();\n\n // Skip if no scoped-relevant state has changed.\n if (prevState) {\n const p = prevState;\n const errKeys = Object.keys(next.errors);\n const prevErrKeys = Object.keys(p.errors);\n const errorsMatch =\n errKeys.length === prevErrKeys.length && errKeys.every((k) => next.errors[k] === p.errors[k]);\n\n const touchedMatch =\n next.touchedFields.length === p.touchedFields.length &&\n next.touchedFields.every((v, i) => v === p.touchedFields[i]);\n\n const validatingMatch =\n next.validatingFields.length === p.validatingFields.length &&\n next.validatingFields.every((v, i) => v === p.validatingFields[i]);\n\n const flagsMatch =\n next.isDirty === p.isDirty &&\n next.isLoading === p.isLoading &&\n next.isSubmitting === p.isSubmitting &&\n next.isTouched === p.isTouched &&\n next.isValid === p.isValid &&\n next.isValidating === p.isValidating &&\n next.submitCount === p.submitCount;\n\n if (flagsMatch && errorsMatch && touchedMatch && validatingMatch) return;\n }\n\n prevState = next;\n listener(next);\n }, options);\n }\n\n /* ---- Public scoped form object ---- */\n\n type S = ScopedValues<TValues, P>;\n\n return {\n array: (name) =>\n ctx.root.array(pre(name as string) as FlatKeyOf<TValues>) as ArrayField<\n TypeAtPath<S, typeof name> extends readonly (infer E)[] ? E : unknown\n >,\n batch: (fn) => ctx.root.batch(fn),\n clearError: (name) => ctx.root.clearError(pre(name as string) as ErrorKeyOf<TValues>),\n connect: (name, config?) =>\n ctx.root.connect(pre(name as string) as FlatKeyOf<TValues>, config) as ConnectionResult<\n TypeAtPath<S, typeof name>\n >,\n get disposalSignal() {\n return ctx.root.disposalSignal;\n },\n dispose: () => {\n /* Scoped forms share lifecycle with parent — call parentForm.dispose() to tear down */\n },\n get disposed() {\n return ctx.isDisposed();\n },\n field: (name) =>\n ctx.root.field(pre(name as string) as FlatKeyOf<TValues>) as FieldState<TypeAtPath<S, typeof name>>,\n fields: {\n list: scopedListFields,\n register: (name, options?) =>\n ctx.root.fields.register(\n pre(name as string) as FlatKeyOf<TValues>,\n options as RegisterFieldOptions<TypeAtPath<TValues, FlatKeyOf<TValues>>>,\n ),\n remove: (name) => ctx.root.fields.remove(pre(name as string) as FlatKeyOf<TValues>),\n setValidator: (name, validator?) =>\n ctx.root.fields.setValidator(pre(name as string) as FlatKeyOf<TValues>, validator),\n },\n get: (name) => ctx.root.get(pre(name as string) as FlatKeyOf<TValues>) as TypeAtPath<S, typeof name>,\n get isLoading() {\n return ctx.root.isLoading;\n },\n get isSubmitting() {\n return ctx.root.isSubmitting;\n },\n patch: scopedPatch as Form<S>['patch'],\n replace: scopedReplace as Form<S>['replace'],\n reset: scopedReset,\n resetErrors: scopedResetErrors as Form<S>['resetErrors'],\n resetField: (name) => ctx.root.resetField(pre(name as string) as FlatKeyOf<TValues>),\n // Cast is irreducible: FormSnapshot<ScopedValues<TValues,P>> and FormSnapshot<TValues> are\n // structurally unrelated generic instantiations -- TS cannot verify one against the other.\n restore: (snap) => ctx.root.restore(snap as FormSnapshot<TValues>),\n scope: (subPrefix) => createScopedForm(ctx, pre(subPrefix as string)) as Form<ScopedValues<S, typeof subPrefix>>,\n set: (name, value, options?: SetOptions) =>\n ctx.root.set(\n pre(name as string) as FlatKeyOf<TValues>,\n value as TypeAtPath<TValues, FlatKeyOf<TValues>>,\n options,\n ),\n setError: (name, message) => ctx.root.setError(pre(name as string) as ErrorKeyOf<TValues>, message),\n // Cast is irreducible: FormSnapshot<TValues> and FormSnapshot<ScopedValues<TValues,P>> are\n // structurally unrelated generic instantiations -- TS cannot verify one against the other.\n snapshot: () => ctx.root.snapshot() as FormSnapshot<S>,\n get state() {\n return getScopedState();\n },\n submit: scopedSubmit as Form<S>['submit'],\n submitOrThrow: async (handler) => {\n const result = await scopedSubmit(handler);\n\n if (!result.ok) throw new ForgeValidationError(result.errors as Record<string, string>);\n\n return result.value;\n },\n subscribe: (listener, options?) => ctx.root.subscribe(listener, options),\n subscribeField: (name, listener, options?) =>\n ctx.root.subscribeField(\n pre(name as string) as FlatKeyOf<TValues>,\n listener as (state: FieldState<TypeAtPath<TValues, FlatKeyOf<TValues>>>) => void,\n options,\n ),\n subscribeScoped,\n [Symbol.asyncIterator]: () => ctx.root[Symbol.asyncIterator](),\n [Symbol.dispose]() {\n this.dispose();\n },\n touch: (name) => ctx.root.touch(pre(name as string) as FlatKeyOf<TValues>),\n touchAll: scopedTouchAll,\n untouch: (name) => ctx.root.untouch(pre(name as string) as FlatKeyOf<TValues>),\n untouchAll: scopedUntouchAll,\n validate: scopedValidate as Form<S>['validate'],\n validateStream(signal?) {\n const rootIter = ctx.root.validateStream(signal);\n\n const iter: AsyncIterableIterator<{ error: string | undefined; field: string }> = {\n async next() {\n for (;;) {\n const item = await rootIter.next();\n\n if (item.done) return item;\n\n if (isScopedKey(item.value.field))\n return { done: false, value: { error: item.value.error, field: unscope(item.value.field) } };\n }\n },\n return() {\n return rootIter.return ? rootIter.return() : Promise.resolve({ done: true as const, value: undefined });\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n\n return iter;\n },\n values: scopedValues,\n };\n}\n"],"mappings":"6FAmEA,SAAgB,EACd,EACA,EACgC,CAChC,IAAM,EAAS,GAAG,EAAI,GAEtB,SAAS,EAAI,EAAsB,CACjC,MAAO,GAAG,EAAI,GAAG,GACnB,CAEA,SAAS,EAAY,EAAsB,CACzC,OAAO,IAAQ,GAAO,EAAI,WAAW,CAAM,CAC7C,CAEA,SAAS,EAAQ,EAAqB,CACpC,OAAO,EAAI,WAAW,CAAM,EAAI,EAAI,MAAM,EAAO,MAAM,EAAI,CAC7D,CASA,SAAS,GAA4B,CACnC,IAAM,EAAY,EAAI,iBAAiB,EACjC,EAAS,OAAO,YACpB,OAAO,QAAQ,EAAU,MAAM,CAAC,CAC7B,QAAQ,CAAC,KAAO,EAAY,CAAC,CAAC,CAAC,CAC/B,KAAK,CAAC,EAAG,KAAO,CAAC,EAAQ,CAAC,EAAG,CAAC,CAAC,CACpC,EACM,EAAgB,EAAU,cAAc,OAAO,CAAW,CAAC,CAAC,IAAI,CAAO,EACvE,EAAmB,EAAU,iBAAiB,OAAO,CAAW,CAAC,CAAC,IAAI,CAAO,EAC7E,EAAU,OAAO,KAAK,CAAM,CAAC,CAAC,SAAW,EACzC,EAAU,CAAC,GAAG,EAAI,KAAK,CAAC,CAAC,KAAK,CAAW,EACzC,EAAY,CAAC,GAAG,EAAI,OAAO,CAAC,CAAC,KAAK,CAAW,EAC7C,EAAe,EAAiB,OAAS,EAE/C,OAAO,OAAO,OAAO,CACnB,OAAQ,OAAO,OAAO,CAAM,EAC5B,UACA,UAAW,EAAU,UACrB,aAAc,EAAU,aACxB,YACA,UACA,eACA,YAAa,EAAU,YACvB,cAAe,OAAO,OAAO,CAAa,EAC1C,iBAAkB,OAAO,OAAO,CAAgB,CAClD,CAAC,CACH,CAEA,SAAS,GAAyC,CAChD,IAAM,EAA+B,CAAC,EAEtC,IAAK,GAAM,CAAC,EAAK,KAAU,EAAI,MACzB,EAAI,WAAW,CAAM,IAAG,EAAI,EAAI,MAAM,EAAO,MAAM,GAAK,GAG9D,OAAA,EAAA,EAAA,eAAA,CAAuB,CAAG,CAC5B,CAOA,SAAS,GAAsC,CAC7C,IAAM,EAAQ,IAAI,IAElB,IAAK,IAAM,KAAO,EAAI,MAAM,KAAK,EAC3B,EAAY,CAAG,GAAG,EAAM,IAAI,EAAQ,CAAG,CAAC,EAG9C,IAAK,IAAM,KAAO,EAAI,WAAW,KAAK,EAChC,EAAY,CAAG,GAAG,EAAM,IAAI,EAAQ,CAAG,CAAC,EAG9C,OAAO,OAAO,OAAO,CAAC,GAAG,CAAK,CAAC,CACjC,CAEA,SAAS,GAAuB,CAC9B,EAAI,kBAAkB,EAEtB,IAAK,IAAM,KAAQ,EAAI,MAAM,KAAK,EAC5B,EAAY,CAAI,GAAG,EAAI,QAAQ,IAAI,CAAI,EAG7C,IAAK,IAAM,KAAQ,EAAI,WAAW,KAAK,EACjC,EAAY,CAAI,GAAG,EAAI,QAAQ,IAAI,CAAI,EAG7C,EAAI,cAAc,CACpB,CAEA,SAAS,GAAyB,CAChC,EAAI,kBAAkB,EAEtB,IAAK,IAAM,IAAQ,CAAC,GAAG,EAAI,OAAO,EAC5B,EAAY,CAAI,GAAG,EAAI,QAAQ,OAAO,CAAI,EAGhD,EAAI,cAAc,CACpB,CAEA,SAAS,GAAoB,CAC3B,EAAI,kBAAkB,EAEtB,IAAK,IAAM,IAAO,CAAC,GAAG,EAAI,MAAM,KAAK,CAAC,EAC/B,EAAY,CAAG,IAEpB,EAAI,WAAW,IAAI,CAAG,CAAC,EAAE,MAAM,EAC/B,EAAI,WAAW,OAAO,CAAG,EACzB,EAAI,MAAM,IAAI,EAAK,EAAI,SAAS,IAAI,CAAG,CAAC,EACxC,EAAI,MAAM,OAAO,CAAG,EACpB,EAAI,QAAQ,OAAO,CAAG,EAElB,EAAI,YAAY,OAAO,CAAG,GAAG,EAAI,iBAAiB,GAGxD,EAAI,cAAc,CACpB,CAEA,SAAS,EAAc,EAA2C,CAChE,EAAI,kBAAkB,EAEtB,IAAK,IAAM,IAAO,CAAC,GAAG,EAAI,WAAW,KAAK,CAAC,EACrC,EAAY,CAAG,IACjB,EAAI,WAAW,IAAI,CAAG,CAAC,EAAE,MAAM,EAC/B,EAAI,WAAW,OAAO,CAAG,GAI7B,IAAM,GAAA,EAAA,EAAA,aAAA,CAAqB,CAAoC,EAE/D,IAAK,IAAM,IAAO,CAAC,GAAG,EAAI,MAAM,KAAK,CAAC,EAC/B,EAAY,CAAG,IAEpB,EAAI,MAAM,OAAO,CAAG,EACpB,EAAI,SAAS,OAAO,CAAG,EACvB,EAAI,MAAM,OAAO,CAAG,EACpB,EAAI,QAAQ,OAAO,CAAG,EACtB,EAAI,YAAY,OAAO,CAAG,GAG5B,EAAI,iBAAiB,EAErB,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAI,EAAG,CAC/C,IAAM,EAAO,EAAI,CAAG,EAEpB,EAAI,MAAM,IAAI,EAAM,CAAK,EACzB,EAAI,SAAS,IAAI,EAAM,CAAK,CAC9B,CAEA,EAAI,cAAc,CACpB,CAEA,SAAS,EAAY,EAAwC,CAC3D,EAAI,kBAAkB,EAEtB,IAAM,GAAA,EAAA,EAAA,aAAA,CAAqB,CAAO,EAC5B,EAAwB,CAAC,EAE/B,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAI,EAAG,CAC/C,IAAM,EAAO,EAAI,CAAG,EAEpB,EAAI,SAAS,IAAI,EAAM,CAAK,EAC5B,EAAI,MAAM,IAAI,EAAM,CAAK,EACzB,EAAI,MAAM,OAAO,CAAI,EACrB,EAAY,KAAK,CAAI,CACvB,CAEA,EAAI,cAAc,CAAW,CAC/B,CAEA,SAAS,EACP,EACM,CACN,EAAI,kBAAkB,EAEtB,IAAK,IAAM,IAAO,CAAC,GAAG,EAAI,YAAY,KAAK,CAAC,EACtC,EAAY,CAAG,GAAG,EAAI,YAAY,OAAO,CAAG,EAGlD,GAAI,MACG,GAAM,CAAC,EAAK,KAAY,OAAO,QAAQ,CAAU,EAChD,OAAO,GAAY,UAAU,EAAI,YAAY,IAAI,EAAI,CAAG,EAAG,CAAO,EAI1E,EAAI,iBAAiB,EACrB,EAAI,cAAc,CACpB,CAEA,eAAe,EACb,EACA,EACyB,CAGzB,GAFA,EAAI,kBAAkB,EAGpB,IAAyB,IAAA,IACzB,CAAC,MAAM,QAAQ,CAAoB,GACnC,EAAE,aAAgC,aAClC,CAEA,IAAM,EAAe,EAAI,CAA8B,EAEvD,MAAM,EAAI,kBAAkB,CAAC,CAAsB,EAAG,UAAW,CAAM,EAEvE,IAAM,EAAQ,EAAI,YAAY,IAAI,CAAsB,EAExD,MAAO,CACL,OAAQ,IAAU,IAAA,GAA0D,CAAC,EAA/C,EAAG,GAAiC,CAAM,EACxE,MAAO,IAAU,IAAA,EACnB,CACF,CAEA,GAAI,MAAM,QAAQ,CAAoB,EAAG,CAEvC,IAAM,EAAiB,EAAqB,IAAK,GAAM,EAAI,CAAW,CAAC,EAEvE,MAAM,EAAI,kBAAkB,EAAgB,UAAW,CAAM,EAE7D,IAAM,EAAiC,CAAC,EAExC,IAAK,IAAM,KAAM,EAAgB,CAC/B,IAAM,EAAM,EAAI,YAAY,IAAI,CAAE,EAE9B,IAAQ,IAAA,KAAW,EAAO,EAAQ,CAAE,GAAK,EAC/C,CAEA,MAAO,CAAE,SAAQ,MAAO,OAAO,KAAK,CAAM,CAAC,CAAC,SAAW,CAAE,CAC3D,CAGA,IAAM,EAAM,EACN,EAAS,CAAC,GAAG,EAAI,WAAW,KAAK,CAAC,CAAC,CAAC,OAAO,CAAW,EAE5D,MAAM,EAAI,kBAAkB,EAAQ,UAAW,CAAG,EAElD,IAAM,EAAiC,CAAC,EAExC,IAAK,GAAM,CAAC,EAAK,KAAY,EAAI,YAC3B,EAAY,CAAG,IAAG,EAAO,EAAQ,CAAG,GAAK,GAG/C,MAAO,CAAE,SAAQ,MAAO,OAAO,KAAK,CAAM,CAAC,CAAC,SAAW,CAAE,CAC3D,CAEA,eAAe,EACb,EACgC,CAGhC,GAFA,EAAI,kBAAkB,EAElB,EAAI,aAAa,EAAG,MAAM,IAAI,EAAA,iBAAiB,2DAA2D,EAE9G,EAAI,KAAK,UAAY,CACnB,EAAI,qBAAqB,EACzB,EAAI,cAAc,EAAI,EACtB,EAAe,CACjB,CAAC,EAED,GAAI,CACF,IAAM,EAAS,CAAC,GAAG,EAAI,WAAW,KAAK,CAAC,CAAC,CAAC,OAAO,CAAW,EAE5D,MAAM,EAAI,kBAAkB,EAAQ,SAAS,EAE7C,EAAI,kBAAkB,EAEtB,IAAM,EAAiC,CAAC,EAExC,IAAK,GAAM,CAAC,EAAK,KAAY,EAAI,YAC3B,EAAY,CAAG,IAAG,EAAO,EAAQ,CAAG,GAAK,GAO/C,OAJI,OAAO,KAAK,CAAM,CAAC,CAAC,OAAS,EACxB,CAAE,SAAQ,GAAI,GAAO,KAAM,YAAsB,EAGnD,CAAE,GAAI,GAAe,MAAO,MAAM,EAAQ,EAAa,CAAC,CAAE,CACnE,QAAU,CACR,EAAI,cAAc,EAAK,EAElB,EAAI,WAAW,GAAG,EAAI,cAAc,CAC3C,CACF,CAWA,SAAS,EAAgB,EAAsC,EAAyC,CAEtG,IAAI,EAA8B,KAElC,OAAO,EAAI,KAAK,cAAgB,CAC9B,IAAM,EAAO,EAAe,EAG5B,GAAI,EAAW,CACb,IAAM,EAAI,EACJ,EAAU,OAAO,KAAK,EAAK,MAAM,EACjC,EAAc,OAAO,KAAK,EAAE,MAAM,EAClC,EACJ,EAAQ,SAAW,EAAY,QAAU,EAAQ,MAAO,GAAM,EAAK,OAAO,KAAO,EAAE,OAAO,EAAE,EAExF,EACJ,EAAK,cAAc,SAAW,EAAE,cAAc,QAC9C,EAAK,cAAc,OAAO,EAAG,IAAM,IAAM,EAAE,cAAc,EAAE,EAEvD,EACJ,EAAK,iBAAiB,SAAW,EAAE,iBAAiB,QACpD,EAAK,iBAAiB,OAAO,EAAG,IAAM,IAAM,EAAE,iBAAiB,EAAE,EAWnE,GARE,EAAK,UAAY,EAAE,SACnB,EAAK,YAAc,EAAE,WACrB,EAAK,eAAiB,EAAE,cACxB,EAAK,YAAc,EAAE,WACrB,EAAK,UAAY,EAAE,SACnB,EAAK,eAAiB,EAAE,cACxB,EAAK,cAAgB,EAAE,aAEP,GAAe,GAAgB,EAAiB,MACpE,CAEA,EAAY,EACZ,EAAS,CAAI,CACf,EAAG,CAAO,CACZ,CAMA,MAAO,CACL,MAAQ,GACN,EAAI,KAAK,MAAM,EAAI,CAAc,CAAuB,EAG1D,MAAQ,GAAO,EAAI,KAAK,MAAM,CAAE,EAChC,WAAa,GAAS,EAAI,KAAK,WAAW,EAAI,CAAc,CAAwB,EACpF,SAAU,EAAM,IACd,EAAI,KAAK,QAAQ,EAAI,CAAc,EAAyB,CAAM,EAGpE,IAAI,gBAAiB,CACnB,OAAO,EAAI,KAAK,cAClB,EACA,YAAe,CAEf,EACA,IAAI,UAAW,CACb,OAAO,EAAI,WAAW,CACxB,EACA,MAAQ,GACN,EAAI,KAAK,MAAM,EAAI,CAAc,CAAuB,EAC1D,OAAQ,CACN,KAAM,EACN,UAAW,EAAM,IACf,EAAI,KAAK,OAAO,SACd,EAAI,CAAc,EAClB,CACF,EACF,OAAS,GAAS,EAAI,KAAK,OAAO,OAAO,EAAI,CAAc,CAAuB,EAClF,cAAe,EAAM,IACnB,EAAI,KAAK,OAAO,aAAa,EAAI,CAAc,EAAyB,CAAS,CACrF,EACA,IAAM,GAAS,EAAI,KAAK,IAAI,EAAI,CAAc,CAAuB,EACrE,IAAI,WAAY,CACd,OAAO,EAAI,KAAK,SAClB,EACA,IAAI,cAAe,CACjB,OAAO,EAAI,KAAK,YAClB,EACA,MAAO,EACP,QAAS,EACT,MAAO,EACP,YAAa,EACb,WAAa,GAAS,EAAI,KAAK,WAAW,EAAI,CAAc,CAAuB,EAGnF,QAAU,GAAS,EAAI,KAAK,QAAQ,CAA6B,EACjE,MAAQ,GAAc,EAAiB,EAAK,EAAI,CAAmB,CAAC,EACpE,KAAM,EAAM,EAAO,IACjB,EAAI,KAAK,IACP,EAAI,CAAc,EAClB,EACA,CACF,EACF,UAAW,EAAM,IAAY,EAAI,KAAK,SAAS,EAAI,CAAc,EAA0B,CAAO,EAGlG,aAAgB,EAAI,KAAK,SAAS,EAClC,IAAI,OAAQ,CACV,OAAO,EAAe,CACxB,EACA,OAAQ,EACR,cAAe,KAAO,IAAY,CAChC,IAAM,EAAS,MAAM,EAAa,CAAO,EAEzC,GAAI,CAAC,EAAO,GAAI,MAAM,IAAI,EAAA,qBAAqB,EAAO,MAAgC,EAEtF,OAAO,EAAO,KAChB,EACA,WAAY,EAAU,IAAa,EAAI,KAAK,UAAU,EAAU,CAAO,EACvE,gBAAiB,EAAM,EAAU,IAC/B,EAAI,KAAK,eACP,EAAI,CAAc,EAClB,EACA,CACF,EACF,mBACC,OAAO,mBAAsB,EAAI,KAAK,OAAO,cAAc,CAAC,EAC7D,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,EACA,MAAQ,GAAS,EAAI,KAAK,MAAM,EAAI,CAAc,CAAuB,EACzE,SAAU,EACV,QAAU,GAAS,EAAI,KAAK,QAAQ,EAAI,CAAc,CAAuB,EAC7E,WAAY,EACZ,SAAU,EACV,eAAe,EAAS,CACtB,IAAM,EAAW,EAAI,KAAK,eAAe,CAAM,EAqB/C,MAAO,CAlBL,MAAM,MAAO,CACX,OAAS,CACP,IAAM,EAAO,MAAM,EAAS,KAAK,EAEjC,GAAI,EAAK,KAAM,OAAO,EAEtB,GAAI,EAAY,EAAK,MAAM,KAAK,EAC9B,MAAO,CAAE,KAAM,GAAO,MAAO,CAAE,MAAO,EAAK,MAAM,MAAO,MAAO,EAAQ,EAAK,MAAM,KAAK,CAAE,CAAE,CAC/F,CACF,EACA,QAAS,CACP,OAAO,EAAS,OAAS,EAAS,OAAO,EAAI,QAAQ,QAAQ,CAAE,KAAM,GAAe,MAAO,IAAA,EAAU,CAAC,CACxG,EACA,CAAC,OAAO,gBAAiB,CACvB,OAAO,IACT,CAGK,CACT,EACA,OAAQ,CACV,CACF"}
1
+ {"version":3,"file":"scope.cjs","names":[],"sources":["../../src/core/scope.ts"],"sourcesContent":["import type {\n ArrayField,\n ConnectOptions,\n ConnectionResult,\n ErrorKeyOf,\n FieldState,\n FieldValidator,\n FlatKeyOf,\n Form,\n FormSnapshot,\n FormState,\n MaybePromise,\n RegisterFieldOptions,\n ScopedValues,\n SetOptions,\n SubmitResult,\n SubscribeOptions,\n TypeAtPath,\n Unsubscribe,\n ValidateResult,\n} from '../types';\n\nimport { flattenValues, unflattenValues } from '../_utils';\nimport { ForgeSubmitError, ForgeValidationError } from '../errors';\n\n/**\n * R3: Slim ScopeContext — delegates simple operations through `root: Form<TValues>`.\n * Only the Maps/Sets needed for bulk scoped operations are passed directly.\n * @internal\n */\nexport interface ScopeContext<TValues extends Record<string, unknown> = Record<string, unknown>> {\n /** The fully-featured root form — used for all simple one-field delegations. */\n root: Form<TValues>;\n\n /* ---- Shared mutable state (passed by reference, needed by bulk scoped ops) ---- */\n store: Map<string, unknown>;\n baseline: Map<string, unknown>;\n validators: Map<string, FieldValidator<unknown>>;\n fieldErrors: Map<string, string>;\n touched: Set<string>;\n dirty: Set<string>;\n fieldCtrls: Map<string, AbortController>;\n\n /* ---- Scalar state accessors ---- */\n isSubmitting(): boolean;\n setSubmitting(value: boolean): void;\n incrementSubmitCount(): void;\n isDisposed(): boolean;\n\n /* ---- Core helpers ---- */\n ensureNotDisposed(): void;\n invalidateErrors(): void;\n requestNotify(target?: string | Iterable<string>): void;\n getStateSnapshot(): FormState;\n\n /* ---- Validation core (needed for scoped validate/submit) ---- */\n runValidationCore(\n fields: string[],\n scope: 'full' | 'partial',\n signal?: AbortSignal,\n ): Promise<ValidateResult & { aborted: boolean }>;\n}\n\n/**\n * Creates a scoped sub-form whose field paths are relative to `pfx`.\n * All simple single-field operations delegate to `ctx.root`.\n * Only prefix-aware bulk operations (submit, validate, replace, reset, etc.) contain custom code.\n */\nexport function createScopedForm<TValues extends Record<string, unknown>, P extends string>(\n ctx: ScopeContext<TValues>,\n pfx: P,\n): Form<ScopedValues<TValues, P>> {\n const pfxDot = `${pfx}.`;\n\n function pre(name: string): string {\n return `${pfx}.${name}`;\n }\n\n function isScopedKey(key: string): boolean {\n return key === pfx || key.startsWith(pfxDot);\n }\n\n function unscope(key: string): string {\n return key.startsWith(pfxDot) ? key.slice(pfxDot.length) : key;\n }\n\n /* ---- Non-trivial scoped implementations ---- */\n\n /**\n * Compute a scoped projection of FormState from current raw Maps.\n * Errors, touchedFields, validatingFields, isValid, isDirty, isTouched reflect only\n * fields within the prefix. isSubmitting, isLoading, isValidating, submitCount are full-form.\n */\n function getScopedState(): FormState {\n const rootState = ctx.getStateSnapshot();\n const errors = Object.fromEntries(\n Object.entries(rootState.errors)\n .filter(([k]) => isScopedKey(k))\n .map(([k, v]) => [unscope(k), v]),\n );\n const touchedFields = rootState.touchedFields.filter(isScopedKey).map(unscope);\n const validatingFields = rootState.validatingFields.filter(isScopedKey).map(unscope);\n const isValid = Object.keys(errors).length === 0;\n const isDirty = [...ctx.dirty].some(isScopedKey);\n const isTouched = [...ctx.touched].some(isScopedKey);\n const isValidating = validatingFields.length > 0;\n\n return Object.freeze({\n errors: Object.freeze(errors) as FormState['errors'],\n isDirty,\n isLoading: rootState.isLoading,\n isSubmitting: rootState.isSubmitting,\n isTouched,\n isValid,\n isValidating,\n submitCount: rootState.submitCount,\n touchedFields: Object.freeze(touchedFields) as readonly string[],\n validatingFields: Object.freeze(validatingFields) as readonly string[],\n });\n }\n\n function scopedValues(): ScopedValues<TValues, P> {\n const sub: Record<string, unknown> = {};\n\n for (const [key, value] of ctx.store) {\n if (key.startsWith(pfxDot)) sub[key.slice(pfxDot.length)] = value;\n }\n\n return unflattenValues(sub) as ScopedValues<TValues, P>;\n }\n\n /**\n * Enumerate field paths within this scope's prefix, stripped to relative paths —\n * matching `scope.state`'s relative-path convention, not `state.touchedFields`'s\n * absolute-path convention. Same \"known field\" definition `scopedTouchAll()` uses.\n */\n function scopedListFields(): readonly string[] {\n const known = new Set<string>();\n\n for (const key of ctx.store.keys()) {\n if (isScopedKey(key)) known.add(unscope(key));\n }\n\n for (const key of ctx.validators.keys()) {\n if (isScopedKey(key)) known.add(unscope(key));\n }\n\n return Object.freeze([...known]);\n }\n\n function scopedTouchAll(): void {\n ctx.ensureNotDisposed();\n\n for (const name of ctx.store.keys()) {\n if (isScopedKey(name)) ctx.touched.add(name);\n }\n\n for (const name of ctx.validators.keys()) {\n if (isScopedKey(name)) ctx.touched.add(name);\n }\n\n ctx.requestNotify();\n }\n\n function scopedUntouchAll(): void {\n ctx.ensureNotDisposed();\n\n for (const name of [...ctx.touched]) {\n if (isScopedKey(name)) ctx.touched.delete(name);\n }\n\n ctx.requestNotify();\n }\n\n function scopedReset(): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.store.keys()]) {\n if (!isScopedKey(key)) continue;\n\n ctx.fieldCtrls.get(key)?.abort();\n ctx.fieldCtrls.delete(key);\n ctx.store.set(key, ctx.baseline.get(key));\n ctx.dirty.delete(key);\n ctx.touched.delete(key);\n\n if (ctx.fieldErrors.delete(key)) ctx.invalidateErrors();\n }\n\n ctx.requestNotify();\n }\n\n function scopedReplace(newValues: ScopedValues<TValues, P>): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.fieldCtrls.keys()]) {\n if (isScopedKey(key)) {\n ctx.fieldCtrls.get(key)?.abort();\n ctx.fieldCtrls.delete(key);\n }\n }\n\n const flat = flattenValues(newValues as Record<string, unknown>);\n\n for (const key of [...ctx.store.keys()]) {\n if (!isScopedKey(key)) continue;\n\n ctx.store.delete(key);\n ctx.baseline.delete(key);\n ctx.dirty.delete(key);\n ctx.touched.delete(key);\n ctx.fieldErrors.delete(key);\n }\n\n ctx.invalidateErrors();\n\n for (const [key, value] of Object.entries(flat)) {\n const full = pre(key);\n\n ctx.store.set(full, value);\n ctx.baseline.set(full, value);\n }\n\n ctx.requestNotify();\n }\n\n function scopedPatch(partial: Record<string, unknown>): void {\n ctx.ensureNotDisposed();\n\n const flat = flattenValues(partial);\n const changedKeys: string[] = [];\n\n for (const [key, value] of Object.entries(flat)) {\n const full = pre(key);\n\n ctx.baseline.set(full, value);\n ctx.store.set(full, value);\n ctx.dirty.delete(full);\n changedKeys.push(full);\n }\n\n ctx.requestNotify(changedKeys);\n }\n\n function scopedResetErrors(\n nextErrors?: Partial<Record<ErrorKeyOf<ScopedValues<TValues, P>>, string | undefined>>,\n ): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.fieldErrors.keys()]) {\n if (isScopedKey(key)) ctx.fieldErrors.delete(key);\n }\n\n if (nextErrors) {\n for (const [key, message] of Object.entries(nextErrors)) {\n if (typeof message === 'string') ctx.fieldErrors.set(pre(key), message);\n }\n }\n\n ctx.invalidateErrors();\n ctx.requestNotify();\n }\n\n async function scopedValidate(\n nameOrFieldsOrSignal?: FlatKeyOf<ScopedValues<TValues, P>> | FlatKeyOf<ScopedValues<TValues, P>>[] | AbortSignal,\n signal?: AbortSignal,\n ): Promise<ValidateResult> {\n ctx.ensureNotDisposed();\n\n if (\n nameOrFieldsOrSignal !== undefined &&\n !Array.isArray(nameOrFieldsOrSignal) &&\n !(nameOrFieldsOrSignal instanceof AbortSignal)\n ) {\n // validate(name) — single field\n const prefixedName = pre(nameOrFieldsOrSignal as string) as FlatKeyOf<TValues>;\n\n await ctx.runValidationCore([prefixedName as string], 'partial', signal);\n\n const error = ctx.fieldErrors.get(prefixedName as string);\n\n return {\n errors: error !== undefined ? { [nameOrFieldsOrSignal as string]: error } : {},\n valid: error === undefined,\n };\n }\n\n if (Array.isArray(nameOrFieldsOrSignal)) {\n // validate(fields[]) — specific subset\n const prefixedFields = nameOrFieldsOrSignal.map((f) => pre(f as string)) as string[];\n\n await ctx.runValidationCore(prefixedFields, 'partial', signal);\n\n const errors: Record<string, string> = {};\n\n for (const pf of prefixedFields) {\n const msg = ctx.fieldErrors.get(pf);\n\n if (msg !== undefined) errors[unscope(pf)] = msg;\n }\n\n return { errors, valid: Object.keys(errors).length === 0 };\n }\n\n // validate(signal?) — all scoped fields\n const sig = nameOrFieldsOrSignal as AbortSignal | undefined;\n const fields = [...ctx.validators.keys()].filter(isScopedKey);\n\n await ctx.runValidationCore(fields, 'partial', sig);\n\n const errors: Record<string, string> = {};\n\n for (const [key, message] of ctx.fieldErrors) {\n if (isScopedKey(key)) errors[unscope(key)] = message;\n }\n\n return { errors, valid: Object.keys(errors).length === 0 };\n }\n\n async function scopedSubmit<TResult>(\n handler: (values: ScopedValues<TValues, P>) => MaybePromise<TResult>,\n ): Promise<SubmitResult<TResult>> {\n ctx.ensureNotDisposed();\n\n if (ctx.isSubmitting()) throw new ForgeSubmitError('submit() called while a submission is already in progress');\n\n ctx.root.batch(() => {\n ctx.incrementSubmitCount();\n ctx.setSubmitting(true);\n scopedTouchAll();\n });\n\n try {\n const fields = [...ctx.validators.keys()].filter(isScopedKey);\n\n await ctx.runValidationCore(fields, 'partial');\n\n ctx.ensureNotDisposed();\n\n const errors: Record<string, string> = {};\n\n for (const [key, message] of ctx.fieldErrors) {\n if (isScopedKey(key)) errors[unscope(key)] = message;\n }\n\n if (Object.keys(errors).length > 0) {\n return { errors, ok: false, type: 'validation' as const };\n }\n\n return { ok: true as const, value: await handler(scopedValues()) };\n } finally {\n ctx.setSubmitting(false);\n\n if (!ctx.isDisposed()) ctx.requestNotify();\n }\n }\n\n /**\n * Subscribe filtered to scoped fields only.\n * Errors, touchedFields, and validatingFields are remapped to relative paths.\n * `isValid`, `isDirty`, and `isTouched` reflect only fields within this scope's prefix.\n * `isSubmitting`, `isLoading`, `isValidating`, and `submitCount` reflect the full form.\n *\n * The listener fires only when the scoped projection changes — mutations outside this\n * prefix do not fire the listener.\n */\n function subscribeScoped(listener: (state: FormState) => void, options?: SubscribeOptions): Unsubscribe {\n // Track the previous scoped projection for equality comparison.\n let prevState: FormState | null = null;\n\n return ctx.root.subscribe(() => {\n const next = getScopedState();\n\n // Skip if no scoped-relevant state has changed.\n if (prevState) {\n const p = prevState;\n const errKeys = Object.keys(next.errors);\n const prevErrKeys = Object.keys(p.errors);\n const errorsMatch =\n errKeys.length === prevErrKeys.length && errKeys.every((k) => next.errors[k] === p.errors[k]);\n\n const touchedMatch =\n next.touchedFields.length === p.touchedFields.length &&\n next.touchedFields.every((v, i) => v === p.touchedFields[i]);\n\n const validatingMatch =\n next.validatingFields.length === p.validatingFields.length &&\n next.validatingFields.every((v, i) => v === p.validatingFields[i]);\n\n const flagsMatch =\n next.isDirty === p.isDirty &&\n next.isLoading === p.isLoading &&\n next.isSubmitting === p.isSubmitting &&\n next.isTouched === p.isTouched &&\n next.isValid === p.isValid &&\n next.isValidating === p.isValidating &&\n next.submitCount === p.submitCount;\n\n if (flagsMatch && errorsMatch && touchedMatch && validatingMatch) return;\n }\n\n prevState = next;\n listener(next);\n }, options);\n }\n\n function createScopedAdapter() {\n return {\n array(name: string): ArrayField {\n return ctx.root.array(pre(name) as FlatKeyOf<TValues>) as ArrayField;\n },\n clearError(name: string): void {\n ctx.root.clearError(pre(name) as ErrorKeyOf<TValues>);\n },\n connect(name: string, config?: ConnectOptions): ConnectionResult<unknown> {\n return ctx.root.connect(pre(name) as FlatKeyOf<TValues>, config) as ConnectionResult<unknown>;\n },\n field(name: string): FieldState<unknown> {\n return ctx.root.field(pre(name) as FlatKeyOf<TValues>) as FieldState<unknown>;\n },\n get(name: string): unknown {\n return ctx.root.get(pre(name) as FlatKeyOf<TValues>);\n },\n register(name: string, options?: RegisterFieldOptions<unknown>): Unsubscribe {\n return ctx.root.fields.register(\n pre(name) as FlatKeyOf<TValues>,\n options as RegisterFieldOptions<TypeAtPath<TValues, FlatKeyOf<TValues>>>,\n );\n },\n remove(name: string): void {\n ctx.root.fields.remove(pre(name) as FlatKeyOf<TValues>);\n },\n resetField(name: string): void {\n ctx.root.resetField(pre(name) as FlatKeyOf<TValues>);\n },\n set(name: string, value: unknown, options?: SetOptions): void {\n ctx.root.set(pre(name) as FlatKeyOf<TValues>, value as TypeAtPath<TValues, FlatKeyOf<TValues>>, options);\n },\n setError(name: string, message: string): void {\n ctx.root.setError(pre(name) as ErrorKeyOf<TValues>, message);\n },\n setValidator(name: string, validator?: FieldValidator): void {\n ctx.root.fields.setValidator(pre(name) as FlatKeyOf<TValues>, validator);\n },\n subscribeField(\n name: string,\n listener: (state: FieldState<unknown>) => void,\n options?: SubscribeOptions,\n ): Unsubscribe {\n return ctx.root.subscribeField(\n pre(name) as FlatKeyOf<TValues>,\n listener as (state: FieldState<TypeAtPath<TValues, FlatKeyOf<TValues>>>) => void,\n options,\n );\n },\n touch(name: string): void {\n ctx.root.touch(pre(name) as FlatKeyOf<TValues>);\n },\n untouch(name: string): void {\n ctx.root.untouch(pre(name) as FlatKeyOf<TValues>);\n },\n };\n }\n\n /* ---- Public scoped form object ---- */\n\n type S = ScopedValues<TValues, P>;\n\n const adapter = createScopedAdapter();\n\n return {\n array: (name) =>\n adapter.array(name as string) as ArrayField<\n TypeAtPath<S, typeof name> extends readonly (infer E)[] ? E : unknown\n >,\n batch: (fn) => ctx.root.batch(fn),\n clearError: (name) => adapter.clearError(name as string),\n connect: (name, config?) => adapter.connect(name as string, config) as ConnectionResult<TypeAtPath<S, typeof name>>,\n get disposalSignal() {\n return ctx.root.disposalSignal;\n },\n dispose: () => {\n /* Scoped forms share lifecycle with parent — call parentForm.dispose() to tear down */\n },\n get disposed() {\n return ctx.isDisposed();\n },\n field: (name) => adapter.field(name as string) as FieldState<TypeAtPath<S, typeof name>>,\n fields: {\n list: scopedListFields,\n register: (name, options?) => adapter.register(name as string, options as RegisterFieldOptions<unknown>),\n remove: (name) => adapter.remove(name as string),\n setValidator: (name, validator?) => adapter.setValidator(name as string, validator),\n },\n get: (name) => adapter.get(name as string) as TypeAtPath<S, typeof name>,\n get isLoading() {\n return ctx.root.isLoading;\n },\n get isSubmitting() {\n return ctx.root.isSubmitting;\n },\n patch: scopedPatch as Form<S>['patch'],\n replace: scopedReplace as Form<S>['replace'],\n reset: scopedReset,\n resetErrors: scopedResetErrors as Form<S>['resetErrors'],\n resetField: (name) => adapter.resetField(name as string),\n // Cast is irreducible: FormSnapshot<ScopedValues<TValues,P>> and FormSnapshot<TValues> are\n // structurally unrelated generic instantiations -- TS cannot verify one against the other.\n restore: (snap) => ctx.root.restore(snap as FormSnapshot<TValues>),\n scope: (subPrefix) => createScopedForm(ctx, pre(subPrefix as string)) as Form<ScopedValues<S, typeof subPrefix>>,\n set: (name, value, options?: SetOptions) => adapter.set(name as string, value, options),\n setError: (name, message) => adapter.setError(name as string, message),\n // Cast is irreducible: FormSnapshot<TValues> and FormSnapshot<ScopedValues<TValues,P>> are\n // structurally unrelated generic instantiations -- TS cannot verify one against the other.\n snapshot: () => ctx.root.snapshot() as FormSnapshot<S>,\n get state() {\n return getScopedState();\n },\n submit: scopedSubmit as Form<S>['submit'],\n submitOrThrow: async (handler) => {\n const result = await scopedSubmit(handler);\n\n if (!result.ok) throw new ForgeValidationError(result.errors as Record<string, string>);\n\n return result.value;\n },\n subscribe: (listener, options?) => ctx.root.subscribe(listener, options),\n subscribeField: (name, listener, options?) =>\n adapter.subscribeField(name as string, listener as (state: FieldState<unknown>) => void, options),\n subscribeScoped,\n [Symbol.asyncIterator]: () => ctx.root[Symbol.asyncIterator](),\n [Symbol.dispose]() {\n this.dispose();\n },\n touch: (name) => adapter.touch(name as string),\n touchAll: scopedTouchAll,\n untouch: (name) => adapter.untouch(name as string),\n untouchAll: scopedUntouchAll,\n validate: scopedValidate as Form<S>['validate'],\n validateStream(signal?) {\n const rootIter = ctx.root.validateStream(signal);\n\n const iter: AsyncIterableIterator<{ error: string | undefined; field: string }> = {\n async next() {\n for (;;) {\n const item = await rootIter.next();\n\n if (item.done) return item;\n\n if (isScopedKey(item.value.field))\n return { done: false, value: { error: item.value.error, field: unscope(item.value.field) } };\n }\n },\n return() {\n return rootIter.return ? rootIter.return() : Promise.resolve({ done: true as const, value: undefined });\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n\n return iter;\n },\n values: scopedValues,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/core/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAOV,IAAI,EAKJ,YAAY,EAOb,MAAM,UAAU,CAAC;AA2ClB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,MAAM,EACxF,GAAG,EAAE,YAAY,CAAC,OAAO,CAAC,EAC1B,GAAG,EAAE,CAAC,GACL,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAochC"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/core/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAQV,IAAI,EAKJ,YAAY,EAOb,MAAM,UAAU,CAAC;AA2ClB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,MAAM,EACxF,GAAG,EAAE,YAAY,CAAC,OAAO,CAAC,EAC1B,GAAG,EAAE,CAAC,GACL,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CA8ehC"}
@@ -146,11 +146,58 @@ function i(a, o) {
146
146
  n = t, e(t);
147
147
  }, t);
148
148
  }
149
+ function C() {
150
+ return {
151
+ array(e) {
152
+ return a.root.array(c(e));
153
+ },
154
+ clearError(e) {
155
+ a.root.clearError(c(e));
156
+ },
157
+ connect(e, t) {
158
+ return a.root.connect(c(e), t);
159
+ },
160
+ field(e) {
161
+ return a.root.field(c(e));
162
+ },
163
+ get(e) {
164
+ return a.root.get(c(e));
165
+ },
166
+ register(e, t) {
167
+ return a.root.fields.register(c(e), t);
168
+ },
169
+ remove(e) {
170
+ a.root.fields.remove(c(e));
171
+ },
172
+ resetField(e) {
173
+ a.root.resetField(c(e));
174
+ },
175
+ set(e, t, n) {
176
+ a.root.set(c(e), t, n);
177
+ },
178
+ setError(e, t) {
179
+ a.root.setError(c(e), t);
180
+ },
181
+ setValidator(e, t) {
182
+ a.root.fields.setValidator(c(e), t);
183
+ },
184
+ subscribeField(e, t, n) {
185
+ return a.root.subscribeField(c(e), t, n);
186
+ },
187
+ touch(e) {
188
+ a.root.touch(c(e));
189
+ },
190
+ untouch(e) {
191
+ a.root.untouch(c(e));
192
+ }
193
+ };
194
+ }
195
+ let w = C();
149
196
  return {
150
- array: (e) => a.root.array(c(e)),
197
+ array: (e) => w.array(e),
151
198
  batch: (e) => a.root.batch(e),
152
- clearError: (e) => a.root.clearError(c(e)),
153
- connect: (e, t) => a.root.connect(c(e), t),
199
+ clearError: (e) => w.clearError(e),
200
+ connect: (e, t) => w.connect(e, t),
154
201
  get disposalSignal() {
155
202
  return a.root.disposalSignal;
156
203
  },
@@ -158,14 +205,14 @@ function i(a, o) {
158
205
  get disposed() {
159
206
  return a.isDisposed();
160
207
  },
161
- field: (e) => a.root.field(c(e)),
208
+ field: (e) => w.field(e),
162
209
  fields: {
163
210
  list: p,
164
- register: (e, t) => a.root.fields.register(c(e), t),
165
- remove: (e) => a.root.fields.remove(c(e)),
166
- setValidator: (e, t) => a.root.fields.setValidator(c(e), t)
211
+ register: (e, t) => w.register(e, t),
212
+ remove: (e) => w.remove(e),
213
+ setValidator: (e, t) => w.setValidator(e, t)
167
214
  },
168
- get: (e) => a.root.get(c(e)),
215
+ get: (e) => w.get(e),
169
216
  get isLoading() {
170
217
  return a.root.isLoading;
171
218
  },
@@ -176,11 +223,11 @@ function i(a, o) {
176
223
  replace: _,
177
224
  reset: g,
178
225
  resetErrors: y,
179
- resetField: (e) => a.root.resetField(c(e)),
226
+ resetField: (e) => w.resetField(e),
180
227
  restore: (e) => a.root.restore(e),
181
228
  scope: (e) => i(a, c(e)),
182
- set: (e, t, n) => a.root.set(c(e), t, n),
183
- setError: (e, t) => a.root.setError(c(e), t),
229
+ set: (e, t, n) => w.set(e, t, n),
230
+ setError: (e, t) => w.setError(e, t),
184
231
  snapshot: () => a.root.snapshot(),
185
232
  get state() {
186
233
  return d();
@@ -192,15 +239,15 @@ function i(a, o) {
192
239
  return n.value;
193
240
  },
194
241
  subscribe: (e, t) => a.root.subscribe(e, t),
195
- subscribeField: (e, t, n) => a.root.subscribeField(c(e), t, n),
242
+ subscribeField: (e, t, n) => w.subscribeField(e, t, n),
196
243
  subscribeScoped: S,
197
244
  [Symbol.asyncIterator]: () => a.root[Symbol.asyncIterator](),
198
245
  [Symbol.dispose]() {
199
246
  this.dispose();
200
247
  },
201
- touch: (e) => a.root.touch(c(e)),
248
+ touch: (e) => w.touch(e),
202
249
  touchAll: m,
203
- untouch: (e) => a.root.untouch(c(e)),
250
+ untouch: (e) => w.untouch(e),
204
251
  untouchAll: h,
205
252
  validate: b,
206
253
  validateStream(e) {
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","names":[],"sources":["../../src/core/scope.ts"],"sourcesContent":["import type {\n ArrayField,\n ConnectionResult,\n ErrorKeyOf,\n FieldState,\n FieldValidator,\n FlatKeyOf,\n Form,\n FormSnapshot,\n FormState,\n MaybePromise,\n RegisterFieldOptions,\n ScopedValues,\n SetOptions,\n SubmitResult,\n SubscribeOptions,\n TypeAtPath,\n Unsubscribe,\n ValidateResult,\n} from '../types';\n\nimport { flattenValues, unflattenValues } from '../_utils';\nimport { ForgeSubmitError, ForgeValidationError } from '../errors';\n\n/**\n * R3: Slim ScopeContext — delegates simple operations through `root: Form<TValues>`.\n * Only the Maps/Sets needed for bulk scoped operations are passed directly.\n * @internal\n */\nexport interface ScopeContext<TValues extends Record<string, unknown> = Record<string, unknown>> {\n /** The fully-featured root form — used for all simple one-field delegations. */\n root: Form<TValues>;\n\n /* ---- Shared mutable state (passed by reference, needed by bulk scoped ops) ---- */\n store: Map<string, unknown>;\n baseline: Map<string, unknown>;\n validators: Map<string, FieldValidator<unknown>>;\n fieldErrors: Map<string, string>;\n touched: Set<string>;\n dirty: Set<string>;\n fieldCtrls: Map<string, AbortController>;\n\n /* ---- Scalar state accessors ---- */\n isSubmitting(): boolean;\n setSubmitting(value: boolean): void;\n incrementSubmitCount(): void;\n isDisposed(): boolean;\n\n /* ---- Core helpers ---- */\n ensureNotDisposed(): void;\n invalidateErrors(): void;\n requestNotify(target?: string | Iterable<string>): void;\n getStateSnapshot(): FormState;\n\n /* ---- Validation core (needed for scoped validate/submit) ---- */\n runValidationCore(\n fields: string[],\n scope: 'full' | 'partial',\n signal?: AbortSignal,\n ): Promise<ValidateResult & { aborted: boolean }>;\n}\n\n/**\n * Creates a scoped sub-form whose field paths are relative to `pfx`.\n * All simple single-field operations delegate to `ctx.root`.\n * Only prefix-aware bulk operations (submit, validate, replace, reset, etc.) contain custom code.\n */\nexport function createScopedForm<TValues extends Record<string, unknown>, P extends string>(\n ctx: ScopeContext<TValues>,\n pfx: P,\n): Form<ScopedValues<TValues, P>> {\n const pfxDot = `${pfx}.`;\n\n function pre(name: string): string {\n return `${pfx}.${name}`;\n }\n\n function isScopedKey(key: string): boolean {\n return key === pfx || key.startsWith(pfxDot);\n }\n\n function unscope(key: string): string {\n return key.startsWith(pfxDot) ? key.slice(pfxDot.length) : key;\n }\n\n /* ---- Non-trivial scoped implementations ---- */\n\n /**\n * Compute a scoped projection of FormState from current raw Maps.\n * Errors, touchedFields, validatingFields, isValid, isDirty, isTouched reflect only\n * fields within the prefix. isSubmitting, isLoading, isValidating, submitCount are full-form.\n */\n function getScopedState(): FormState {\n const rootState = ctx.getStateSnapshot();\n const errors = Object.fromEntries(\n Object.entries(rootState.errors)\n .filter(([k]) => isScopedKey(k))\n .map(([k, v]) => [unscope(k), v]),\n );\n const touchedFields = rootState.touchedFields.filter(isScopedKey).map(unscope);\n const validatingFields = rootState.validatingFields.filter(isScopedKey).map(unscope);\n const isValid = Object.keys(errors).length === 0;\n const isDirty = [...ctx.dirty].some(isScopedKey);\n const isTouched = [...ctx.touched].some(isScopedKey);\n const isValidating = validatingFields.length > 0;\n\n return Object.freeze({\n errors: Object.freeze(errors) as FormState['errors'],\n isDirty,\n isLoading: rootState.isLoading,\n isSubmitting: rootState.isSubmitting,\n isTouched,\n isValid,\n isValidating,\n submitCount: rootState.submitCount,\n touchedFields: Object.freeze(touchedFields) as readonly string[],\n validatingFields: Object.freeze(validatingFields) as readonly string[],\n });\n }\n\n function scopedValues(): ScopedValues<TValues, P> {\n const sub: Record<string, unknown> = {};\n\n for (const [key, value] of ctx.store) {\n if (key.startsWith(pfxDot)) sub[key.slice(pfxDot.length)] = value;\n }\n\n return unflattenValues(sub) as ScopedValues<TValues, P>;\n }\n\n /**\n * Enumerate field paths within this scope's prefix, stripped to relative paths —\n * matching `scope.state`'s relative-path convention, not `state.touchedFields`'s\n * absolute-path convention. Same \"known field\" definition `scopedTouchAll()` uses.\n */\n function scopedListFields(): readonly string[] {\n const known = new Set<string>();\n\n for (const key of ctx.store.keys()) {\n if (isScopedKey(key)) known.add(unscope(key));\n }\n\n for (const key of ctx.validators.keys()) {\n if (isScopedKey(key)) known.add(unscope(key));\n }\n\n return Object.freeze([...known]);\n }\n\n function scopedTouchAll(): void {\n ctx.ensureNotDisposed();\n\n for (const name of ctx.store.keys()) {\n if (isScopedKey(name)) ctx.touched.add(name);\n }\n\n for (const name of ctx.validators.keys()) {\n if (isScopedKey(name)) ctx.touched.add(name);\n }\n\n ctx.requestNotify();\n }\n\n function scopedUntouchAll(): void {\n ctx.ensureNotDisposed();\n\n for (const name of [...ctx.touched]) {\n if (isScopedKey(name)) ctx.touched.delete(name);\n }\n\n ctx.requestNotify();\n }\n\n function scopedReset(): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.store.keys()]) {\n if (!isScopedKey(key)) continue;\n\n ctx.fieldCtrls.get(key)?.abort();\n ctx.fieldCtrls.delete(key);\n ctx.store.set(key, ctx.baseline.get(key));\n ctx.dirty.delete(key);\n ctx.touched.delete(key);\n\n if (ctx.fieldErrors.delete(key)) ctx.invalidateErrors();\n }\n\n ctx.requestNotify();\n }\n\n function scopedReplace(newValues: ScopedValues<TValues, P>): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.fieldCtrls.keys()]) {\n if (isScopedKey(key)) {\n ctx.fieldCtrls.get(key)?.abort();\n ctx.fieldCtrls.delete(key);\n }\n }\n\n const flat = flattenValues(newValues as Record<string, unknown>);\n\n for (const key of [...ctx.store.keys()]) {\n if (!isScopedKey(key)) continue;\n\n ctx.store.delete(key);\n ctx.baseline.delete(key);\n ctx.dirty.delete(key);\n ctx.touched.delete(key);\n ctx.fieldErrors.delete(key);\n }\n\n ctx.invalidateErrors();\n\n for (const [key, value] of Object.entries(flat)) {\n const full = pre(key);\n\n ctx.store.set(full, value);\n ctx.baseline.set(full, value);\n }\n\n ctx.requestNotify();\n }\n\n function scopedPatch(partial: Record<string, unknown>): void {\n ctx.ensureNotDisposed();\n\n const flat = flattenValues(partial);\n const changedKeys: string[] = [];\n\n for (const [key, value] of Object.entries(flat)) {\n const full = pre(key);\n\n ctx.baseline.set(full, value);\n ctx.store.set(full, value);\n ctx.dirty.delete(full);\n changedKeys.push(full);\n }\n\n ctx.requestNotify(changedKeys);\n }\n\n function scopedResetErrors(\n nextErrors?: Partial<Record<ErrorKeyOf<ScopedValues<TValues, P>>, string | undefined>>,\n ): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.fieldErrors.keys()]) {\n if (isScopedKey(key)) ctx.fieldErrors.delete(key);\n }\n\n if (nextErrors) {\n for (const [key, message] of Object.entries(nextErrors)) {\n if (typeof message === 'string') ctx.fieldErrors.set(pre(key), message);\n }\n }\n\n ctx.invalidateErrors();\n ctx.requestNotify();\n }\n\n async function scopedValidate(\n nameOrFieldsOrSignal?: FlatKeyOf<ScopedValues<TValues, P>> | FlatKeyOf<ScopedValues<TValues, P>>[] | AbortSignal,\n signal?: AbortSignal,\n ): Promise<ValidateResult> {\n ctx.ensureNotDisposed();\n\n if (\n nameOrFieldsOrSignal !== undefined &&\n !Array.isArray(nameOrFieldsOrSignal) &&\n !(nameOrFieldsOrSignal instanceof AbortSignal)\n ) {\n // validate(name) — single field\n const prefixedName = pre(nameOrFieldsOrSignal as string) as FlatKeyOf<TValues>;\n\n await ctx.runValidationCore([prefixedName as string], 'partial', signal);\n\n const error = ctx.fieldErrors.get(prefixedName as string);\n\n return {\n errors: error !== undefined ? { [nameOrFieldsOrSignal as string]: error } : {},\n valid: error === undefined,\n };\n }\n\n if (Array.isArray(nameOrFieldsOrSignal)) {\n // validate(fields[]) — specific subset\n const prefixedFields = nameOrFieldsOrSignal.map((f) => pre(f as string)) as string[];\n\n await ctx.runValidationCore(prefixedFields, 'partial', signal);\n\n const errors: Record<string, string> = {};\n\n for (const pf of prefixedFields) {\n const msg = ctx.fieldErrors.get(pf);\n\n if (msg !== undefined) errors[unscope(pf)] = msg;\n }\n\n return { errors, valid: Object.keys(errors).length === 0 };\n }\n\n // validate(signal?) — all scoped fields\n const sig = nameOrFieldsOrSignal as AbortSignal | undefined;\n const fields = [...ctx.validators.keys()].filter(isScopedKey);\n\n await ctx.runValidationCore(fields, 'partial', sig);\n\n const errors: Record<string, string> = {};\n\n for (const [key, message] of ctx.fieldErrors) {\n if (isScopedKey(key)) errors[unscope(key)] = message;\n }\n\n return { errors, valid: Object.keys(errors).length === 0 };\n }\n\n async function scopedSubmit<TResult>(\n handler: (values: ScopedValues<TValues, P>) => MaybePromise<TResult>,\n ): Promise<SubmitResult<TResult>> {\n ctx.ensureNotDisposed();\n\n if (ctx.isSubmitting()) throw new ForgeSubmitError('submit() called while a submission is already in progress');\n\n ctx.root.batch(() => {\n ctx.incrementSubmitCount();\n ctx.setSubmitting(true);\n scopedTouchAll();\n });\n\n try {\n const fields = [...ctx.validators.keys()].filter(isScopedKey);\n\n await ctx.runValidationCore(fields, 'partial');\n\n ctx.ensureNotDisposed();\n\n const errors: Record<string, string> = {};\n\n for (const [key, message] of ctx.fieldErrors) {\n if (isScopedKey(key)) errors[unscope(key)] = message;\n }\n\n if (Object.keys(errors).length > 0) {\n return { errors, ok: false, type: 'validation' as const };\n }\n\n return { ok: true as const, value: await handler(scopedValues()) };\n } finally {\n ctx.setSubmitting(false);\n\n if (!ctx.isDisposed()) ctx.requestNotify();\n }\n }\n\n /**\n * Subscribe filtered to scoped fields only.\n * Errors, touchedFields, and validatingFields are remapped to relative paths.\n * `isValid`, `isDirty`, and `isTouched` reflect only fields within this scope's prefix.\n * `isSubmitting`, `isLoading`, `isValidating`, and `submitCount` reflect the full form.\n *\n * The listener fires only when the scoped projection changes — mutations outside this\n * prefix do not fire the listener.\n */\n function subscribeScoped(listener: (state: FormState) => void, options?: SubscribeOptions): Unsubscribe {\n // Track the previous scoped projection for equality comparison.\n let prevState: FormState | null = null;\n\n return ctx.root.subscribe(() => {\n const next = getScopedState();\n\n // Skip if no scoped-relevant state has changed.\n if (prevState) {\n const p = prevState;\n const errKeys = Object.keys(next.errors);\n const prevErrKeys = Object.keys(p.errors);\n const errorsMatch =\n errKeys.length === prevErrKeys.length && errKeys.every((k) => next.errors[k] === p.errors[k]);\n\n const touchedMatch =\n next.touchedFields.length === p.touchedFields.length &&\n next.touchedFields.every((v, i) => v === p.touchedFields[i]);\n\n const validatingMatch =\n next.validatingFields.length === p.validatingFields.length &&\n next.validatingFields.every((v, i) => v === p.validatingFields[i]);\n\n const flagsMatch =\n next.isDirty === p.isDirty &&\n next.isLoading === p.isLoading &&\n next.isSubmitting === p.isSubmitting &&\n next.isTouched === p.isTouched &&\n next.isValid === p.isValid &&\n next.isValidating === p.isValidating &&\n next.submitCount === p.submitCount;\n\n if (flagsMatch && errorsMatch && touchedMatch && validatingMatch) return;\n }\n\n prevState = next;\n listener(next);\n }, options);\n }\n\n /* ---- Public scoped form object ---- */\n\n type S = ScopedValues<TValues, P>;\n\n return {\n array: (name) =>\n ctx.root.array(pre(name as string) as FlatKeyOf<TValues>) as ArrayField<\n TypeAtPath<S, typeof name> extends readonly (infer E)[] ? E : unknown\n >,\n batch: (fn) => ctx.root.batch(fn),\n clearError: (name) => ctx.root.clearError(pre(name as string) as ErrorKeyOf<TValues>),\n connect: (name, config?) =>\n ctx.root.connect(pre(name as string) as FlatKeyOf<TValues>, config) as ConnectionResult<\n TypeAtPath<S, typeof name>\n >,\n get disposalSignal() {\n return ctx.root.disposalSignal;\n },\n dispose: () => {\n /* Scoped forms share lifecycle with parent — call parentForm.dispose() to tear down */\n },\n get disposed() {\n return ctx.isDisposed();\n },\n field: (name) =>\n ctx.root.field(pre(name as string) as FlatKeyOf<TValues>) as FieldState<TypeAtPath<S, typeof name>>,\n fields: {\n list: scopedListFields,\n register: (name, options?) =>\n ctx.root.fields.register(\n pre(name as string) as FlatKeyOf<TValues>,\n options as RegisterFieldOptions<TypeAtPath<TValues, FlatKeyOf<TValues>>>,\n ),\n remove: (name) => ctx.root.fields.remove(pre(name as string) as FlatKeyOf<TValues>),\n setValidator: (name, validator?) =>\n ctx.root.fields.setValidator(pre(name as string) as FlatKeyOf<TValues>, validator),\n },\n get: (name) => ctx.root.get(pre(name as string) as FlatKeyOf<TValues>) as TypeAtPath<S, typeof name>,\n get isLoading() {\n return ctx.root.isLoading;\n },\n get isSubmitting() {\n return ctx.root.isSubmitting;\n },\n patch: scopedPatch as Form<S>['patch'],\n replace: scopedReplace as Form<S>['replace'],\n reset: scopedReset,\n resetErrors: scopedResetErrors as Form<S>['resetErrors'],\n resetField: (name) => ctx.root.resetField(pre(name as string) as FlatKeyOf<TValues>),\n // Cast is irreducible: FormSnapshot<ScopedValues<TValues,P>> and FormSnapshot<TValues> are\n // structurally unrelated generic instantiations -- TS cannot verify one against the other.\n restore: (snap) => ctx.root.restore(snap as FormSnapshot<TValues>),\n scope: (subPrefix) => createScopedForm(ctx, pre(subPrefix as string)) as Form<ScopedValues<S, typeof subPrefix>>,\n set: (name, value, options?: SetOptions) =>\n ctx.root.set(\n pre(name as string) as FlatKeyOf<TValues>,\n value as TypeAtPath<TValues, FlatKeyOf<TValues>>,\n options,\n ),\n setError: (name, message) => ctx.root.setError(pre(name as string) as ErrorKeyOf<TValues>, message),\n // Cast is irreducible: FormSnapshot<TValues> and FormSnapshot<ScopedValues<TValues,P>> are\n // structurally unrelated generic instantiations -- TS cannot verify one against the other.\n snapshot: () => ctx.root.snapshot() as FormSnapshot<S>,\n get state() {\n return getScopedState();\n },\n submit: scopedSubmit as Form<S>['submit'],\n submitOrThrow: async (handler) => {\n const result = await scopedSubmit(handler);\n\n if (!result.ok) throw new ForgeValidationError(result.errors as Record<string, string>);\n\n return result.value;\n },\n subscribe: (listener, options?) => ctx.root.subscribe(listener, options),\n subscribeField: (name, listener, options?) =>\n ctx.root.subscribeField(\n pre(name as string) as FlatKeyOf<TValues>,\n listener as (state: FieldState<TypeAtPath<TValues, FlatKeyOf<TValues>>>) => void,\n options,\n ),\n subscribeScoped,\n [Symbol.asyncIterator]: () => ctx.root[Symbol.asyncIterator](),\n [Symbol.dispose]() {\n this.dispose();\n },\n touch: (name) => ctx.root.touch(pre(name as string) as FlatKeyOf<TValues>),\n touchAll: scopedTouchAll,\n untouch: (name) => ctx.root.untouch(pre(name as string) as FlatKeyOf<TValues>),\n untouchAll: scopedUntouchAll,\n validate: scopedValidate as Form<S>['validate'],\n validateStream(signal?) {\n const rootIter = ctx.root.validateStream(signal);\n\n const iter: AsyncIterableIterator<{ error: string | undefined; field: string }> = {\n async next() {\n for (;;) {\n const item = await rootIter.next();\n\n if (item.done) return item;\n\n if (isScopedKey(item.value.field))\n return { done: false, value: { error: item.value.error, field: unscope(item.value.field) } };\n }\n },\n return() {\n return rootIter.return ? rootIter.return() : Promise.resolve({ done: true as const, value: undefined });\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n\n return iter;\n },\n values: scopedValues,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"scope.js","names":[],"sources":["../../src/core/scope.ts"],"sourcesContent":["import type {\n ArrayField,\n ConnectOptions,\n ConnectionResult,\n ErrorKeyOf,\n FieldState,\n FieldValidator,\n FlatKeyOf,\n Form,\n FormSnapshot,\n FormState,\n MaybePromise,\n RegisterFieldOptions,\n ScopedValues,\n SetOptions,\n SubmitResult,\n SubscribeOptions,\n TypeAtPath,\n Unsubscribe,\n ValidateResult,\n} from '../types';\n\nimport { flattenValues, unflattenValues } from '../_utils';\nimport { ForgeSubmitError, ForgeValidationError } from '../errors';\n\n/**\n * R3: Slim ScopeContext — delegates simple operations through `root: Form<TValues>`.\n * Only the Maps/Sets needed for bulk scoped operations are passed directly.\n * @internal\n */\nexport interface ScopeContext<TValues extends Record<string, unknown> = Record<string, unknown>> {\n /** The fully-featured root form — used for all simple one-field delegations. */\n root: Form<TValues>;\n\n /* ---- Shared mutable state (passed by reference, needed by bulk scoped ops) ---- */\n store: Map<string, unknown>;\n baseline: Map<string, unknown>;\n validators: Map<string, FieldValidator<unknown>>;\n fieldErrors: Map<string, string>;\n touched: Set<string>;\n dirty: Set<string>;\n fieldCtrls: Map<string, AbortController>;\n\n /* ---- Scalar state accessors ---- */\n isSubmitting(): boolean;\n setSubmitting(value: boolean): void;\n incrementSubmitCount(): void;\n isDisposed(): boolean;\n\n /* ---- Core helpers ---- */\n ensureNotDisposed(): void;\n invalidateErrors(): void;\n requestNotify(target?: string | Iterable<string>): void;\n getStateSnapshot(): FormState;\n\n /* ---- Validation core (needed for scoped validate/submit) ---- */\n runValidationCore(\n fields: string[],\n scope: 'full' | 'partial',\n signal?: AbortSignal,\n ): Promise<ValidateResult & { aborted: boolean }>;\n}\n\n/**\n * Creates a scoped sub-form whose field paths are relative to `pfx`.\n * All simple single-field operations delegate to `ctx.root`.\n * Only prefix-aware bulk operations (submit, validate, replace, reset, etc.) contain custom code.\n */\nexport function createScopedForm<TValues extends Record<string, unknown>, P extends string>(\n ctx: ScopeContext<TValues>,\n pfx: P,\n): Form<ScopedValues<TValues, P>> {\n const pfxDot = `${pfx}.`;\n\n function pre(name: string): string {\n return `${pfx}.${name}`;\n }\n\n function isScopedKey(key: string): boolean {\n return key === pfx || key.startsWith(pfxDot);\n }\n\n function unscope(key: string): string {\n return key.startsWith(pfxDot) ? key.slice(pfxDot.length) : key;\n }\n\n /* ---- Non-trivial scoped implementations ---- */\n\n /**\n * Compute a scoped projection of FormState from current raw Maps.\n * Errors, touchedFields, validatingFields, isValid, isDirty, isTouched reflect only\n * fields within the prefix. isSubmitting, isLoading, isValidating, submitCount are full-form.\n */\n function getScopedState(): FormState {\n const rootState = ctx.getStateSnapshot();\n const errors = Object.fromEntries(\n Object.entries(rootState.errors)\n .filter(([k]) => isScopedKey(k))\n .map(([k, v]) => [unscope(k), v]),\n );\n const touchedFields = rootState.touchedFields.filter(isScopedKey).map(unscope);\n const validatingFields = rootState.validatingFields.filter(isScopedKey).map(unscope);\n const isValid = Object.keys(errors).length === 0;\n const isDirty = [...ctx.dirty].some(isScopedKey);\n const isTouched = [...ctx.touched].some(isScopedKey);\n const isValidating = validatingFields.length > 0;\n\n return Object.freeze({\n errors: Object.freeze(errors) as FormState['errors'],\n isDirty,\n isLoading: rootState.isLoading,\n isSubmitting: rootState.isSubmitting,\n isTouched,\n isValid,\n isValidating,\n submitCount: rootState.submitCount,\n touchedFields: Object.freeze(touchedFields) as readonly string[],\n validatingFields: Object.freeze(validatingFields) as readonly string[],\n });\n }\n\n function scopedValues(): ScopedValues<TValues, P> {\n const sub: Record<string, unknown> = {};\n\n for (const [key, value] of ctx.store) {\n if (key.startsWith(pfxDot)) sub[key.slice(pfxDot.length)] = value;\n }\n\n return unflattenValues(sub) as ScopedValues<TValues, P>;\n }\n\n /**\n * Enumerate field paths within this scope's prefix, stripped to relative paths —\n * matching `scope.state`'s relative-path convention, not `state.touchedFields`'s\n * absolute-path convention. Same \"known field\" definition `scopedTouchAll()` uses.\n */\n function scopedListFields(): readonly string[] {\n const known = new Set<string>();\n\n for (const key of ctx.store.keys()) {\n if (isScopedKey(key)) known.add(unscope(key));\n }\n\n for (const key of ctx.validators.keys()) {\n if (isScopedKey(key)) known.add(unscope(key));\n }\n\n return Object.freeze([...known]);\n }\n\n function scopedTouchAll(): void {\n ctx.ensureNotDisposed();\n\n for (const name of ctx.store.keys()) {\n if (isScopedKey(name)) ctx.touched.add(name);\n }\n\n for (const name of ctx.validators.keys()) {\n if (isScopedKey(name)) ctx.touched.add(name);\n }\n\n ctx.requestNotify();\n }\n\n function scopedUntouchAll(): void {\n ctx.ensureNotDisposed();\n\n for (const name of [...ctx.touched]) {\n if (isScopedKey(name)) ctx.touched.delete(name);\n }\n\n ctx.requestNotify();\n }\n\n function scopedReset(): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.store.keys()]) {\n if (!isScopedKey(key)) continue;\n\n ctx.fieldCtrls.get(key)?.abort();\n ctx.fieldCtrls.delete(key);\n ctx.store.set(key, ctx.baseline.get(key));\n ctx.dirty.delete(key);\n ctx.touched.delete(key);\n\n if (ctx.fieldErrors.delete(key)) ctx.invalidateErrors();\n }\n\n ctx.requestNotify();\n }\n\n function scopedReplace(newValues: ScopedValues<TValues, P>): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.fieldCtrls.keys()]) {\n if (isScopedKey(key)) {\n ctx.fieldCtrls.get(key)?.abort();\n ctx.fieldCtrls.delete(key);\n }\n }\n\n const flat = flattenValues(newValues as Record<string, unknown>);\n\n for (const key of [...ctx.store.keys()]) {\n if (!isScopedKey(key)) continue;\n\n ctx.store.delete(key);\n ctx.baseline.delete(key);\n ctx.dirty.delete(key);\n ctx.touched.delete(key);\n ctx.fieldErrors.delete(key);\n }\n\n ctx.invalidateErrors();\n\n for (const [key, value] of Object.entries(flat)) {\n const full = pre(key);\n\n ctx.store.set(full, value);\n ctx.baseline.set(full, value);\n }\n\n ctx.requestNotify();\n }\n\n function scopedPatch(partial: Record<string, unknown>): void {\n ctx.ensureNotDisposed();\n\n const flat = flattenValues(partial);\n const changedKeys: string[] = [];\n\n for (const [key, value] of Object.entries(flat)) {\n const full = pre(key);\n\n ctx.baseline.set(full, value);\n ctx.store.set(full, value);\n ctx.dirty.delete(full);\n changedKeys.push(full);\n }\n\n ctx.requestNotify(changedKeys);\n }\n\n function scopedResetErrors(\n nextErrors?: Partial<Record<ErrorKeyOf<ScopedValues<TValues, P>>, string | undefined>>,\n ): void {\n ctx.ensureNotDisposed();\n\n for (const key of [...ctx.fieldErrors.keys()]) {\n if (isScopedKey(key)) ctx.fieldErrors.delete(key);\n }\n\n if (nextErrors) {\n for (const [key, message] of Object.entries(nextErrors)) {\n if (typeof message === 'string') ctx.fieldErrors.set(pre(key), message);\n }\n }\n\n ctx.invalidateErrors();\n ctx.requestNotify();\n }\n\n async function scopedValidate(\n nameOrFieldsOrSignal?: FlatKeyOf<ScopedValues<TValues, P>> | FlatKeyOf<ScopedValues<TValues, P>>[] | AbortSignal,\n signal?: AbortSignal,\n ): Promise<ValidateResult> {\n ctx.ensureNotDisposed();\n\n if (\n nameOrFieldsOrSignal !== undefined &&\n !Array.isArray(nameOrFieldsOrSignal) &&\n !(nameOrFieldsOrSignal instanceof AbortSignal)\n ) {\n // validate(name) — single field\n const prefixedName = pre(nameOrFieldsOrSignal as string) as FlatKeyOf<TValues>;\n\n await ctx.runValidationCore([prefixedName as string], 'partial', signal);\n\n const error = ctx.fieldErrors.get(prefixedName as string);\n\n return {\n errors: error !== undefined ? { [nameOrFieldsOrSignal as string]: error } : {},\n valid: error === undefined,\n };\n }\n\n if (Array.isArray(nameOrFieldsOrSignal)) {\n // validate(fields[]) — specific subset\n const prefixedFields = nameOrFieldsOrSignal.map((f) => pre(f as string)) as string[];\n\n await ctx.runValidationCore(prefixedFields, 'partial', signal);\n\n const errors: Record<string, string> = {};\n\n for (const pf of prefixedFields) {\n const msg = ctx.fieldErrors.get(pf);\n\n if (msg !== undefined) errors[unscope(pf)] = msg;\n }\n\n return { errors, valid: Object.keys(errors).length === 0 };\n }\n\n // validate(signal?) — all scoped fields\n const sig = nameOrFieldsOrSignal as AbortSignal | undefined;\n const fields = [...ctx.validators.keys()].filter(isScopedKey);\n\n await ctx.runValidationCore(fields, 'partial', sig);\n\n const errors: Record<string, string> = {};\n\n for (const [key, message] of ctx.fieldErrors) {\n if (isScopedKey(key)) errors[unscope(key)] = message;\n }\n\n return { errors, valid: Object.keys(errors).length === 0 };\n }\n\n async function scopedSubmit<TResult>(\n handler: (values: ScopedValues<TValues, P>) => MaybePromise<TResult>,\n ): Promise<SubmitResult<TResult>> {\n ctx.ensureNotDisposed();\n\n if (ctx.isSubmitting()) throw new ForgeSubmitError('submit() called while a submission is already in progress');\n\n ctx.root.batch(() => {\n ctx.incrementSubmitCount();\n ctx.setSubmitting(true);\n scopedTouchAll();\n });\n\n try {\n const fields = [...ctx.validators.keys()].filter(isScopedKey);\n\n await ctx.runValidationCore(fields, 'partial');\n\n ctx.ensureNotDisposed();\n\n const errors: Record<string, string> = {};\n\n for (const [key, message] of ctx.fieldErrors) {\n if (isScopedKey(key)) errors[unscope(key)] = message;\n }\n\n if (Object.keys(errors).length > 0) {\n return { errors, ok: false, type: 'validation' as const };\n }\n\n return { ok: true as const, value: await handler(scopedValues()) };\n } finally {\n ctx.setSubmitting(false);\n\n if (!ctx.isDisposed()) ctx.requestNotify();\n }\n }\n\n /**\n * Subscribe filtered to scoped fields only.\n * Errors, touchedFields, and validatingFields are remapped to relative paths.\n * `isValid`, `isDirty`, and `isTouched` reflect only fields within this scope's prefix.\n * `isSubmitting`, `isLoading`, `isValidating`, and `submitCount` reflect the full form.\n *\n * The listener fires only when the scoped projection changes — mutations outside this\n * prefix do not fire the listener.\n */\n function subscribeScoped(listener: (state: FormState) => void, options?: SubscribeOptions): Unsubscribe {\n // Track the previous scoped projection for equality comparison.\n let prevState: FormState | null = null;\n\n return ctx.root.subscribe(() => {\n const next = getScopedState();\n\n // Skip if no scoped-relevant state has changed.\n if (prevState) {\n const p = prevState;\n const errKeys = Object.keys(next.errors);\n const prevErrKeys = Object.keys(p.errors);\n const errorsMatch =\n errKeys.length === prevErrKeys.length && errKeys.every((k) => next.errors[k] === p.errors[k]);\n\n const touchedMatch =\n next.touchedFields.length === p.touchedFields.length &&\n next.touchedFields.every((v, i) => v === p.touchedFields[i]);\n\n const validatingMatch =\n next.validatingFields.length === p.validatingFields.length &&\n next.validatingFields.every((v, i) => v === p.validatingFields[i]);\n\n const flagsMatch =\n next.isDirty === p.isDirty &&\n next.isLoading === p.isLoading &&\n next.isSubmitting === p.isSubmitting &&\n next.isTouched === p.isTouched &&\n next.isValid === p.isValid &&\n next.isValidating === p.isValidating &&\n next.submitCount === p.submitCount;\n\n if (flagsMatch && errorsMatch && touchedMatch && validatingMatch) return;\n }\n\n prevState = next;\n listener(next);\n }, options);\n }\n\n function createScopedAdapter() {\n return {\n array(name: string): ArrayField {\n return ctx.root.array(pre(name) as FlatKeyOf<TValues>) as ArrayField;\n },\n clearError(name: string): void {\n ctx.root.clearError(pre(name) as ErrorKeyOf<TValues>);\n },\n connect(name: string, config?: ConnectOptions): ConnectionResult<unknown> {\n return ctx.root.connect(pre(name) as FlatKeyOf<TValues>, config) as ConnectionResult<unknown>;\n },\n field(name: string): FieldState<unknown> {\n return ctx.root.field(pre(name) as FlatKeyOf<TValues>) as FieldState<unknown>;\n },\n get(name: string): unknown {\n return ctx.root.get(pre(name) as FlatKeyOf<TValues>);\n },\n register(name: string, options?: RegisterFieldOptions<unknown>): Unsubscribe {\n return ctx.root.fields.register(\n pre(name) as FlatKeyOf<TValues>,\n options as RegisterFieldOptions<TypeAtPath<TValues, FlatKeyOf<TValues>>>,\n );\n },\n remove(name: string): void {\n ctx.root.fields.remove(pre(name) as FlatKeyOf<TValues>);\n },\n resetField(name: string): void {\n ctx.root.resetField(pre(name) as FlatKeyOf<TValues>);\n },\n set(name: string, value: unknown, options?: SetOptions): void {\n ctx.root.set(pre(name) as FlatKeyOf<TValues>, value as TypeAtPath<TValues, FlatKeyOf<TValues>>, options);\n },\n setError(name: string, message: string): void {\n ctx.root.setError(pre(name) as ErrorKeyOf<TValues>, message);\n },\n setValidator(name: string, validator?: FieldValidator): void {\n ctx.root.fields.setValidator(pre(name) as FlatKeyOf<TValues>, validator);\n },\n subscribeField(\n name: string,\n listener: (state: FieldState<unknown>) => void,\n options?: SubscribeOptions,\n ): Unsubscribe {\n return ctx.root.subscribeField(\n pre(name) as FlatKeyOf<TValues>,\n listener as (state: FieldState<TypeAtPath<TValues, FlatKeyOf<TValues>>>) => void,\n options,\n );\n },\n touch(name: string): void {\n ctx.root.touch(pre(name) as FlatKeyOf<TValues>);\n },\n untouch(name: string): void {\n ctx.root.untouch(pre(name) as FlatKeyOf<TValues>);\n },\n };\n }\n\n /* ---- Public scoped form object ---- */\n\n type S = ScopedValues<TValues, P>;\n\n const adapter = createScopedAdapter();\n\n return {\n array: (name) =>\n adapter.array(name as string) as ArrayField<\n TypeAtPath<S, typeof name> extends readonly (infer E)[] ? E : unknown\n >,\n batch: (fn) => ctx.root.batch(fn),\n clearError: (name) => adapter.clearError(name as string),\n connect: (name, config?) => adapter.connect(name as string, config) as ConnectionResult<TypeAtPath<S, typeof name>>,\n get disposalSignal() {\n return ctx.root.disposalSignal;\n },\n dispose: () => {\n /* Scoped forms share lifecycle with parent — call parentForm.dispose() to tear down */\n },\n get disposed() {\n return ctx.isDisposed();\n },\n field: (name) => adapter.field(name as string) as FieldState<TypeAtPath<S, typeof name>>,\n fields: {\n list: scopedListFields,\n register: (name, options?) => adapter.register(name as string, options as RegisterFieldOptions<unknown>),\n remove: (name) => adapter.remove(name as string),\n setValidator: (name, validator?) => adapter.setValidator(name as string, validator),\n },\n get: (name) => adapter.get(name as string) as TypeAtPath<S, typeof name>,\n get isLoading() {\n return ctx.root.isLoading;\n },\n get isSubmitting() {\n return ctx.root.isSubmitting;\n },\n patch: scopedPatch as Form<S>['patch'],\n replace: scopedReplace as Form<S>['replace'],\n reset: scopedReset,\n resetErrors: scopedResetErrors as Form<S>['resetErrors'],\n resetField: (name) => adapter.resetField(name as string),\n // Cast is irreducible: FormSnapshot<ScopedValues<TValues,P>> and FormSnapshot<TValues> are\n // structurally unrelated generic instantiations -- TS cannot verify one against the other.\n restore: (snap) => ctx.root.restore(snap as FormSnapshot<TValues>),\n scope: (subPrefix) => createScopedForm(ctx, pre(subPrefix as string)) as Form<ScopedValues<S, typeof subPrefix>>,\n set: (name, value, options?: SetOptions) => adapter.set(name as string, value, options),\n setError: (name, message) => adapter.setError(name as string, message),\n // Cast is irreducible: FormSnapshot<TValues> and FormSnapshot<ScopedValues<TValues,P>> are\n // structurally unrelated generic instantiations -- TS cannot verify one against the other.\n snapshot: () => ctx.root.snapshot() as FormSnapshot<S>,\n get state() {\n return getScopedState();\n },\n submit: scopedSubmit as Form<S>['submit'],\n submitOrThrow: async (handler) => {\n const result = await scopedSubmit(handler);\n\n if (!result.ok) throw new ForgeValidationError(result.errors as Record<string, string>);\n\n return result.value;\n },\n subscribe: (listener, options?) => ctx.root.subscribe(listener, options),\n subscribeField: (name, listener, options?) =>\n adapter.subscribeField(name as string, listener as (state: FieldState<unknown>) => void, options),\n subscribeScoped,\n [Symbol.asyncIterator]: () => ctx.root[Symbol.asyncIterator](),\n [Symbol.dispose]() {\n this.dispose();\n },\n touch: (name) => adapter.touch(name as string),\n touchAll: scopedTouchAll,\n untouch: (name) => adapter.untouch(name as string),\n untouchAll: scopedUntouchAll,\n validate: scopedValidate as Form<S>['validate'],\n validateStream(signal?) {\n const rootIter = ctx.root.validateStream(signal);\n\n const iter: AsyncIterableIterator<{ error: string | undefined; field: string }> = {\n async next() {\n for (;;) {\n const item = await rootIter.next();\n\n if (item.done) return item;\n\n if (isScopedKey(item.value.field))\n return { done: false, value: { error: item.value.error, field: unscope(item.value.field) } };\n }\n },\n return() {\n return rootIter.return ? rootIter.return() : Promise.resolve({ done: true as const, value: undefined });\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n\n return iter;\n },\n values: scopedValues,\n };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("../_utils.cjs"),t=require("../_dev.cjs"),n=require("./array.cjs");let r=require("@vielzeug/arsenal");function i(i){function a(t){let n=t;return e.assertSafeKey(n),i.store.get(n)}function o(){return i.cachedValues??=(0,r.unflattenPaths)(Object.fromEntries(i.store))}function s(e,t){i.baseline.get(e)===t?i.dirty.delete(e):i.dirty.add(e)}function c(t,n,r={}){i.ensureNotDisposed();let a=t;e.assertSafeKey(a),i.store.set(a,n),s(a,n),r.touched&&i.touched.add(a),i.requestNotify(a)}function l(t){let n=t;return e.assertSafeKey(n),i.getFieldSnapshot(n)}function u(t,n){i.ensureNotDisposed();let r=t;e.assertSafeKey(r),i.fieldErrors.set(r,n),i.invalidateErrors(),i.requestNotify(r)}function d(t){i.ensureNotDisposed();let n=t;e.assertSafeKey(n),i.fieldErrors.delete(n)&&(i.invalidateErrors(),i.requestNotify(n))}function f(t={}){i.ensureNotDisposed(),i.fieldErrors.clear();for(let[n,r]of Object.entries(t))e.assertSafeKey(n),typeof r==`string`&&i.fieldErrors.set(n,r);i.invalidateErrors(),i.requestNotify()}function p(n,r){/\.\d+(\.|$)/.test(n)&&!i.store.has(n)&&t.warn(`${r}('${e.sanitizeForLog(n,80)}'): path looks like an array item key. Array items are stored as whole arrays — register on the parent key instead.`)}function m(t,n){i.ensureNotDisposed();let r=t;e.assertSafeKey(r),p(r,`setValidator`),i.fieldCtrls.get(r)?.abort(),i.fieldCtrls.delete(r),n?i.validators.set(r,n):(i.validators.delete(r),i.fieldErrors.delete(r)&&(i.invalidateErrors(),i.requestNotify(r)))}function h(t,n={}){i.ensureNotDisposed();let r=t;return e.assertSafeKey(r),p(r,`fields.register`),n.validator!==void 0&&m(t,n.validator),n.defaultValue!==void 0&&!i.store.has(r)&&(i.store.set(r,n.defaultValue),i.baseline.set(r,n.defaultValue),i.requestNotify(r)),()=>{i.disposed||S(t)}}function g(){let e=new Set;for(let t of i.store.keys())e.add(t);for(let t of i.validators.keys())e.add(t);return Object.freeze([...e])}function _(t){i.ensureNotDisposed();let n=t;e.assertSafeKey(n),i.touched.add(n),i.requestNotify(n)}function v(t){i.ensureNotDisposed();let n=t;e.assertSafeKey(n),i.touched.delete(n)&&i.requestNotify(n)}function y(){i.ensureNotDisposed();for(let e of i.store.keys())i.touched.add(e);for(let e of i.validators.keys())i.touched.add(e);i.requestNotify()}function b(){i.ensureNotDisposed(),i.touched.clear(),i.requestNotify()}function x(t){i.ensureNotDisposed();let n=t;e.assertSafeKey(n),i.fieldCtrls.get(n)?.abort(),i.fieldCtrls.delete(n),i.store.set(n,i.baseline.get(n)),i.dirty.delete(n),i.touched.delete(n),i.fieldErrors.delete(n)&&i.invalidateErrors(),i.requestNotify(n)}function S(t){i.ensureNotDisposed();let n=t;e.assertSafeKey(n),i.store.delete(n),i.baseline.delete(n),i.dirty.delete(n),i.touched.delete(n),i.validators.delete(n),i.arrayCache.delete(n),i.fieldCtrls.get(n)?.abort(),i.fieldCtrls.delete(n),i.fieldErrors.delete(n)&&i.invalidateErrors(),i.requestNotify(n)}function C(){i.ensureNotDisposed();for(let e of i.runCtrls)e.abort();for(let e of i.fieldCtrls.values())e.abort();i.runCtrls.clear(),i.fieldCtrls.clear(),i.validatingRuns.clear(),i.store.clear(),i.fieldErrors.clear(),i.touched.clear(),i.dirty.clear(),i.submitCount=0,i.invalidateErrors();for(let[e,t]of i.baseline)i.store.set(e,t);i.requestNotify()}function w(e){i.ensureNotDisposed();for(let e of i.runCtrls)e.abort();for(let e of i.fieldCtrls.values())e.abort();i.runCtrls.clear(),i.fieldCtrls.clear(),i.validatingRuns.clear();let t=(0,r.flattenPaths)(e);i.store.clear(),i.baseline.clear(),i.fieldErrors.clear(),i.touched.clear(),i.dirty.clear(),i.submitCount=0,i.invalidateErrors();for(let[e,n]of Object.entries(t))i.store.set(e,n),i.baseline.set(e,n);i.requestNotify()}function T(e){i.ensureNotDisposed();let t=(0,r.flattenPaths)(e);for(let[e,n]of Object.entries(t))i.baseline.set(e,n),i.store.set(e,n),i.dirty.delete(e);i.requestNotify(Object.keys(t))}function E(t){i.ensureNotDisposed();let r=t;e.assertSafeKey(r);let a=i.arrayCache.get(r);if(a)return a;let o=n.createArrayField(t,i.store,c);return i.arrayCache.set(r,o),o}return{array:E,clearError:d,field:l,get:a,listFields:g,patch:T,registerField:h,removeField:S,replace:w,reset:C,resetErrors:f,resetField:x,set:c,setError:u,setValidator:m,touch:_,touchAll:y,untouch:v,untouchAll:b,values:o}}exports.createValueOps=i;
1
+ const e=require("../_dev.cjs"),t=require("../_utils.cjs"),n=require("./array.cjs");let r=require("@vielzeug/arsenal");function i(i){function a(e){let n=e;return t.assertSafeKey(n),i.store.get(n)}function o(){return i.cachedValues??=(0,r.unflattenPaths)(Object.fromEntries(i.store))}function s(e,t){i.baseline.get(e)===t?i.dirty.delete(e):i.dirty.add(e)}function c(e,n,r={}){i.ensureNotDisposed();let a=e;t.assertSafeKey(a),i.store.set(a,n),s(a,n),r.touched&&i.touched.add(a),i.requestNotify(a)}function l(e){let n=e;return t.assertSafeKey(n),i.getFieldSnapshot(n)}function u(e,n){i.ensureNotDisposed();let r=e;t.assertSafeKey(r),i.fieldErrors.set(r,n),i.invalidateErrors(),i.requestNotify(r)}function d(e){i.ensureNotDisposed();let n=e;t.assertSafeKey(n),i.fieldErrors.delete(n)&&(i.invalidateErrors(),i.requestNotify(n))}function f(e={}){i.ensureNotDisposed(),i.fieldErrors.clear();for(let[n,r]of Object.entries(e))t.assertSafeKey(n),typeof r==`string`&&i.fieldErrors.set(n,r);i.invalidateErrors(),i.requestNotify()}function p(n,r){/\.\d+(\.|$)/.test(n)&&!i.store.has(n)&&e.warn(`${r}('${t.sanitizeForLog(n,80)}'): path looks like an array item key. Array items are stored as whole arrays — register on the parent key instead.`)}function m(e,n){i.ensureNotDisposed();let r=e;t.assertSafeKey(r),p(r,`setValidator`),i.fieldCtrls.get(r)?.abort(),i.fieldCtrls.delete(r),n?i.validators.set(r,n):(i.validators.delete(r),i.fieldErrors.delete(r)&&(i.invalidateErrors(),i.requestNotify(r)))}function h(e,n={}){i.ensureNotDisposed();let r=e;return t.assertSafeKey(r),p(r,`fields.register`),n.validator!==void 0&&m(e,n.validator),n.defaultValue!==void 0&&!i.store.has(r)&&(i.store.set(r,n.defaultValue),i.baseline.set(r,n.defaultValue),i.requestNotify(r)),()=>{i.disposed||S(e)}}function g(){let e=new Set;for(let t of i.store.keys())e.add(t);for(let t of i.validators.keys())e.add(t);return Object.freeze([...e])}function _(e){i.ensureNotDisposed();let n=e;t.assertSafeKey(n),i.touched.add(n),i.requestNotify(n)}function v(e){i.ensureNotDisposed();let n=e;t.assertSafeKey(n),i.touched.delete(n)&&i.requestNotify(n)}function y(){i.ensureNotDisposed();for(let e of i.store.keys())i.touched.add(e);for(let e of i.validators.keys())i.touched.add(e);i.requestNotify()}function b(){i.ensureNotDisposed(),i.touched.clear(),i.requestNotify()}function x(e){i.ensureNotDisposed();let n=e;t.assertSafeKey(n),i.fieldCtrls.get(n)?.abort(),i.fieldCtrls.delete(n),i.store.set(n,i.baseline.get(n)),i.dirty.delete(n),i.touched.delete(n),i.fieldErrors.delete(n)&&i.invalidateErrors(),i.requestNotify(n)}function S(e){i.ensureNotDisposed();let n=e;t.assertSafeKey(n),i.store.delete(n),i.baseline.delete(n),i.dirty.delete(n),i.touched.delete(n),i.validators.delete(n),i.arrayCache.delete(n),i.fieldCtrls.get(n)?.abort(),i.fieldCtrls.delete(n),i.fieldErrors.delete(n)&&i.invalidateErrors(),i.requestNotify(n)}function C(){i.ensureNotDisposed();for(let e of i.runCtrls)e.abort();for(let e of i.fieldCtrls.values())e.abort();i.runCtrls.clear(),i.fieldCtrls.clear(),i.validatingRuns.clear(),i.store.clear(),i.fieldErrors.clear(),i.touched.clear(),i.dirty.clear(),i.submitCount=0,i.invalidateErrors();for(let[e,t]of i.baseline)i.store.set(e,t);i.requestNotify()}function w(e){i.ensureNotDisposed();for(let e of i.runCtrls)e.abort();for(let e of i.fieldCtrls.values())e.abort();i.runCtrls.clear(),i.fieldCtrls.clear(),i.validatingRuns.clear();let t=(0,r.flattenPaths)(e);i.store.clear(),i.baseline.clear(),i.fieldErrors.clear(),i.touched.clear(),i.dirty.clear(),i.submitCount=0,i.invalidateErrors();for(let[e,n]of Object.entries(t))i.store.set(e,n),i.baseline.set(e,n);i.requestNotify()}function T(e){i.ensureNotDisposed();let t=(0,r.flattenPaths)(e);for(let[e,n]of Object.entries(t))i.baseline.set(e,n),i.store.set(e,n),i.dirty.delete(e);i.requestNotify(Object.keys(t))}function E(e){i.ensureNotDisposed();let r=e;t.assertSafeKey(r);let a=i.arrayCache.get(r);if(a)return a;let o=n.createArrayField(e,i.store,c);return i.arrayCache.set(r,o),o}return{array:E,clearError:d,field:l,get:a,listFields:g,patch:T,registerField:h,removeField:S,replace:w,reset:C,resetErrors:f,resetField:x,set:c,setError:u,setValidator:m,touch:_,touchAll:y,untouch:v,untouchAll:b,values:o}}exports.createValueOps=i;
2
2
  //# sourceMappingURL=values.cjs.map