kerfjs 4.4.0 → 4.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +284 -104
  2. package/LICENSE +1 -1
  3. package/README.md +73 -54
  4. package/ai/cursorrules +130 -48
  5. package/ai/manifest.json +63 -5
  6. package/ai/skill.md +148 -65
  7. package/dist/actions.d.ts +1 -1
  8. package/dist/actions.js +4 -4
  9. package/dist/actions.js.map +1 -1
  10. package/dist/array-signal.js +5 -5
  11. package/dist/async.js +34 -24
  12. package/dist/async.js.map +1 -1
  13. package/dist/attach.d.ts +11 -8
  14. package/dist/attach.js +54 -4
  15. package/dist/attach.js.map +1 -1
  16. package/dist/{chunk-QIP723L4.js → chunk-5WRGJZV6.js} +4 -3
  17. package/dist/chunk-5WRGJZV6.js.map +1 -0
  18. package/dist/{chunk-GY4XV2UV.js → chunk-BDX3R4OM.js} +4 -3
  19. package/dist/chunk-BDX3R4OM.js.map +1 -0
  20. package/dist/{chunk-VVDJLWMP.js → chunk-CEQMZYLR.js} +2 -2
  21. package/dist/chunk-CEQMZYLR.js.map +1 -0
  22. package/dist/{chunk-KEZTD6H4.js → chunk-E5R5GNKE.js} +15 -5
  23. package/dist/chunk-E5R5GNKE.js.map +1 -0
  24. package/dist/{chunk-MRYM3O3V.js → chunk-ELXVRKY2.js} +12 -9
  25. package/dist/chunk-ELXVRKY2.js.map +1 -0
  26. package/dist/{chunk-U32TFTGZ.js → chunk-MK42GLPV.js} +3 -3
  27. package/dist/chunk-MK42GLPV.js.map +1 -0
  28. package/dist/{chunk-SUPUPSBE.js → chunk-QFUNWHKH.js} +42 -20
  29. package/dist/chunk-QFUNWHKH.js.map +1 -0
  30. package/dist/{chunk-SRWQKB33.js → chunk-V757BT6U.js} +206 -111
  31. package/dist/chunk-V757BT6U.js.map +1 -0
  32. package/dist/{chunk-YHH7OUFA.js → chunk-WKIPLNVO.js} +3 -3
  33. package/dist/chunk-WKIPLNVO.js.map +1 -0
  34. package/dist/{chunk-3APBEVHF.js → chunk-Y2FOYPBV.js} +3 -3
  35. package/dist/{chunk-3APBEVHF.js.map → chunk-Y2FOYPBV.js.map} +1 -1
  36. package/dist/{chunk-SAYPJ6XR.js → chunk-ZOIERTUW.js} +10 -6
  37. package/dist/chunk-ZOIERTUW.js.map +1 -0
  38. package/dist/dev.d.ts +9 -6
  39. package/dist/dev.js +66 -19
  40. package/dist/dev.js.map +1 -1
  41. package/dist/html.d.ts +1 -1
  42. package/dist/html.js +8 -7
  43. package/dist/html.js.map +1 -1
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.js +28 -19
  46. package/dist/index.js.map +1 -1
  47. package/dist/jsx-runtime.js +5 -5
  48. package/dist/list.d.ts +1 -1
  49. package/dist/list.js +304 -213
  50. package/dist/list.js.map +1 -1
  51. package/dist/overlay.d.ts +190 -280
  52. package/dist/overlay.js +471 -364
  53. package/dist/overlay.js.map +1 -1
  54. package/dist/remount.d.ts +5 -3
  55. package/dist/remount.js +29 -10
  56. package/dist/remount.js.map +1 -1
  57. package/dist/router.d.ts +1 -1
  58. package/dist/router.js +73 -28
  59. package/dist/router.js.map +1 -1
  60. package/dist/scope.d.ts +4 -3
  61. package/dist/scope.js +11 -10
  62. package/dist/scope.js.map +1 -1
  63. package/dist/testing.js +4 -4
  64. package/dist/timing.d.ts +3 -2
  65. package/dist/timing.js +5 -5
  66. package/dist/timing.js.map +1 -1
  67. package/llms.txt +13 -6
  68. package/package.json +35 -13
  69. package/setup/cli.mjs +90 -0
  70. package/setup/index.d.mts +37 -0
  71. package/setup/index.mjs +1347 -0
  72. package/setup/jsonc.mjs +201 -0
  73. package/setup/state.schema.json +56 -0
  74. package/dist/chunk-GY4XV2UV.js.map +0 -1
  75. package/dist/chunk-KEZTD6H4.js.map +0 -1
  76. package/dist/chunk-MRYM3O3V.js.map +0 -1
  77. package/dist/chunk-QIP723L4.js.map +0 -1
  78. package/dist/chunk-SAYPJ6XR.js.map +0 -1
  79. package/dist/chunk-SRWQKB33.js.map +0 -1
  80. package/dist/chunk-SUPUPSBE.js.map +0 -1
  81. package/dist/chunk-U32TFTGZ.js.map +0 -1
  82. package/dist/chunk-VVDJLWMP.js.map +0 -1
  83. package/dist/chunk-YHH7OUFA.js.map +0 -1
  84. /package/dist/{attrSelector-Cmu2ZoGO.d.ts → attr-Cmu2ZoGO.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import { devHooks } from './chunk-VVDJLWMP.js';
1
+ import { devHooks } from './chunk-CEQMZYLR.js';
2
2
  import { Signal, signal as signal$1, effect as effect$1 } from '@preact/signals-core';
3
3
  export { batch, computed } from '@preact/signals-core';
4
4
 
@@ -16,5 +16,5 @@ function effect(fn) {
16
16
  }
17
17
 
18
18
  export { effect, isSignal, signal };
19
- //# sourceMappingURL=chunk-3APBEVHF.js.map
20
- //# sourceMappingURL=chunk-3APBEVHF.js.map
19
+
20
+ //# sourceMappingURL=chunk-Y2FOYPBV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/reactive.ts"],"names":["coreSignal","coreEffect"],"mappings":";;;;AA0CO,SAAS,SAAS,KAAA,EAA0C;AACjE,EAAA,OAAO,KAAA,YAAiB,MAAA;AAC1B;AAEO,SAAS,OAAU,KAAA,EAAsB;AAC9C,EAAA,MAAM,UAAU,QAAA,CAAS,aAAA;AACzB,EAAA,IAAI,OAAA,EAAS,OAAO,OAAA,CAAW,KAAU,CAAA;AACzC,EAAA,OAAOA,SAAW,KAAU,CAAA;AAC9B;AAEO,SAAS,OAAO,EAAA,EAA2C;AAChE,EAAA,MAAM,OAAO,QAAA,CAAS,UAAA;AACtB,EAAA,OAAOC,QAAA,CAAW,IAAA,GAAO,IAAA,CAAK,EAAE,IAAI,EAAE,CAAA;AACxC","file":"chunk-3APBEVHF.js","sourcesContent":["/**\n * Re-exports of `@preact/signals-core`. Lets the rest of the codebase depend\n * on `'./reactive.js'` without naming the underlying lib, so swapping it out\n * later (or fronting it with a hand-rolled implementation) is a one-file\n * change.\n *\n * Two dev hook slots sit in front of the bare re-exports:\n *\n * - `signalFactory` replaces the constructor so writes to never-subscribed\n * signals can warn (`KERF_DEV_WARN_UNTRACKED_SIGNALS=1`).\n *\n * - `wrapEffect` wraps the user body so `delegate()` can detect that it's\n * running inside an effect (`KERF_DEV_WARN_DELEGATE_IN_EFFECT=1`).\n *\n * Both are `undefined` unless the consumer imported `kerfjs/dev`, so production\n * sees the bare `@preact/signals-core` exports behind one property read.\n *\n * ORDERING: `signalFactory` is resolved at signal-CREATION time, so signals\n * created before `kerfjs/dev` is installed stay plain and the untracked-signal\n * warning never sees them. Static imports hoist above a `await import()`, so a\n * module-scope signal in an imported module is created first. See\n * docs/11-dev-warnings.md for the install-ordering rules.\n */\n\nimport { effect as coreEffect,Signal,signal as coreSignal } from '@preact/signals-core';\n\nimport { devHooks } from './dev-hooks.js';\n\nexport {\n batch,\n computed,\n type ReadonlySignal,\n Signal,\n} from '@preact/signals-core';\n\n/**\n * Runtime type guard for a `@preact/signals-core` signal (both `signal()`\n * values and `computed()` values are `Signal` instances). Used by the JSX\n * runtime (KF-294) to detect a signal handed straight into an attribute or\n * text hole — the trigger for a fine-grained binding rather than a snapshot\n * stringify.\n */\nexport function isSignal(value: unknown): value is Signal<unknown> {\n return value instanceof Signal;\n}\n\nexport function signal<T>(value?: T): Signal<T> {\n const factory = devHooks.signalFactory;\n if (factory) return factory<T>(value as T);\n return coreSignal(value as T);\n}\n\nexport function effect(fn: () => void | (() => void)): () => void {\n const wrap = devHooks.wrapEffect;\n return coreEffect(wrap ? wrap(fn) : fn);\n}\n"]}
1
+ {"version":3,"sources":["../src/reactive.ts"],"names":["coreSignal","coreEffect"],"mappings":";;;;AA8CO,SAAS,SAAS,KAAA,EAA0C;AACjE,EAAA,OAAO,KAAA,YAAiB,MAAA;AAC1B;AAEO,SAAS,OAAU,KAAA,EAAsB;AAC9C,EAAA,MAAM,UAAU,QAAA,CAAS,aAAA;AACzB,EAAA,IAAI,OAAA,EAAS,OAAO,OAAA,CAAW,KAAU,CAAA;AACzC,EAAA,OAAOA,SAAW,KAAU,CAAA;AAC9B;AAEO,SAAS,OAAO,EAAA,EAA2C;AAChE,EAAA,MAAM,OAAO,QAAA,CAAS,UAAA;AACtB,EAAA,OAAOC,QAAA,CAAW,IAAA,GAAO,IAAA,CAAK,EAAE,IAAI,EAAE,CAAA;AACxC","file":"chunk-Y2FOYPBV.js","sourcesContent":["/**\n * Re-exports of `@preact/signals-core`. Lets the rest of the codebase depend\n * on `'./reactive.js'` without naming the underlying lib, so swapping it out\n * later (or fronting it with a hand-rolled implementation) is a one-file\n * change.\n *\n * Two dev hook slots sit in front of the bare re-exports:\n *\n * - `signalFactory` replaces the constructor so writes to never-subscribed\n * signals can warn (`KERF_DEV_WARN_UNTRACKED_SIGNALS=1`).\n *\n * - `wrapEffect` wraps the user body so `delegate()` can detect that it's\n * running inside an effect (`KERF_DEV_WARN_DELEGATE_IN_EFFECT=1`).\n *\n * Both are `undefined` unless the consumer imported `kerfjs/dev`, so production\n * sees the bare `@preact/signals-core` exports behind one property read.\n *\n * ORDERING: `signalFactory` is resolved at signal-CREATION time, so signals\n * created before `kerfjs/dev` is installed stay plain and the untracked-signal\n * warning never sees them. Static imports hoist above a `await import()`, so a\n * module-scope signal in an imported module is created first. See\n * docs/11-dev-warnings.md for the install-ordering rules.\n */\n\nimport {\n effect as coreEffect,\n Signal,\n signal as coreSignal,\n} from '@preact/signals-core';\n\nimport { devHooks } from './dev-hooks.js';\n\nexport {\n batch,\n computed,\n type ReadonlySignal,\n Signal,\n} from '@preact/signals-core';\n\n/**\n * Runtime type guard for a `@preact/signals-core` signal (both `signal()`\n * values and `computed()` values are `Signal` instances). Used by the JSX\n * runtime (KF-294) to detect a signal handed straight into an attribute or\n * text hole — the trigger for a fine-grained binding rather than a snapshot\n * stringify.\n */\nexport function isSignal(value: unknown): value is Signal<unknown> {\n return value instanceof Signal;\n}\n\nexport function signal<T>(value?: T): Signal<T> {\n const factory = devHooks.signalFactory;\n if (factory) return factory<T>(value as T);\n return coreSignal(value as T);\n}\n\nexport function effect(fn: () => void | (() => void)): () => void {\n const wrap = devHooks.wrapEffect;\n return coreEffect(wrap ? wrap(fn) : fn);\n}\n"]}
@@ -1,15 +1,19 @@
1
- import { signal } from './chunk-3APBEVHF.js';
2
- import { devHooks } from './chunk-VVDJLWMP.js';
1
+ import { signal } from './chunk-Y2FOYPBV.js';
2
+ import { devHooks } from './chunk-CEQMZYLR.js';
3
3
 
4
4
  // src/store.ts
5
5
  var REGISTRY = [];
6
6
  function defineStore(spec) {
7
7
  const internal = signal(spec.initial());
8
- const warnCtx = devHooks.narrowSet ? { warned: false } : null;
8
+ let warnCtx = null;
9
9
  const set = (next) => {
10
10
  const toRaw = devHooks.storeToRaw;
11
11
  const raw = toRaw ? toRaw(next) : next;
12
- if (warnCtx) devHooks.narrowSet?.(internal.value, raw, warnCtx);
12
+ const narrowSet = devHooks.narrowSet;
13
+ if (narrowSet) {
14
+ warnCtx ??= { warned: false };
15
+ narrowSet(internal.value, raw, warnCtx);
16
+ }
13
17
  internal.value = raw;
14
18
  };
15
19
  const get = () => {
@@ -39,5 +43,5 @@ function clearStoreRegistry() {
39
43
  }
40
44
 
41
45
  export { clearStoreRegistry, defineStore, resetAllStores };
42
- //# sourceMappingURL=chunk-SAYPJ6XR.js.map
43
- //# sourceMappingURL=chunk-SAYPJ6XR.js.map
46
+
47
+ //# sourceMappingURL=chunk-ZOIERTUW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/store.ts"],"names":[],"mappings":";;;;AAyCA,IAAM,WAAyC,EAAC;AAEzC,SAAS,YACd,IAAA,EACyB;AACzB,EAAA,MAAM,QAAA,GAA2B,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,CAAA;AAOtD,EAAA,IAAI,OAAA,GAAkC,IAAA;AAEtC,EAAA,MAAM,GAAA,GAAM,CAAC,IAAA,KAAuB;AAMlC,IAAA,MAAM,QAAQ,QAAA,CAAS,UAAA;AACvB,IAAA,MAAM,GAAA,GAAM,KAAA,GAAQ,KAAA,CAAM,IAAI,CAAA,GAAI,IAAA;AAClC,IAAA,MAAM,YAAY,QAAA,CAAS,SAAA;AAC3B,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,OAAA,KAAY,EAAE,QAAQ,KAAA,EAAM;AAC5B,MAAA,SAAA,CAAU,QAAA,CAAS,KAAA,EAAO,GAAA,EAAK,OAAO,CAAA;AAAA,IACxC;AACA,IAAA,QAAA,CAAS,KAAA,GAAQ,GAAA;AAAA,EACnB,CAAA;AAOA,EAAA,MAAM,MAAM,MAAwB;AAClC,IAAA,MAAM,IAAI,QAAA,CAAS,KAAA;AACnB,IAAA,MAAM,WAAW,QAAA,CAAS,aAAA;AAC1B,IAAA,IAAI,QAAA,IAAY,CAAA,KAAM,IAAA,IAAQ,OAAO,MAAM,QAAA,EAAU;AACnD,MAAA,OAAO,SAAS,CAAoB,CAAA;AAAA,IACtC;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,GAAG,CAAA;AAErC,EAAA,MAAM,KAAA,GAAiC;AAAA,IACrC,KAAA,EAAO,QAAA;AAAA,IACP,OAAA;AAAA,IACA,KAAA,GAAQ;AACN,MAAA,QAAA,CAAS,KAAA,GAAQ,KAAK,OAAA,EAAQ;AAAA,IAChC;AAAA,GACF;AAEA,EAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AACnB,EAAA,OAAO,KAAA;AACT;AAOO,SAAS,cAAA,GAAuB;AACrC,EAAA,KAAA,MAAW,CAAA,IAAK,QAAA,EAAU,CAAA,CAAE,KAAA,EAAM;AACpC;AAMO,SAAS,kBAAA,GAA2B;AACzC,EAAA,QAAA,CAAS,MAAA,GAAS,CAAA;AACpB","file":"chunk-ZOIERTUW.js","sourcesContent":["/**\n * `defineStore({ initial, actions })` — composable testable stores layered on\n * top of `reactive.ts`'s signals.\n *\n * Three rules:\n * 1. `state` is read-only. Consumers read via `state.value` or subscribe via\n * `effect()`. They cannot write directly.\n * 2. `actions` is the only mutation surface. All writes go through named\n * action functions. This is what makes stores testable — assert against\n * actions, not against arbitrary writes.\n * 3. `reset()` resets to `initial()`. Always defined; tests use it for\n * setup, lifecycle hooks (route change, sign-out, etc.) use it for\n * tear-down.\n *\n * A module-level registry tracks every store created via `defineStore()`;\n * `resetAllStores()` walks the registry and calls each `reset()`. Useful for\n * tests + project-switch / logout / route-reset scenarios where every piece\n * of client state should return to its initial shape.\n */\n\nimport { devHooks, type WarnOnceContext } from './dev-hooks.js';\nimport type { ReadonlySignal, Signal } from './reactive.js';\nimport { signal } from './reactive.js';\n\nexport interface Store<TState, TActions> {\n /** Read-only reactive view. Consumers read `state.value` or subscribe via `effect()`. */\n readonly state: ReadonlySignal<TState>;\n /** Named mutators — the only way to change state. */\n readonly actions: TActions;\n /** Reset state to `initial()`. Used by tests and lifecycle hooks. */\n reset(): void;\n}\n\ninterface DefineStoreSpec<TState, TActions> {\n initial: () => TState;\n actions: (\n set: (next: TState) => void,\n get: () => Readonly<TState>,\n ) => TActions;\n}\n\nconst REGISTRY: Array<{ reset: () => void }> = [];\n\nexport function defineStore<TState, TActions>(\n spec: DefineStoreSpec<TState, TActions>,\n): Store<TState, TActions> {\n const internal: Signal<TState> = signal(spec.initial());\n // KF-212: per-store one-shot dedup for the opt-in narrow-set warning.\n // Default off; consumers opt in via `KERF_DEV_WARN_NARROW_SET=1` in dev.\n // Resolve the hook on each set(), so a store created before `kerfjs/dev` is\n // installed starts warning as soon as the diagnostics become available.\n // Allocate the context lazily — production never pays for an object it will\n // never read.\n let warnCtx: WarnOnceContext | null = null;\n\n const set = (next: TState): void => {\n // With `kerfjs/dev` installed, `next` may carry proxies handed back by the\n // `get()` trap (e.g. `set({ ...get(), count: 1 })`). Unwrap them so the\n // internal signal only ever holds a plain object — the narrow-set warning\n // and every consumer read see raw state, never a Proxy. Production stores\n // the bare reference.\n const toRaw = devHooks.storeToRaw;\n const raw = toRaw ? toRaw(next) : next;\n const narrowSet = devHooks.narrowSet;\n if (narrowSet) {\n warnCtx ??= { warned: false };\n narrowSet(internal.value, raw, warnCtx);\n }\n internal.value = raw;\n };\n // With the diagnostics installed, wrap the reference returned to actions in a\n // deep read-only Proxy so that `get().count = 42` / `get().nested.x = 1`\n // (documented Rule 8 violations) throw a `TypeError` instead of silently\n // landing on the underlying state without notifying subscribers. The live\n // state object is never frozen or mutated, so external references to it stay\n // writable. Production returns the bare reference — no proxy, no wrapping.\n const get = (): Readonly<TState> => {\n const v = internal.value;\n const readonly = devHooks.storeReadonly;\n if (readonly && v !== null && typeof v === 'object') {\n return readonly(v as TState & object);\n }\n return v;\n };\n\n const actions = spec.actions(set, get);\n\n const store: Store<TState, TActions> = {\n state: internal,\n actions,\n reset() {\n internal.value = spec.initial();\n },\n };\n\n REGISTRY.push(store);\n return store;\n}\n\n/**\n * Reset every store registered via `defineStore()` to its `initial()` value.\n * Used by tests and by application lifecycle hooks (project switch, logout,\n * route reset).\n */\nexport function resetAllStores(): void {\n for (const s of REGISTRY) s.reset();\n}\n\n/**\n * Test helper — clears the registry. Exposed via the `kerfjs/testing` subpath,\n * not the main `kerfjs` entry. Unit tests use it to isolate stores between cases.\n */\nexport function clearStoreRegistry(): void {\n REGISTRY.length = 0;\n}\n"]}
package/dist/dev.d.ts CHANGED
@@ -115,9 +115,11 @@ interface ListBinding {
115
115
  * those before paying the cost, exactly as it checked the old `isOptedIn()`
116
116
  * exports.
117
117
  *
118
- * Each warner keeps its own internal opt-in check (the `KERF_DEV_WARN_*` env
119
- * reads). Installation decides whether the diagnostics are *present*; the
120
- * individual warner still decides whether it is *switched on*.
118
+ * Each opt-in warner keeps its own internal switch check through `devFlag()`;
119
+ * an `enableWarnings()` override wins over the matching `KERF_DEV_WARN_*`
120
+ * environment variable. Installation decides whether the diagnostics are
121
+ * *present*; the opt-in warner decides whether it is *switched on*. Always-on
122
+ * hooks skip that second gate.
121
123
  *
122
124
  * @see docs/11-dev-warnings.md
123
125
  */
@@ -295,9 +297,10 @@ interface DevWarningOptions {
295
297
  * `Signal.prototype`'s `value` accessor is non-configurable, and reaching live
296
298
  * instances would require a per-signal registry that production would pay for.
297
299
  *
298
- * Installation decides whether the diagnostics are PRESENT; each individual
299
- * warner still reads its own `KERF_DEV_WARN_*` env var to decide whether it is
300
- * switched ON. That keeps the existing opt-in contract intact.
300
+ * Installation decides whether the diagnostics are PRESENT. Each opt-in
301
+ * warner then reads its own switch through `devFlag()`: an `enableWarnings()`
302
+ * override wins over the matching `KERF_DEV_WARN_*` environment variable.
303
+ * The always-on hooks skip that second gate.
301
304
  *
302
305
  * @see docs/11-dev-warnings.md
303
306
  */
package/dist/dev.js CHANGED
@@ -1,7 +1,7 @@
1
- import { truncateRowHtml } from './chunk-YHH7OUFA.js';
2
- import { LIST_MARKER_PREFIX } from './chunk-GY4XV2UV.js';
3
- import { installDevHooks } from './chunk-VVDJLWMP.js';
4
- export { clearDevHooks, devHooks, installDevHooks } from './chunk-VVDJLWMP.js';
1
+ import { truncateRowHtml } from './chunk-WKIPLNVO.js';
2
+ import { LIST_MARKER_PREFIX } from './chunk-BDX3R4OM.js';
3
+ import { installDevHooks } from './chunk-CEQMZYLR.js';
4
+ export { clearDevHooks, devHooks, installDevHooks } from './chunk-CEQMZYLR.js';
5
5
  import { signal, Signal } from '@preact/signals-core';
6
6
 
7
7
  // src/dev-warn-config.ts
@@ -24,7 +24,10 @@ function applyWarningOptions(options) {
24
24
  for (const [key, value] of Object.entries(options)) {
25
25
  const envName = ENV_NAME[key];
26
26
  if (envName === void 0 || value === void 0) continue;
27
- overrides.set(envName, value === false ? false : value === true ? "1" : value);
27
+ overrides.set(
28
+ envName,
29
+ value === false ? false : value === true ? "1" : value
30
+ );
28
31
  }
29
32
  }
30
33
  function devFlag(envName) {
@@ -157,18 +160,38 @@ function findListInvariantViolations(rootEl, bindings, expectedCounts) {
157
160
  const { marker, liveParent, items } = binding;
158
161
  const expected = expectedCounts?.get(id);
159
162
  if (expected !== void 0 && items.length !== expected) {
160
- problems.push(describe(id, `holds ${items.length} row(s) but its source has ${expected} \u2014 the reconcile dropped or duplicated rows`));
163
+ problems.push(
164
+ describe(
165
+ id,
166
+ `holds ${items.length} row(s) but its source has ${expected} \u2014 the reconcile dropped or duplicated rows`
167
+ )
168
+ );
161
169
  }
162
170
  if (!rootEl.contains(marker)) {
163
- problems.push(describe(id, "its marker comment is no longer inside the mount root, so every future reconcile would mutate a detached tree"));
171
+ problems.push(
172
+ describe(
173
+ id,
174
+ "its marker comment is no longer inside the mount root, so every future reconcile would mutate a detached tree"
175
+ )
176
+ );
164
177
  continue;
165
178
  }
166
179
  if (marker.data !== `${LIST_MARKER_PREFIX}${id}`) {
167
- problems.push(describe(id, `its marker reads '${marker.data}' \u2014 the id is carried by a different marker node, so this binding describes another list`));
180
+ problems.push(
181
+ describe(
182
+ id,
183
+ `its marker reads '${marker.data}' \u2014 the id is carried by a different marker node, so this binding describes another list`
184
+ )
185
+ );
168
186
  }
169
187
  const markerIndex = indexIn(liveParent, marker);
170
188
  if (markerIndex === -1) {
171
- problems.push(describe(id, "its marker is not a child of the parent the binding records"));
189
+ problems.push(
190
+ describe(
191
+ id,
192
+ "its marker is not a child of the parent the binding records"
193
+ )
194
+ );
172
195
  continue;
173
196
  }
174
197
  let previousIndex = markerIndex;
@@ -177,28 +200,46 @@ function findListInvariantViolations(rootEl, bindings, expectedCounts) {
177
200
  const node = items[i].node;
178
201
  const index = indexIn(liveParent, node);
179
202
  if (index === -1) {
180
- problems.push(describe(id, `bound row ${i} is not a child of the list's parent (<${liveParent.tagName.toLowerCase()}>)${node.isConnected ? " \u2014 it is attached elsewhere in the document" : " \u2014 it is detached"}`));
203
+ problems.push(
204
+ describe(
205
+ id,
206
+ `bound row ${i} is not a child of the list's parent (<${liveParent.tagName.toLowerCase()}>)${node.isConnected ? " \u2014 it is attached elsewhere in the document" : " \u2014 it is detached"}`
207
+ )
208
+ );
181
209
  continue;
182
210
  }
183
211
  if (index <= previousIndex) {
184
- problems.push(describe(id, `bound row ${i} appears at child position ${index}, which is not after the previous one (${previousIndex}) \u2014 the rows are out of order or have crossed the marker`));
212
+ problems.push(
213
+ describe(
214
+ id,
215
+ `bound row ${i} appears at child position ${index}, which is not after the previous one (${previousIndex}) \u2014 the rows are out of order or have crossed the marker`
216
+ )
217
+ );
185
218
  }
186
219
  previousIndex = index;
187
220
  if (first === -1) first = index;
188
221
  const owner = owners.get(node);
189
222
  if (owner !== void 0) {
190
- problems.push(describe(id, `bound row ${i} is also claimed by list '${owner}'`));
223
+ problems.push(
224
+ describe(id, `bound row ${i} is also claimed by list '${owner}'`)
225
+ );
191
226
  } else {
192
227
  owners.set(node, id);
193
228
  }
194
229
  }
195
- if (first !== -1) spans.push({ id, parent: liveParent, from: first, to: previousIndex });
230
+ if (first !== -1)
231
+ spans.push({ id, parent: liveParent, from: first, to: previousIndex });
196
232
  }
197
233
  for (let a = 0; a < spans.length; a++) {
198
234
  for (let b = a + 1; b < spans.length; b++) {
199
235
  if (spans[a].parent !== spans[b].parent) continue;
200
236
  if (spans[a].from <= spans[b].to && spans[b].from <= spans[a].to) {
201
- problems.push(describe(spans[a].id, `its rows (child positions ${spans[a].from}-${spans[a].to}) overlap those of list '${spans[b].id}' (${spans[b].from}-${spans[b].to}) in the same parent`));
237
+ problems.push(
238
+ describe(
239
+ spans[a].id,
240
+ `its rows (child positions ${spans[a].from}-${spans[a].to}) overlap those of list '${spans[b].id}' (${spans[b].from}-${spans[b].to}) in the same parent`
241
+ )
242
+ );
202
243
  }
203
244
  }
204
245
  }
@@ -207,7 +248,11 @@ function findListInvariantViolations(rootEl, bindings, expectedCounts) {
207
248
  function maybeCheckListInvariants(rootEl, bindings, expectedCounts) {
208
249
  const level = mode();
209
250
  if (level === "off") return;
210
- const problems = findListInvariantViolations(rootEl, bindings, expectedCounts);
251
+ const problems = findListInvariantViolations(
252
+ rootEl,
253
+ bindings,
254
+ expectedCounts
255
+ );
211
256
  if (problems.length === 0) return;
212
257
  const report = `${problems.join("\n")}
213
258
  This is a kerf bug, not an application one \u2014 please report it with the markup that produced it. Set KERF_DEV_INVARIANTS=1 to warn instead of throw, or unset it to disable these checks.`;
@@ -277,12 +322,14 @@ function patchAddEventListenerOnce() {
277
322
  };
278
323
  }
279
324
  function hasMarkedListener(el) {
280
- if (el[LISTENER_MARKER] === true) return true;
325
+ if (el[LISTENER_MARKER] === true)
326
+ return true;
281
327
  const stack = [];
282
328
  for (let i = 0; i < el.children.length; i++) stack.push(el.children[i]);
283
329
  while (stack.length > 0) {
284
330
  const cur = stack.pop();
285
- if (cur[LISTENER_MARKER] === true) return true;
331
+ if (cur[LISTENER_MARKER] === true)
332
+ return true;
286
333
  for (let i = 0; i < cur.children.length; i++) stack.push(cur.children[i]);
287
334
  }
288
335
  return false;
@@ -491,7 +538,7 @@ function maybeWarnNarrowSet(prev, next, ctx) {
491
538
  console.warn(`${WARNING_PREFIX}${keysList}${WARNING_SUFFIX}`);
492
539
  }
493
540
 
494
- // src/utils/devReadonly.ts
541
+ // src/utils/dev-readonly.ts
495
542
  var RULE_MESSAGE = "kerf: store state is read-only \u2014 all writes must go through actions (build a new state object and pass it to `set()`). Mutating the object returned by `get()` is a Rule 8 violation and never notifies subscribers.";
496
543
  var proxyToRaw = /* @__PURE__ */ new WeakMap();
497
544
  var rawToProxy = /* @__PURE__ */ new WeakMap();
@@ -603,5 +650,5 @@ installDevHooks(DEV_HOOKS);
603
650
  if (isDevWarnUntrackedEnabled()) noteUntrackedCoverage();
604
651
 
605
652
  export { DEV_HOOKS, enableWarnings };
606
- //# sourceMappingURL=dev.js.map
653
+
607
654
  //# sourceMappingURL=dev.js.map