@epoch32/visage 1.3.0 → 1.3.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 (44) hide show
  1. package/dist/api/index.js +4 -4
  2. package/dist/charts/index.js +5 -5
  3. package/dist/devtools/index.js +7 -7
  4. package/dist/dom/index.js +3 -3
  5. package/dist/form/index.js +2 -2
  6. package/dist/{index-grhdtcb5.js → index-0qat98zs.js} +3 -3
  7. package/dist/{index-h6tjqk6e.js → index-1jcd8gjf.js} +28 -17
  8. package/dist/{index-6kfe1nr4.js → index-1yhbg34h.js} +41 -9
  9. package/dist/{index-9fvarkrx.js → index-3y73zgbk.js} +1 -1
  10. package/dist/{index-y9bq7h9g.js → index-5jhzwtdz.js} +2 -2
  11. package/dist/{index-a4xns6cc.js → index-65j7a9et.js} +1 -1
  12. package/dist/{index-dyvgtp43.js → index-9bez1tmf.js} +2 -2
  13. package/dist/{index-dvq5f3s8.js → index-aagpn02x.js} +4 -4
  14. package/dist/{index-df5e614s.js → index-awcrz19g.js} +1 -1
  15. package/dist/{index-8x8xz80v.js → index-b7emqmej.js} +3 -3
  16. package/dist/{index-061jf06a.js → index-cgepvvd4.js} +1 -1
  17. package/dist/{index-1xtrtz1t.js → index-dmhmde2z.js} +2 -2
  18. package/dist/{index-0madxn60.js → index-enc8cmea.js} +1 -1
  19. package/dist/{index-js199er4.js → index-g1drdx7k.js} +12 -1
  20. package/dist/{index-zr6cvset.js → index-ptj8rt6b.js} +5 -5
  21. package/dist/{index-8czhpea8.js → index-x6whpv54.js} +30 -19
  22. package/dist/{index-5s255b3w.js → index-xby428n5.js} +23 -22
  23. package/dist/{index-x2rs3vab.js → index-y3nprgn7.js} +1 -1
  24. package/dist/index.js +18 -18
  25. package/dist/jsx-runtime/index.js +4 -4
  26. package/dist/query/index.js +3 -3
  27. package/dist/router/index.js +5 -5
  28. package/dist/rpc/index.js +4 -4
  29. package/dist/server/index.js +2 -2
  30. package/dist/signals/index.js +1 -1
  31. package/dist/signals/system.d.ts +2 -0
  32. package/dist/style/index.js +6 -6
  33. package/dist/template/index.js +2 -2
  34. package/dist/ui/index.js +7 -7
  35. package/dist/virtual/index.js +5 -5
  36. package/package.json +1 -1
  37. package/src/dom/control-flow.ts +31 -21
  38. package/src/form/form.ts +29 -17
  39. package/src/signals/effect.ts +2 -2
  40. package/src/signals/scope.ts +10 -8
  41. package/src/signals/store.ts +32 -1
  42. package/src/signals/system.ts +8 -0
  43. package/src/template/template.ts +12 -1
  44. package/src/virtual/virtualizer.ts +31 -18
package/dist/api/index.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  defineMiddleware2,
17
17
  ProcedureBuilder2,
18
18
  procedure2
19
- } from "../index-061jf06a.js";
19
+ } from "../index-cgepvvd4.js";
20
20
  import {
21
21
  ERROR_CODE_TO_STATUS2,
22
22
  STATUS_TO_ERROR_CODE2,
@@ -27,9 +27,9 @@ import {
27
27
  validateWithSchema2,
28
28
  v2
29
29
  } from "../index-2zz0g2n2.js";
30
- import"../index-y9bq7h9g.js";
31
- import"../index-a4xns6cc.js";
32
- import"../index-6kfe1nr4.js";
30
+ import"../index-5jhzwtdz.js";
31
+ import"../index-65j7a9et.js";
32
+ import"../index-1yhbg34h.js";
33
33
  export {
34
34
  ERROR_CODE_TO_STATUS2 as ERROR_CODE_TO_STATUS,
35
35
  ProcedureBuilder2 as ProcedureBuilder,
@@ -1,6 +1,6 @@
1
- import"../index-6kfe1nr4.js";
2
- import"../index-5s255b3w.js";
3
- import"../index-9fvarkrx.js";
1
+ import"../index-1yhbg34h.js";
2
+ import"../index-xby428n5.js";
3
+ import"../index-3y73zgbk.js";
4
4
  import {
5
5
  ChartContext2,
6
6
  useChartContext2,
@@ -23,8 +23,8 @@ import {
23
23
  Pie2,
24
24
  ChartTooltip2,
25
25
  Tooltip2
26
- } from "../index-dyvgtp43.js";
27
- import"../index-a4xns6cc.js";
26
+ } from "../index-9bez1tmf.js";
27
+ import"../index-65j7a9et.js";
28
28
  export {
29
29
  Area2 as Area,
30
30
  Bar2 as Bar,
@@ -4,13 +4,13 @@ import {
4
4
  highlightElement2,
5
5
  VisageDevTools2,
6
6
  connectDevTools2
7
- } from "../index-zr6cvset.js";
8
- import"../index-8x8xz80v.js";
9
- import"../index-0madxn60.js";
10
- import"../index-9fvarkrx.js";
11
- import"../index-5s255b3w.js";
12
- import"../index-a4xns6cc.js";
13
- import"../index-6kfe1nr4.js";
7
+ } from "../index-ptj8rt6b.js";
8
+ import"../index-b7emqmej.js";
9
+ import"../index-enc8cmea.js";
10
+ import"../index-3y73zgbk.js";
11
+ import"../index-xby428n5.js";
12
+ import"../index-65j7a9et.js";
13
+ import"../index-1yhbg34h.js";
14
14
  export {
15
15
  DevToolsHub2 as DevToolsHub,
16
16
  VisageDevTools2 as VisageDevTools,
package/dist/dom/index.js CHANGED
@@ -3,20 +3,20 @@ import {
3
3
  Show2,
4
4
  For2,
5
5
  Portal2
6
- } from "../index-5s255b3w.js";
6
+ } from "../index-xby428n5.js";
7
7
  import {
8
8
  SuspenseContext2,
9
9
  createResource2,
10
10
  Suspense2,
11
11
  ErrorBoundary2
12
- } from "../index-a4xns6cc.js";
12
+ } from "../index-65j7a9et.js";
13
13
  import {
14
14
  isReactive2,
15
15
  resolveValue2,
16
16
  render2,
17
17
  setAttribute2,
18
18
  insertChild2
19
- } from "../index-6kfe1nr4.js";
19
+ } from "../index-1yhbg34h.js";
20
20
  export {
21
21
  ErrorBoundary2 as ErrorBoundary,
22
22
  For2 as For,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createForm2
3
- } from "../index-h6tjqk6e.js";
3
+ } from "../index-1jcd8gjf.js";
4
4
  import {
5
5
  Schema2,
6
6
  validateWithSchema2,
7
7
  v2
8
8
  } from "../index-2zz0g2n2.js";
9
- import"../index-6kfe1nr4.js";
9
+ import"../index-1yhbg34h.js";
10
10
  export {
11
11
  Schema2 as Schema,
12
12
  createForm2 as createForm,
@@ -4,13 +4,13 @@ import {
4
4
  createContext2,
5
5
  useContext2,
6
6
  signal2
7
- } from "./index-6kfe1nr4.js";
7
+ } from "./index-1yhbg34h.js";
8
8
  import {
9
9
  Show2
10
- } from "./index-5s255b3w.js";
10
+ } from "./index-xby428n5.js";
11
11
  import {
12
12
  jsx2
13
- } from "./index-9fvarkrx.js";
13
+ } from "./index-3y73zgbk.js";
14
14
  // src/router/router.tsx
15
15
  var RouterContext = createContext2(null);
16
16
  function compilePath(path) {
@@ -2,7 +2,7 @@ import {
2
2
  batch2,
3
3
  computed2,
4
4
  signal2
5
- } from "./index-6kfe1nr4.js";
5
+ } from "./index-1yhbg34h.js";
6
6
  import {
7
7
  validateWithSchema2
8
8
  } from "./index-2zz0g2n2.js";
@@ -15,6 +15,30 @@ function createForm2(options) {
15
15
  const isSubmitting = signal2(false);
16
16
  const submitCount = signal2(0);
17
17
  const customErrors = signal2({});
18
+ const getValues = () => {
19
+ const res = {};
20
+ for (const key in fields) {
21
+ res[key] = fields[key].value();
22
+ }
23
+ return res;
24
+ };
25
+ const schemaValidation = computed2(() => {
26
+ if (!options.schema) {
27
+ return { success: true, issuesMap: new Map };
28
+ }
29
+ const currentValues = getValues();
30
+ const res = validateWithSchema2(options.schema, currentValues);
31
+ const issuesMap = new Map;
32
+ if (!res.success && res.issues) {
33
+ for (const issue of res.issues) {
34
+ const pathKey = String(issue.path);
35
+ if (!issuesMap.has(pathKey)) {
36
+ issuesMap.set(pathKey, issue.message);
37
+ }
38
+ }
39
+ }
40
+ return { success: res.success, issuesMap };
41
+ });
18
42
  for (const key in initialValues) {
19
43
  const initVal = initialValues[key];
20
44
  const valSignal = signal2(initVal);
@@ -33,23 +57,11 @@ function createForm2(options) {
33
57
  }
34
58
  if (!options.schema)
35
59
  return null;
36
- const currentValues = getValues();
37
- const res = validateWithSchema2(options.schema, currentValues);
38
- if (!res.success && res.issues) {
39
- const match = res.issues.find((i) => i.path === key || i.path === `${key}`);
40
- return match ? match.message : null;
41
- }
42
- return null;
60
+ const validation = schemaValidation();
61
+ return validation.issuesMap.get(key) ?? validation.issuesMap.get(String(key)) ?? null;
43
62
  })
44
63
  };
45
64
  }
46
- const getValues = () => {
47
- const res = {};
48
- for (const key in fields) {
49
- res[key] = fields[key].value();
50
- }
51
- return res;
52
- };
53
65
  const errors = computed2(() => {
54
66
  const errMap = {};
55
67
  for (const key in fields) {
@@ -74,8 +86,7 @@ function createForm2(options) {
74
86
  const validate = () => {
75
87
  if (!options.schema)
76
88
  return true;
77
- const res = validateWithSchema2(options.schema, getValues());
78
- return res.success;
89
+ return schemaValidation().success;
79
90
  };
80
91
  const handleSubmit = async (e) => {
81
92
  if (e?.preventDefault) {
@@ -52,6 +52,9 @@ function addPendingEffect(eff) {
52
52
  function removePendingEffect(eff) {
53
53
  ctx.pendingEffects.delete(eff);
54
54
  }
55
+ function getBatchDepth() {
56
+ return ctx.batchDepth;
57
+ }
55
58
  var MAX_FLUSH_COUNT = 100;
56
59
  function flushEffects() {
57
60
  if (ctx.isFlushing || ctx.batchDepth > 0)
@@ -680,7 +683,7 @@ class Scope2 {
680
683
  parent = null;
681
684
  isDisposed = false;
682
685
  context;
683
- constructor(parent = currentScope) {
686
+ constructor(parent = getCurrentScope()) {
684
687
  this.parent = parent;
685
688
  if (parent && !parent.isDisposed) {
686
689
  parent.cleanups.push(() => this.dispose());
@@ -720,14 +723,16 @@ class Scope2 {
720
723
  }
721
724
  }
722
725
  function onCleanup2(fn) {
723
- if (currentSubscriber && "addCleanup" in currentSubscriber) {
724
- currentSubscriber.addCleanup(fn);
725
- } else if (currentScope) {
726
- currentScope.addCleanup(fn);
726
+ const curSub = getCurrentSubscriber();
727
+ const curScope = getCurrentScope();
728
+ if (curSub && "addCleanup" in curSub) {
729
+ curSub.addCleanup(fn);
730
+ } else if (curScope) {
731
+ curScope.addCleanup(fn);
727
732
  }
728
733
  }
729
734
  function createRoot2(fn) {
730
- const prevScope = currentScope;
735
+ const prevScope = getCurrentScope();
731
736
  const scope = new Scope2(null);
732
737
  setCurrentScope(scope);
733
738
  try {
@@ -737,7 +742,7 @@ function createRoot2(fn) {
737
742
  }
738
743
  }
739
744
  function runInScope2(scope, fn) {
740
- const prevScope = currentScope;
745
+ const prevScope = getCurrentScope();
741
746
  setCurrentScope(scope);
742
747
  try {
743
748
  return fn();
@@ -820,7 +825,7 @@ class Effect2 {
820
825
  }
821
826
  this.state = targetState;
822
827
  addPendingEffect(this);
823
- if (batchDepth === 0) {
828
+ if (getBatchDepth() === 0) {
824
829
  flushEffects();
825
830
  }
826
831
  }
@@ -1085,6 +1090,7 @@ function createSignal2(initialValue, optionsOrEquals) {
1085
1090
  var STORE_RAW = Symbol("visage.store.raw");
1086
1091
  var STORE_SIGNALS = Symbol("visage.store.signals");
1087
1092
  var STORE_PROXY = Symbol("visage.store.proxy");
1093
+ var STORE_ITERATE = Symbol("visage.store.iterate");
1088
1094
  function isObject(val) {
1089
1095
  return typeof val === "object" && val !== null && (typeof Node === "undefined" || !(val instanceof Node)) && !isSignal2(val);
1090
1096
  }
@@ -1126,18 +1132,42 @@ function createStoreProxy(target) {
1126
1132
  }
1127
1133
  return value;
1128
1134
  },
1135
+ has(target, prop) {
1136
+ if (prop === STORE_RAW || prop === STORE_PROXY)
1137
+ return true;
1138
+ if (typeof prop === "string" || typeof prop === "symbol") {
1139
+ const sig = getOrCreatePropertySignal(target, prop);
1140
+ sig.get();
1141
+ }
1142
+ return Reflect.has(target, prop);
1143
+ },
1144
+ ownKeys(target) {
1145
+ const iterSig = getOrCreatePropertySignal(target, STORE_ITERATE);
1146
+ iterSig.get();
1147
+ return Reflect.ownKeys(target);
1148
+ },
1149
+ getOwnPropertyDescriptor(target, prop) {
1150
+ return Reflect.getOwnPropertyDescriptor(target, prop);
1151
+ },
1129
1152
  set(target, prop, value, receiver) {
1153
+ const hadProp = Reflect.has(target, prop);
1130
1154
  const prevValue = Reflect.get(target, prop, receiver);
1131
- if (Object.is(prevValue, value)) {
1155
+ if (hadProp && Object.is(prevValue, value)) {
1132
1156
  return true;
1133
1157
  }
1134
1158
  const success = Reflect.set(target, prop, value, receiver);
1135
1159
  if (success) {
1136
1160
  const sig = getOrCreatePropertySignal(target, prop);
1137
1161
  sig.set(value);
1162
+ if (!hadProp) {
1163
+ const iterSig = getOrCreatePropertySignal(target, STORE_ITERATE);
1164
+ iterSig.update((prev = 0) => prev + 1);
1165
+ }
1138
1166
  if (Array.isArray(target) && prop !== "length") {
1139
1167
  const lenSig = getOrCreatePropertySignal(target, "length");
1140
1168
  lenSig.set(target.length);
1169
+ const iterSig = getOrCreatePropertySignal(target, STORE_ITERATE);
1170
+ iterSig.update((prev = 0) => prev + 1);
1141
1171
  }
1142
1172
  }
1143
1173
  return success;
@@ -1148,6 +1178,8 @@ function createStoreProxy(target) {
1148
1178
  if (hadProp && success) {
1149
1179
  const sig = getOrCreatePropertySignal(target, prop);
1150
1180
  sig.set(undefined);
1181
+ const iterSig = getOrCreatePropertySignal(target, STORE_ITERATE);
1182
+ iterSig.update((prev = 0) => prev + 1);
1151
1183
  }
1152
1184
  return success;
1153
1185
  }
@@ -3,7 +3,7 @@ import {
3
3
  resolveValue2,
4
4
  setAttribute2,
5
5
  insertChild2
6
- } from "./index-6kfe1nr4.js";
6
+ } from "./index-1yhbg34h.js";
7
7
 
8
8
  // src/jsx-runtime/index.ts
9
9
  var SVG_NS = "http://www.w3.org/2000/svg";
@@ -8,10 +8,10 @@ import {
8
8
  useContext2,
9
9
  effect2,
10
10
  signal2
11
- } from "./index-6kfe1nr4.js";
11
+ } from "./index-1yhbg34h.js";
12
12
  import {
13
13
  SuspenseContext2
14
- } from "./index-a4xns6cc.js";
14
+ } from "./index-65j7a9et.js";
15
15
 
16
16
  // src/query/focus-manager.ts
17
17
  class FocusManager2 {
@@ -9,7 +9,7 @@ import {
9
9
  useContext2,
10
10
  effect2,
11
11
  signal2
12
- } from "./index-6kfe1nr4.js";
12
+ } from "./index-1yhbg34h.js";
13
13
 
14
14
  // src/dom/resource.ts
15
15
  var SuspenseContext2 = createContext2(null);
@@ -6,11 +6,11 @@ import {
6
6
  createContext2,
7
7
  useContext2,
8
8
  signal2
9
- } from "./index-6kfe1nr4.js";
9
+ } from "./index-1yhbg34h.js";
10
10
  import {
11
11
  jsx2,
12
12
  jsxs2
13
- } from "./index-9fvarkrx.js";
13
+ } from "./index-3y73zgbk.js";
14
14
 
15
15
  // src/charts/context.ts
16
16
  var ChartContext2 = createContext2(undefined);
@@ -5,23 +5,23 @@ import {
5
5
  useContext2,
6
6
  signal2,
7
7
  createSignal2
8
- } from "./index-6kfe1nr4.js";
8
+ } from "./index-1yhbg34h.js";
9
9
  import {
10
10
  Show2,
11
11
  For2,
12
12
  Portal2
13
- } from "./index-5s255b3w.js";
13
+ } from "./index-xby428n5.js";
14
14
  import {
15
15
  Fragment2,
16
16
  jsx2,
17
17
  jsxs2
18
- } from "./index-9fvarkrx.js";
18
+ } from "./index-3y73zgbk.js";
19
19
  import {
20
20
  createId2,
21
21
  createControllableSignal2,
22
22
  trapFocus2,
23
23
  onClickOutside2
24
- } from "./index-8x8xz80v.js";
24
+ } from "./index-b7emqmej.js";
25
25
 
26
26
  // src/ui/accordion.tsx
27
27
  var AccordionContext = createContext2(null);
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  createMutation2,
8
8
  createQuery2
9
- } from "./index-y9bq7h9g.js";
9
+ } from "./index-5jhzwtdz.js";
10
10
  // src/rpc/client.ts
11
11
  async function resolveHeaders(headers, fullPath = "") {
12
12
  if (!headers)
@@ -5,16 +5,16 @@ import {
5
5
  createContext2,
6
6
  useContext2,
7
7
  signal2
8
- } from "./index-6kfe1nr4.js";
8
+ } from "./index-1yhbg34h.js";
9
9
  import {
10
10
  Show2,
11
11
  Portal2
12
- } from "./index-5s255b3w.js";
12
+ } from "./index-xby428n5.js";
13
13
  import {
14
14
  Fragment2,
15
15
  jsx2,
16
16
  jsxs2
17
- } from "./index-9fvarkrx.js";
17
+ } from "./index-3y73zgbk.js";
18
18
 
19
19
  // src/ui/utils.ts
20
20
  var idCounter = 0;
@@ -9,7 +9,7 @@ import {
9
9
  import {
10
10
  createMutation2,
11
11
  createQuery2
12
- } from "./index-y9bq7h9g.js";
12
+ } from "./index-5jhzwtdz.js";
13
13
  // src/api/client.ts
14
14
  async function resolveHeaders(headers, fullPath = "") {
15
15
  if (!headers)
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  space2,
3
3
  resolveDimension2
4
- } from "./index-6kfe1nr4.js";
4
+ } from "./index-1yhbg34h.js";
5
5
  import {
6
6
  jsx2
7
- } from "./index-9fvarkrx.js";
7
+ } from "./index-3y73zgbk.js";
8
8
 
9
9
  // src/style/layout.tsx
10
10
  var ALIGN_MAP = {
@@ -3,7 +3,7 @@ import {
3
3
  formatStyleProp2,
4
4
  onCleanup2,
5
5
  effect2
6
- } from "./index-6kfe1nr4.js";
6
+ } from "./index-1yhbg34h.js";
7
7
 
8
8
  // src/style/hash.ts
9
9
  function hashString2(str) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  setAttribute2,
3
3
  insertChild2
4
- } from "./index-6kfe1nr4.js";
4
+ } from "./index-1yhbg34h.js";
5
5
 
6
6
  // src/template/template.ts
7
7
  var templateCache = new Map;
@@ -57,6 +57,17 @@ function html2(strings, ...values) {
57
57
  targetEl.removeAttribute(bind.attrName);
58
58
  setAttribute2(targetEl, bind.attrName, bind.value);
59
59
  }
60
+ } else if (bind.isAttr && !bind.attrName) {
61
+ const propAttr = `data-visage-prop-${bind.id.replace(MARKER_PREFIX, "")}`;
62
+ const targetEl = findElementWithAttributeValue(root, propAttr, bind.id);
63
+ if (targetEl) {
64
+ targetEl.removeAttribute(propAttr);
65
+ if (typeof bind.value === "object" && bind.value !== null) {
66
+ for (const key of Object.keys(bind.value)) {
67
+ setAttribute2(targetEl, key, bind.value[key]);
68
+ }
69
+ }
70
+ }
60
71
  } else if (!bind.isAttr) {
61
72
  const commentNode = findCommentNode(root, bind.id);
62
73
  if (commentNode?.parentNode) {
@@ -3,23 +3,23 @@ import {
3
3
  effect2,
4
4
  signal2,
5
5
  createSignal2
6
- } from "./index-6kfe1nr4.js";
6
+ } from "./index-1yhbg34h.js";
7
7
  import {
8
8
  Show2,
9
9
  For2
10
- } from "./index-5s255b3w.js";
10
+ } from "./index-xby428n5.js";
11
11
  import {
12
12
  jsx2,
13
13
  jsxs2
14
- } from "./index-9fvarkrx.js";
14
+ } from "./index-3y73zgbk.js";
15
15
  import {
16
16
  Tabs2,
17
17
  Tooltip3,
18
18
  Switch2
19
- } from "./index-8x8xz80v.js";
19
+ } from "./index-b7emqmej.js";
20
20
  import {
21
21
  Style2
22
- } from "./index-0madxn60.js";
22
+ } from "./index-enc8cmea.js";
23
23
 
24
24
  // src/devtools/hub.ts
25
25
  class DevToolsHub2 {
@@ -3,13 +3,13 @@ import {
3
3
  onCleanup2,
4
4
  effect2,
5
5
  signal2
6
- } from "./index-6kfe1nr4.js";
6
+ } from "./index-1yhbg34h.js";
7
7
  import {
8
8
  For2
9
- } from "./index-5s255b3w.js";
9
+ } from "./index-xby428n5.js";
10
10
  import {
11
11
  jsx2
12
- } from "./index-9fvarkrx.js";
12
+ } from "./index-3y73zgbk.js";
13
13
 
14
14
  // src/virtual/virtualizer.ts
15
15
  function createVirtualizer2(options) {
@@ -26,27 +26,35 @@ function createVirtualizer2(options) {
26
26
  return cached;
27
27
  return getItemHeight(index);
28
28
  };
29
- const totalSize = computed2(() => {
30
- const count = getCount();
31
- if (typeof options.itemHeight === "number" && dynamicSizeCache.size === 0) {
32
- return count * options.itemHeight;
33
- }
34
- let total = 0;
35
- for (let i = 0;i < count; i++) {
36
- total += getItemSize(i);
37
- }
38
- return total;
39
- });
29
+ const offsetsCache = [0];
30
+ let offsetsValidUpTo = 0;
31
+ const invalidateOffsetsFrom = (index) => {
32
+ offsetsValidUpTo = Math.min(offsetsValidUpTo, index);
33
+ };
40
34
  const getOffsetForIndex = (targetIndex) => {
35
+ if (targetIndex <= 0)
36
+ return 0;
41
37
  if (typeof options.itemHeight === "number" && dynamicSizeCache.size === 0) {
42
38
  return targetIndex * options.itemHeight;
43
39
  }
44
- let offset = 0;
45
- for (let i = 0;i < targetIndex; i++) {
46
- offset += getItemSize(i);
40
+ if (targetIndex <= offsetsValidUpTo) {
41
+ return offsetsCache[targetIndex];
42
+ }
43
+ for (let i = offsetsValidUpTo;i < targetIndex; i++) {
44
+ offsetsCache[i + 1] = (offsetsCache[i] ?? 0) + getItemSize(i);
47
45
  }
48
- return offset;
46
+ offsetsValidUpTo = targetIndex;
47
+ return offsetsCache[targetIndex];
49
48
  };
49
+ const measurementVersion = signal2(0, { internal: true });
50
+ const totalSize = computed2(() => {
51
+ measurementVersion();
52
+ const count = getCount();
53
+ if (typeof options.itemHeight === "number" && dynamicSizeCache.size === 0) {
54
+ return count * options.itemHeight;
55
+ }
56
+ return getOffsetForIndex(count);
57
+ });
50
58
  const findIndexAtOffset = (offset) => {
51
59
  const count = getCount();
52
60
  if (count === 0)
@@ -72,11 +80,13 @@ function createVirtualizer2(options) {
72
80
  return Math.max(0, Math.min(count - 1, low));
73
81
  };
74
82
  const startIndex = computed2(() => {
83
+ measurementVersion();
75
84
  const offset = scrollOffset();
76
85
  const rawStart = findIndexAtOffset(offset);
77
86
  return Math.max(0, rawStart - overscan);
78
87
  });
79
88
  const endIndex = computed2(() => {
89
+ measurementVersion();
80
90
  const count = getCount();
81
91
  if (count === 0)
82
92
  return 0;
@@ -193,7 +203,8 @@ function createVirtualizer2(options) {
193
203
  const measuredSize = isHorizontal ? element.getBoundingClientRect().width : element.getBoundingClientRect().height;
194
204
  if (measuredSize > 0 && dynamicSizeCache.get(index) !== measuredSize) {
195
205
  dynamicSizeCache.set(index, measuredSize);
196
- scrollOffset.update((o) => o);
206
+ invalidateOffsetsFrom(index);
207
+ measurementVersion.update((v) => v + 1);
197
208
  }
198
209
  };
199
210
  return {