@fuma-content/studio 1.0.3 → 1.0.4

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 (109) hide show
  1. package/build/client/assets/{QueryClientProvider-Cys2v_1v.js → QueryClientProvider-BFSUF51X.js} +1 -1
  2. package/build/client/assets/actions-ByenKsIt.js +1 -0
  3. package/build/client/assets/actions-ClHPL1CP.js +1 -0
  4. package/build/client/assets/badge-BnhEE6iu.js +1 -0
  5. package/build/client/assets/{client-Cfd36Zz-.js → client-BEKU4RIg.js} +146 -146
  6. package/build/client/assets/client-DBU2dkUR.js +1 -0
  7. package/build/client/assets/client-DvwvjHta.js +1 -0
  8. package/build/client/assets/client-wd2sce2I.js +8 -0
  9. package/build/client/assets/dropdown-menu-By_XeFX4.js +1 -0
  10. package/build/client/assets/entry.rsc-J_U0YQEr.js +1 -0
  11. package/build/client/assets/{index-DL539Bhx.js → index-B5GacMxj.js} +1 -1
  12. package/build/client/assets/index-BTaHNKf7.js +1 -0
  13. package/build/client/assets/index-BgFxGtat.js +1 -0
  14. package/build/client/assets/index-CG_0cSZQ.js +1 -0
  15. package/build/client/assets/index-CfCSvolS.js +1 -0
  16. package/build/client/assets/{index-C37mbJ0i.js → index-D8KuzOxG.js} +1 -1
  17. package/build/client/assets/index-DrT4Adhh.js +41 -0
  18. package/build/client/assets/{index-DXHuzvfN.js → index-El_a1Yhs.js} +1 -1
  19. package/build/client/assets/index-QYLIz8qa.js +1 -0
  20. package/build/client/assets/layout-BPVd8vtW.js +1 -0
  21. package/build/client/assets/{mdx-CehodSrM.js → mdx-DBJIR6uw.js} +1 -1
  22. package/build/client/assets/page-BJL5nvn-.js +1 -0
  23. package/build/client/assets/page-eyuUZvVn.js +1 -0
  24. package/build/client/assets/popover-BowiFsDm.js +1 -0
  25. package/build/client/assets/{react-D58ornpH.js → react-CzFdRS7Y.js} +7 -7
  26. package/build/client/assets/root-7fvd-0uP.js +1 -0
  27. package/build/client/assets/root-B0B6-NU5.css +1 -0
  28. package/build/client/assets/{root-CNcQf1GA.js → root-jg-0qm8s.js} +1 -1
  29. package/build/client/assets/route-BLLsZ_zO.js +1 -0
  30. package/build/client/assets/{router-XCTsiXqQ.js → router-QEl8O8lm.js} +1 -1
  31. package/build/client/assets/select-BI356bZ1.js +1 -0
  32. package/build/client/assets/separator-0kwG7IIM.js +1 -0
  33. package/build/client/assets/sidebar-ByyQE2QS.js +12 -0
  34. package/build/client/assets/{site-header-1Aor7-g4.js → site-header-iBpA4Sim.js} +1 -1
  35. package/build/client/assets/spinner-D35u7i0p.js +1 -0
  36. package/build/client/assets/tooltip-v-_I4rCw.js +16 -0
  37. package/build/client/assets/use-sync-yCWvjE_m.js +2 -0
  38. package/build/client/assets/{yaml-DUnUkeX8.js → yaml-BnQf_2Zt.js} +1 -1
  39. package/build/server/__ssr_build/__vite_rsc_assets_manifest.js +213 -133
  40. package/build/server/__ssr_build/assets/{actions-DLZnfFzU.js → actions-C5Kv8XYU.js} +2 -2
  41. package/build/server/__ssr_build/assets/{actions-D6dLhck1.js → actions-DQIBBM15.js} +4 -4
  42. package/build/server/__ssr_build/assets/{badge-CH6ntch2.js → badge-B48L9yYO.js} +1 -1
  43. package/build/server/__ssr_build/assets/{client-C-WcMcGh.js → client-AuWNsacU.js} +3 -3
  44. package/build/server/__ssr_build/assets/client-BHaLyky8.js +1162 -0
  45. package/build/server/__ssr_build/assets/{client-DX-wDNer.js → client-BogEWrwz.js} +9 -5
  46. package/build/server/__ssr_build/assets/{client-JNaR8Jey.js → client-DXOHI3cC.js} +2808 -4397
  47. package/build/server/__ssr_build/assets/{dropdown-menu-gcIcDMHP.js → dropdown-menu-CnDgV_JY.js} +7 -9
  48. package/build/server/__ssr_build/assets/{entry.rsc-Cg_DxYkh.js → entry.rsc-aOU-YPkj.js} +1 -1
  49. package/build/server/__ssr_build/assets/{index-PpqpVA51.js → index-B6ajh-UP.js} +1 -1
  50. package/build/server/__ssr_build/assets/index-BPd5y8T-.js +76 -0
  51. package/build/server/__ssr_build/assets/{button-U-KvP9zg.js → index-By9m5mBe.js} +3272 -3175
  52. package/build/server/__ssr_build/assets/index-Ch7b9Ofo.js +37 -0
  53. package/build/server/__ssr_build/assets/{index-BJ-AF-IL.js → index-Cw6b1mnl.js} +8 -7
  54. package/build/server/__ssr_build/assets/{index-BloUStie.js → index-kCa2P0Xn.js} +4 -75
  55. package/build/server/__ssr_build/assets/{index-CWwW5yWZ.js → index-tFzyztyE.js} +2 -2
  56. package/build/server/__ssr_build/assets/{layout-B79fq6F-.js → layout-CC-HJHWR.js} +13 -11
  57. package/build/server/__ssr_build/assets/{mdx-bmeV1kyx.js → mdx-D9VFmsYC.js} +1 -1
  58. package/build/server/__ssr_build/assets/{page-CxhOzrct.js → page-BVUd9aDy.js} +10 -8
  59. package/build/server/__ssr_build/assets/{page-DxtKhA1K.js → page-C_wQzy3_.js} +13 -11
  60. package/build/server/__ssr_build/assets/popover-CzQgoguQ.js +321 -0
  61. package/build/server/__ssr_build/assets/{root-TWeSpY2W.js → root-BmMc6_zA.js} +1 -1
  62. package/build/server/__ssr_build/assets/route-CNYc37pV.js +860 -0
  63. package/build/server/__ssr_build/assets/{spinner-w3Q_wkh3.js → select-B8QQSB6X.js} +10 -25
  64. package/build/server/__ssr_build/assets/{separator-CKrKBtv4.js → separator-C601eKPH.js} +2 -2
  65. package/build/server/__ssr_build/assets/{sidebar-DoXmiwf0.js → sidebar-C6fHDjcx.js} +237 -65
  66. package/build/server/__ssr_build/assets/{site-header-pFjDV73T.js → site-header-Bmsr3a30.js} +2 -2
  67. package/build/server/__ssr_build/assets/spinner-D5zAJQcS.js +19 -0
  68. package/build/server/__ssr_build/assets/{tooltip-B2NV0tpS.js → tooltip-B3A57zPO.js} +1211 -1211
  69. package/build/server/__ssr_build/assets/{use-sync-p_-o0jkt.js → use-sync-DTZgOM1O.js} +29 -1185
  70. package/build/server/__ssr_build/assets/{yaml-BEdFfhvc.js → yaml-xJU1Ur4O.js} +1 -1
  71. package/build/server/__ssr_build/index.js +31 -15
  72. package/build/server/__vite_rsc_assets_manifest.js +213 -133
  73. package/build/server/assets/{actions-C92yn6jE.js → actions-BbMzIy5J.js} +2 -2
  74. package/build/server/assets/{actions-CWWFIcb1.js → actions-CjWBMAed.js} +2 -2
  75. package/build/server/assets/{actions-DZdN0IBq.js → actions-cRzXiMyR.js} +2 -2
  76. package/build/server/assets/{config-Cb909uq6.js → config-Dka4Bvz4.js} +10 -10
  77. package/build/server/assets/{layout-CRw_6FCt.js → layout-CIIfFN0v.js} +2 -2
  78. package/build/server/assets/{page-BfKoQQmw.js → page-pyqagPXb.js} +2 -2
  79. package/build/server/assets/root-B0B6-NU5.css +1 -0
  80. package/build/server/assets/{root-BqMNAwvK.js → root-D1ebFoST.js} +1 -1
  81. package/build/server/assets/{route-DiqCR5uw.js → route-C7QEArEP.js} +13911 -5699
  82. package/build/server/index.js +40 -15
  83. package/dist/bin.mjs +4 -4
  84. package/dist/package.mjs +1 -1
  85. package/package.json +32 -15
  86. package/build/client/assets/actions-BIaFztcg.js +0 -1
  87. package/build/client/assets/actions-Bws1O3FH.js +0 -1
  88. package/build/client/assets/badge-C70RdDmr.js +0 -1
  89. package/build/client/assets/button-B0G-joJA.js +0 -41
  90. package/build/client/assets/client-C814jsdE.js +0 -1
  91. package/build/client/assets/client-wwp8K9Xz.js +0 -1
  92. package/build/client/assets/dropdown-menu-Re3QusA0.js +0 -1
  93. package/build/client/assets/entry.rsc-CdTwhQ3_.js +0 -1
  94. package/build/client/assets/index-DZ8LIlZu.js +0 -1
  95. package/build/client/assets/index-DprkZK2S.js +0 -1
  96. package/build/client/assets/index-UnlOgAz7.js +0 -1
  97. package/build/client/assets/layout-C5TjiFIx.js +0 -1
  98. package/build/client/assets/page-CiRIEJz9.js +0 -1
  99. package/build/client/assets/page-DBIuN_hk.js +0 -1
  100. package/build/client/assets/root-CbriXo_i.css +0 -1
  101. package/build/client/assets/root-DJ8qMHCd.js +0 -1
  102. package/build/client/assets/separator-BDe8wWVP.js +0 -1
  103. package/build/client/assets/sidebar-DNKkYLTA.js +0 -12
  104. package/build/client/assets/spinner-O3ZbB6fn.js +0 -1
  105. package/build/client/assets/tooltip-B4fI3WTO.js +0 -16
  106. package/build/client/assets/use-sync-CfDyibsS.js +0 -9
  107. package/build/server/assets/root-CbriXo_i.css +0 -1
  108. /package/build/server/__ssr_build/assets/{root-BYlluTc0.js → root-S8l7oX7x.js} +0 -0
  109. /package/build/server/assets/{root-ByROcfN4.js → root-DRYtk85G.js} +0 -0
@@ -1,12 +1,13 @@
1
- import { r as reactExports, j as jsxRuntimeExports, i as reactDomExports } from "../index.js";
2
- import { c as createLucideIcon, j as createPopperScope, h as useControllableState, R as Root2$1, a as createContextScope, k as useId, u as useComposedRefs, A as Anchor, P as Primitive, b as composeEventHandlers, f as useLayoutEffect2, l as Portal$1, V as VISUALLY_HIDDEN_STYLES, e as useCallbackRef, m as hideOthers, p as useFocusGuards, n as ReactRemoveScroll, o as createSlot, F as FocusScope, D as DismissableLayer, C as Content, q as Arrow, s as cn } from "./button-U-KvP9zg.js";
3
- import { u as useDirection, a as createCollection, C as Check } from "./index-BloUStie.js";
4
- const __iconNode$2 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
5
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$2);
6
- const __iconNode$1 = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
7
- const ChevronUp = createLucideIcon("chevron-up", __iconNode$1);
8
- const __iconNode = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
9
- const LoaderCircle = createLucideIcon("loader-circle", __iconNode);
1
+ import { r as reactExports, j as jsxRuntimeExports, h as reactDomExports } from "../index.js";
2
+ import { c as createLucideIcon, f as useControllableState, R as Root2$1, u as useId, m as useComposedRefs, A as Anchor, P as Primitive, g as composeEventHandlers, e as useLayoutEffect2, s as Portal$1, t as createPopperScope, V as VISUALLY_HIDDEN_STYLES, d as useCallbackRef, v as hideOthers, y as useFocusGuards, w as ReactRemoveScroll, F as FocusScope, D as DismissableLayer, h as createContextScope, x as createSlot, z as Content, E as Arrow, b as cn } from "./index-By9m5mBe.js";
3
+ import { u as useDirection, c as createCollection, C as Check } from "./index-BPd5y8T-.js";
4
+ const __iconNode$1 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
5
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$1);
6
+ const __iconNode = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
7
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode);
8
+ function clamp(value, [min, max]) {
9
+ return Math.min(max, Math.max(min, value));
10
+ }
10
11
  function usePrevious(value) {
11
12
  const ref = reactExports.useRef({ value, previous: value });
12
13
  return reactExports.useMemo(() => {
@@ -17,9 +18,6 @@ function usePrevious(value) {
17
18
  return ref.current.previous;
18
19
  }, [value]);
19
20
  }
20
- function clamp(value, [min, max]) {
21
- return Math.min(max, Math.max(min, value));
22
- }
23
21
  var OPEN_KEYS = [" ", "Enter", "ArrowUp", "ArrowDown"];
24
22
  var SELECTION_KEYS = [" ", "Enter"];
25
23
  var SELECT_NAME = "Select";
@@ -1267,25 +1265,12 @@ function SelectScrollDownButton({
1267
1265
  }
1268
1266
  );
1269
1267
  }
1270
- function Spinner({ className, ...props }) {
1271
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
1272
- LoaderCircle,
1273
- {
1274
- role: "status",
1275
- "aria-label": "Loading",
1276
- className: cn("size-4 animate-spin", className),
1277
- ...props
1278
- }
1279
- );
1280
- }
1281
1268
  export {
1282
1269
  ChevronDown as C,
1283
- LoaderCircle as L,
1284
1270
  Select as S,
1285
1271
  SelectTrigger as a,
1286
1272
  SelectValue as b,
1287
1273
  SelectContent as c,
1288
1274
  SelectItem as d,
1289
- Spinner as e,
1290
1275
  usePrevious as u
1291
1276
  };
@@ -1,5 +1,6 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../index.js";
2
- import { P as Primitive, s as cn } from "./button-U-KvP9zg.js";
2
+ import { P as Primitive } from "./index-Ch7b9Ofo.js";
3
+ import { b as cn } from "./index-By9m5mBe.js";
3
4
  var NAME = "Separator";
4
5
  var DEFAULT_ORIENTATION = "horizontal";
5
6
  var ORIENTATIONS = ["horizontal", "vertical"];
@@ -44,6 +45,5 @@ function Separator({
44
45
  );
45
46
  }
46
47
  export {
47
- Root as R,
48
48
  Separator as S
49
49
  };
@@ -1,9 +1,9 @@
1
- import { r as reactExports, c as createServerReference, j as jsxRuntimeExports } from "../index.js";
1
+ import { r as reactExports, d as createServerReference, j as jsxRuntimeExports } from "../index.js";
2
2
  import { queryCollectionOptions } from "@tanstack/query-db-collection";
3
3
  import { q as queryClient } from "./query-C1_xUNXy.js";
4
4
  import { cva } from "class-variance-authority";
5
- import { c as createLucideIcon, s as cn, B as Button, X, S as Slot } from "./button-U-KvP9zg.js";
6
- import { R as Root, C as Content, a as Close, T as Title, D as Description, P as Portal, O as Overlay, l as Tooltip, m as TooltipTrigger, q as TooltipContent } from "./tooltip-B2NV0tpS.js";
5
+ import { c as createLucideIcon, B as Button, X, b as cn, S as Slot } from "./index-By9m5mBe.js";
6
+ import { R as Root, C as Content, ao as Close, am as Title, an as Description, P as Portal, O as Overlay, T as Tooltip, i as TooltipTrigger, m as TooltipContent } from "./tooltip-B3A57zPO.js";
7
7
  const __iconNode = [
8
8
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
9
9
  ["path", { d: "M9 3v18", key: "fh3hqa" }]
@@ -655,6 +655,7 @@ function areUint8ArraysEqual(a, b) {
655
655
  return true;
656
656
  }
657
657
  const UINT8ARRAY_NORMALIZE_THRESHOLD = 128;
658
+ const UNDEFINED_SENTINEL = `__TS_DB_BTREE_UNDEFINED_VALUE__`;
658
659
  function normalizeValue(value) {
659
660
  if (value instanceof Date) {
660
661
  return value.getTime();
@@ -667,6 +668,18 @@ function normalizeValue(value) {
667
668
  }
668
669
  return value;
669
670
  }
671
+ function normalizeForBTree(value) {
672
+ if (value === void 0) {
673
+ return UNDEFINED_SENTINEL;
674
+ }
675
+ return normalizeValue(value);
676
+ }
677
+ function denormalizeUndefined(value) {
678
+ if (value === UNDEFINED_SENTINEL) {
679
+ return void 0;
680
+ }
681
+ return value;
682
+ }
670
683
  function areValuesEqual(a, b) {
671
684
  if (a === b) {
672
685
  return true;
@@ -1196,9 +1209,15 @@ class ReverseIndex {
1196
1209
  take(n, from, filterFn) {
1197
1210
  return this.originalIndex.takeReversed(n, from, filterFn);
1198
1211
  }
1212
+ takeFromStart(n, filterFn) {
1213
+ return this.originalIndex.takeReversedFromEnd(n, filterFn);
1214
+ }
1199
1215
  takeReversed(n, from, filterFn) {
1200
1216
  return this.originalIndex.take(n, from, filterFn);
1201
1217
  }
1218
+ takeReversedFromEnd(n, filterFn) {
1219
+ return this.originalIndex.takeFromStart(n, filterFn);
1220
+ }
1202
1221
  get orderedEntriesArray() {
1203
1222
  return this.originalIndex.orderedEntriesArrayReversed;
1204
1223
  }
@@ -4536,7 +4555,8 @@ class BTreeIndex extends BaseIndex {
4536
4555
  this.valueMap = /* @__PURE__ */ new Map();
4537
4556
  this.indexedKeys = /* @__PURE__ */ new Set();
4538
4557
  this.compareFn = defaultComparator;
4539
- this.compareFn = options?.compareFn ?? defaultComparator;
4558
+ const baseCompareFn = options?.compareFn ?? defaultComparator;
4559
+ this.compareFn = (a, b) => baseCompareFn(denormalizeUndefined(a), denormalizeUndefined(b));
4540
4560
  if (options?.compareOptions) {
4541
4561
  this.compareOptions = options.compareOptions;
4542
4562
  }
@@ -4556,7 +4576,7 @@ class BTreeIndex extends BaseIndex {
4556
4576
  `Failed to evaluate index expression for key ${key}: ${error}`
4557
4577
  );
4558
4578
  }
4559
- const normalizedValue = normalizeValue(indexedValue2);
4579
+ const normalizedValue = normalizeForBTree(indexedValue2);
4560
4580
  if (this.valueMap.has(normalizedValue)) {
4561
4581
  this.valueMap.get(normalizedValue).add(key);
4562
4582
  } else {
@@ -4581,7 +4601,7 @@ class BTreeIndex extends BaseIndex {
4581
4601
  );
4582
4602
  return;
4583
4603
  }
4584
- const normalizedValue = normalizeValue(indexedValue2);
4604
+ const normalizedValue = normalizeForBTree(indexedValue2);
4585
4605
  if (this.valueMap.has(normalizedValue)) {
4586
4606
  const keySet = this.valueMap.get(normalizedValue);
4587
4607
  keySet.delete(key);
@@ -4660,7 +4680,7 @@ class BTreeIndex extends BaseIndex {
4660
4680
  * Performs an equality lookup
4661
4681
  */
4662
4682
  equalityLookup(value) {
4663
- const normalizedValue = normalizeValue(value);
4683
+ const normalizedValue = normalizeForBTree(value);
4664
4684
  return new Set(this.valueMap.get(normalizedValue) ?? []);
4665
4685
  }
4666
4686
  /**
@@ -4670,10 +4690,10 @@ class BTreeIndex extends BaseIndex {
4670
4690
  rangeQuery(options = {}) {
4671
4691
  const { from, to, fromInclusive = true, toInclusive = true } = options;
4672
4692
  const result = /* @__PURE__ */ new Set();
4673
- const normalizedFrom = normalizeValue(from);
4674
- const normalizedTo = normalizeValue(to);
4675
- const fromKey = normalizedFrom ?? this.orderedEntries.minKey();
4676
- const toKey = normalizedTo ?? this.orderedEntries.maxKey();
4693
+ const hasFrom = `from` in options;
4694
+ const hasTo = `to` in options;
4695
+ const fromKey = hasFrom ? normalizeForBTree(from) : this.orderedEntries.minKey();
4696
+ const toKey = hasTo ? normalizeForBTree(to) : this.orderedEntries.maxKey();
4677
4697
  this.orderedEntries.forRange(
4678
4698
  fromKey,
4679
4699
  toKey,
@@ -4695,18 +4715,28 @@ class BTreeIndex extends BaseIndex {
4695
4715
  */
4696
4716
  rangeQueryReversed(options = {}) {
4697
4717
  const { from, to, fromInclusive = true, toInclusive = true } = options;
4718
+ const hasFrom = `from` in options;
4719
+ const hasTo = `to` in options;
4698
4720
  return this.rangeQuery({
4699
- from: to ?? this.orderedEntries.maxKey(),
4700
- to: from ?? this.orderedEntries.minKey(),
4721
+ from: hasTo ? to : this.orderedEntries.maxKey(),
4722
+ to: hasFrom ? from : this.orderedEntries.minKey(),
4701
4723
  fromInclusive: toInclusive,
4702
4724
  toInclusive: fromInclusive
4703
4725
  });
4704
4726
  }
4727
+ /**
4728
+ * Internal method for taking items from the index.
4729
+ * @param n - The number of items to return
4730
+ * @param nextPair - Function to get the next pair from the BTree
4731
+ * @param from - Already normalized! undefined means "start from beginning/end", sentinel means "start from the key undefined"
4732
+ * @param filterFn - Optional filter function
4733
+ * @param reversed - Whether to reverse the order of keys within each value
4734
+ */
4705
4735
  takeInternal(n, nextPair, from, filterFn, reversed = false) {
4706
4736
  const keysInResult = /* @__PURE__ */ new Set();
4707
4737
  const result = [];
4708
4738
  let pair;
4709
- let key = normalizeValue(from);
4739
+ let key = from;
4710
4740
  while ((pair = nextPair(key)) !== void 0 && result.length < n) {
4711
4741
  key = pair[0];
4712
4742
  const keys = this.valueMap.get(key);
@@ -4725,24 +4755,46 @@ class BTreeIndex extends BaseIndex {
4725
4755
  return result;
4726
4756
  }
4727
4757
  /**
4728
- * Returns the next n items after the provided item or the first n items if no from item is provided.
4758
+ * Returns the next n items after the provided item.
4729
4759
  * @param n - The number of items to return
4730
- * @param from - The item to start from (exclusive). Starts from the smallest item (inclusive) if not provided.
4731
- * @returns The next n items after the provided key. Returns the first n items if no from item is provided.
4760
+ * @param from - The item to start from (exclusive).
4761
+ * @returns The next n items after the provided key.
4732
4762
  */
4733
4763
  take(n, from, filterFn) {
4734
4764
  const nextPair = (k) => this.orderedEntries.nextHigherPair(k);
4735
- return this.takeInternal(n, nextPair, from, filterFn);
4765
+ const normalizedFrom = normalizeForBTree(from);
4766
+ return this.takeInternal(n, nextPair, normalizedFrom, filterFn);
4767
+ }
4768
+ /**
4769
+ * Returns the first n items from the beginning.
4770
+ * @param n - The number of items to return
4771
+ * @param filterFn - Optional filter function
4772
+ * @returns The first n items
4773
+ */
4774
+ takeFromStart(n, filterFn) {
4775
+ const nextPair = (k) => this.orderedEntries.nextHigherPair(k);
4776
+ return this.takeInternal(n, nextPair, void 0, filterFn);
4736
4777
  }
4737
4778
  /**
4738
- * Returns the next n items **before** the provided item (in descending order) or the last n items if no from item is provided.
4779
+ * Returns the next n items **before** the provided item (in descending order).
4739
4780
  * @param n - The number of items to return
4740
- * @param from - The item to start from (exclusive). Starts from the largest item (inclusive) if not provided.
4741
- * @returns The next n items **before** the provided key. Returns the last n items if no from item is provided.
4781
+ * @param from - The item to start from (exclusive). Required.
4782
+ * @returns The next n items **before** the provided key.
4742
4783
  */
4743
4784
  takeReversed(n, from, filterFn) {
4744
4785
  const nextPair = (k) => this.orderedEntries.nextLowerPair(k);
4745
- return this.takeInternal(n, nextPair, from, filterFn, true);
4786
+ const normalizedFrom = normalizeForBTree(from);
4787
+ return this.takeInternal(n, nextPair, normalizedFrom, filterFn, true);
4788
+ }
4789
+ /**
4790
+ * Returns the last n items from the end.
4791
+ * @param n - The number of items to return
4792
+ * @param filterFn - Optional filter function
4793
+ * @returns The last n items
4794
+ */
4795
+ takeReversedFromEnd(n, filterFn) {
4796
+ const nextPair = (k) => this.orderedEntries.nextLowerPair(k);
4797
+ return this.takeInternal(n, nextPair, void 0, filterFn, true);
4746
4798
  }
4747
4799
  /**
4748
4800
  * Performs an IN array lookup
@@ -4750,7 +4802,7 @@ class BTreeIndex extends BaseIndex {
4750
4802
  inArrayLookup(values) {
4751
4803
  const result = /* @__PURE__ */ new Set();
4752
4804
  for (const value of values) {
4753
- const normalizedValue = normalizeValue(value);
4805
+ const normalizedValue = normalizeForBTree(value);
4754
4806
  const keys = this.valueMap.get(normalizedValue);
4755
4807
  if (keys) {
4756
4808
  keys.forEach((key) => result.add(key));
@@ -4763,16 +4815,23 @@ class BTreeIndex extends BaseIndex {
4763
4815
  return this.indexedKeys;
4764
4816
  }
4765
4817
  get orderedEntriesArray() {
4766
- return this.orderedEntries.keysArray().map((key) => [key, this.valueMap.get(key) ?? /* @__PURE__ */ new Set()]);
4818
+ return this.orderedEntries.keysArray().map((key) => [
4819
+ denormalizeUndefined(key),
4820
+ this.valueMap.get(key) ?? /* @__PURE__ */ new Set()
4821
+ ]);
4767
4822
  }
4768
4823
  get orderedEntriesArrayReversed() {
4769
- return this.takeReversed(this.orderedEntries.size).map((key) => [
4770
- key,
4824
+ return this.takeReversedFromEnd(this.orderedEntries.size).map((key) => [
4825
+ denormalizeUndefined(key),
4771
4826
  this.valueMap.get(key) ?? /* @__PURE__ */ new Set()
4772
4827
  ]);
4773
4828
  }
4774
4829
  get valueMapData() {
4775
- return this.valueMap;
4830
+ const result = /* @__PURE__ */ new Map();
4831
+ for (const [key, value] of this.valueMap) {
4832
+ result.set(denormalizeUndefined(key), value);
4833
+ }
4834
+ return result;
4776
4835
  }
4777
4836
  }
4778
4837
  function shouldAutoIndex(collection2) {
@@ -5467,7 +5526,7 @@ function getOrderedKeys(collection2, orderBy, limit, whereFilter, optimizedOnly)
5467
5526
  }
5468
5527
  return whereFilter?.(value) ?? true;
5469
5528
  };
5470
- return index.take(limit ?? index.keyCount, void 0, filterFn);
5529
+ return index.takeFromStart(limit ?? index.keyCount, filterFn);
5471
5530
  }
5472
5531
  }
5473
5532
  }
@@ -6604,6 +6663,7 @@ class CollectionSubscription extends EventEmitter {
6604
6663
  limit: opts?.limit
6605
6664
  };
6606
6665
  const syncResult = this.collection._sync.loadSubset(loadOptions);
6666
+ opts?.onLoadSubsetResult?.(syncResult);
6607
6667
  this.loadedSubsets.push(loadOptions);
6608
6668
  const trackLoadSubsetPromise = opts?.trackLoadSubsetPromise ?? true;
6609
6669
  if (trackLoadSubsetPromise) {
@@ -6640,7 +6700,9 @@ class CollectionSubscription extends EventEmitter {
6640
6700
  orderBy,
6641
6701
  limit,
6642
6702
  minValues,
6643
- offset
6703
+ offset,
6704
+ trackLoadSubsetPromise: shouldTrackLoadSubsetPromise = true,
6705
+ onLoadSubsetResult
6644
6706
  }) {
6645
6707
  if (!limit) throw new Error(`limit is required`);
6646
6708
  if (!this.orderByIndex) {
@@ -6648,13 +6710,14 @@ class CollectionSubscription extends EventEmitter {
6648
6710
  `Ordered snapshot was requested but no index was found. You have to call setOrderByIndex before requesting an ordered snapshot.`
6649
6711
  );
6650
6712
  }
6713
+ const hasMinValue = minValues !== void 0 && minValues.length > 0;
6651
6714
  const minValue = minValues?.[0];
6652
6715
  const minValueForIndex = minValue;
6653
6716
  const index = this.orderByIndex;
6654
6717
  const where = this.options.whereExpression;
6655
6718
  const whereFilterFn = where ? createFilterFunctionFromExpression(where) : void 0;
6656
6719
  const filterFn = (key) => {
6657
- if (this.sentKeys.has(key)) {
6720
+ if (key !== void 0 && this.sentKeys.has(key)) {
6658
6721
  return false;
6659
6722
  }
6660
6723
  const value = this.collection.get(key);
@@ -6666,7 +6729,7 @@ class CollectionSubscription extends EventEmitter {
6666
6729
  let biggestObservedValue = minValueForIndex;
6667
6730
  const changes = [];
6668
6731
  let keys = [];
6669
- if (minValueForIndex !== void 0) {
6732
+ if (hasMinValue) {
6670
6733
  const { expression } = orderBy[0];
6671
6734
  const allRowsWithMinValue = this.collection.currentStateAsChanges({
6672
6735
  where: eq(expression, new Value(minValueForIndex))
@@ -6684,7 +6747,7 @@ class CollectionSubscription extends EventEmitter {
6684
6747
  keys = index.take(limit, minValueForIndex, filterFn);
6685
6748
  }
6686
6749
  } else {
6687
- keys = index.take(limit, minValueForIndex, filterFn);
6750
+ keys = index.takeFromStart(limit, filterFn);
6688
6751
  }
6689
6752
  const valuesNeeded = () => Math.max(limit - changes.length, 0);
6690
6753
  const collectionExhausted = () => keys.length === 0;
@@ -6748,8 +6811,11 @@ class CollectionSubscription extends EventEmitter {
6748
6811
  subscription: this
6749
6812
  };
6750
6813
  const syncResult = this.collection._sync.loadSubset(loadOptions);
6814
+ onLoadSubsetResult?.(syncResult);
6751
6815
  this.loadedSubsets.push(loadOptions);
6752
- this.trackLoadSubsetPromise(syncResult);
6816
+ if (shouldTrackLoadSubsetPromise) {
6817
+ this.trackLoadSubsetPromise(syncResult);
6818
+ }
6753
6819
  }
6754
6820
  // TODO: also add similar test but that checks that it can also load it from the collection's loadSubset function
6755
6821
  // and that that also works properly (i.e. does not skip duplicate values)
@@ -6799,6 +6865,12 @@ class CollectionSubscription extends EventEmitter {
6799
6865
  this.sentKeys.add(change.key);
6800
6866
  }
6801
6867
  }
6868
+ if (this.orderByIndex) {
6869
+ this.limitedSnapshotRowCount = Math.max(
6870
+ this.limitedSnapshotRowCount,
6871
+ this.sentKeys.size
6872
+ );
6873
+ }
6802
6874
  }
6803
6875
  /**
6804
6876
  * Mark that the subscription should not filter any changes.
@@ -6902,7 +6974,12 @@ class CollectionChangesManager {
6902
6974
  subscription.on(`status:change`, options.onStatusChange);
6903
6975
  }
6904
6976
  if (options.includeInitialState) {
6905
- subscription.requestSnapshot({ trackLoadSubsetPromise: false });
6977
+ subscription.requestSnapshot({
6978
+ trackLoadSubsetPromise: false,
6979
+ orderBy: options.orderBy,
6980
+ limit: options.limit,
6981
+ onLoadSubsetResult: options.onLoadSubsetResult
6982
+ });
6906
6983
  } else if (options.includeInitialState === false) {
6907
6984
  subscription.markAllStateAsSeen();
6908
6985
  }
@@ -7135,7 +7212,18 @@ class CollectionLifecycleManager {
7135
7212
  this.gcTimeoutId = null;
7136
7213
  }
7137
7214
  this.hasBeenReady = false;
7215
+ const callbacks = [...this.onFirstReadyCallbacks];
7138
7216
  this.onFirstReadyCallbacks = [];
7217
+ callbacks.forEach((callback) => {
7218
+ try {
7219
+ callback();
7220
+ } catch (error) {
7221
+ console.error(
7222
+ `${this.config.id ? `[${this.config.id}] ` : ``}Error in onFirstReady callback during cleanup:`,
7223
+ error
7224
+ );
7225
+ }
7226
+ });
7139
7227
  this.setStatus(`cleaned-up`);
7140
7228
  this.events.cleanup();
7141
7229
  return true;
@@ -11597,24 +11685,17 @@ class CollectionSubscriber {
11597
11685
  }
11598
11686
  subscribeToChanges(whereExpression) {
11599
11687
  const orderByInfo = this.getOrderByInfo();
11600
- const trackLoadPromise = (subscription2) => {
11601
- if (!this.subscriptionLoadingPromises.has(subscription2)) {
11602
- let resolve;
11603
- const promise = new Promise((res) => {
11604
- resolve = res;
11605
- });
11606
- this.subscriptionLoadingPromises.set(subscription2, {
11607
- resolve
11608
- });
11688
+ const trackLoadResult = (result) => {
11689
+ if (result instanceof Promise) {
11609
11690
  this.collectionConfigBuilder.liveQueryCollection._sync.trackLoadPromise(
11610
- promise
11691
+ result
11611
11692
  );
11612
11693
  }
11613
11694
  };
11614
11695
  const onStatusChange = (event) => {
11615
11696
  const subscription2 = event.subscription;
11616
11697
  if (event.status === `loadingSubset`) {
11617
- trackLoadPromise(subscription2);
11698
+ this.ensureLoadingPromise(subscription2);
11618
11699
  } else {
11619
11700
  const deferred = this.subscriptionLoadingPromises.get(subscription2);
11620
11701
  if (deferred) {
@@ -11628,7 +11709,8 @@ class CollectionSubscriber {
11628
11709
  subscription = this.subscribeToOrderedChanges(
11629
11710
  whereExpression,
11630
11711
  orderByInfo,
11631
- onStatusChange
11712
+ onStatusChange,
11713
+ trackLoadResult
11632
11714
  );
11633
11715
  } else {
11634
11716
  const includeInitialState = !this.collectionConfigBuilder.isLazyAlias(
@@ -11641,7 +11723,7 @@ class CollectionSubscriber {
11641
11723
  );
11642
11724
  }
11643
11725
  if (subscription.status === `loadingSubset`) {
11644
- trackLoadPromise(subscription);
11726
+ this.ensureLoadingPromise(subscription);
11645
11727
  }
11646
11728
  const unsubscribe = () => {
11647
11729
  const deferred = this.subscriptionLoadingPromises.get(subscription);
@@ -11685,18 +11767,55 @@ class CollectionSubscriber {
11685
11767
  const sendChanges = (changes) => {
11686
11768
  this.sendChangesToPipeline(changes);
11687
11769
  };
11770
+ const { orderBy, limit, offset } = this.collectionConfigBuilder.query;
11771
+ const effectiveLimit = limit !== void 0 && offset !== void 0 ? limit + offset : limit;
11772
+ const normalizedOrderBy = orderBy ? normalizeOrderByPaths(orderBy, this.alias) : void 0;
11773
+ const canPassOrderBy = normalizedOrderBy?.every((clause) => {
11774
+ const exp = clause.expression;
11775
+ if (exp.type !== `ref`) {
11776
+ return false;
11777
+ }
11778
+ const path = exp.path;
11779
+ return Array.isArray(path) && path.length === 1;
11780
+ }) ?? false;
11781
+ const orderByForSubscription = canPassOrderBy ? normalizedOrderBy : void 0;
11782
+ const limitForSubscription = canPassOrderBy ? effectiveLimit : void 0;
11783
+ const onLoadSubsetResult = includeInitialState ? (result) => {
11784
+ if (result instanceof Promise) {
11785
+ this.collectionConfigBuilder.liveQueryCollection._sync.trackLoadPromise(
11786
+ result
11787
+ );
11788
+ }
11789
+ } : void 0;
11688
11790
  const subscription = this.collection.subscribeChanges(sendChanges, {
11689
11791
  ...includeInitialState && { includeInitialState },
11690
11792
  whereExpression,
11691
- onStatusChange
11793
+ onStatusChange,
11794
+ orderBy: orderByForSubscription,
11795
+ limit: limitForSubscription,
11796
+ onLoadSubsetResult
11692
11797
  });
11693
11798
  return subscription;
11694
11799
  }
11695
- subscribeToOrderedChanges(whereExpression, orderByInfo, onStatusChange) {
11800
+ subscribeToOrderedChanges(whereExpression, orderByInfo, onStatusChange, onLoadSubsetResult) {
11696
11801
  const { orderBy, offset, limit, index } = orderByInfo;
11802
+ const handleLoadSubsetResult = (result) => {
11803
+ if (result instanceof Promise) {
11804
+ this.pendingOrderedLoadPromise = result;
11805
+ result.finally(() => {
11806
+ if (this.pendingOrderedLoadPromise === result) {
11807
+ this.pendingOrderedLoadPromise = void 0;
11808
+ }
11809
+ });
11810
+ }
11811
+ onLoadSubsetResult(result);
11812
+ };
11813
+ this.orderedLoadSubsetResult = handleLoadSubsetResult;
11697
11814
  const subscriptionHolder = {};
11698
11815
  const sendChangesInRange = (changes) => {
11699
- const splittedChanges = splitUpdates(changes);
11816
+ const changesArray = Array.isArray(changes) ? changes : [...changes];
11817
+ this.trackSentValues(changesArray, orderByInfo.comparator);
11818
+ const splittedChanges = splitUpdates(changesArray);
11700
11819
  this.sendChangesToPipelineWithTracking(
11701
11820
  splittedChanges,
11702
11821
  subscriptionHolder.current
@@ -11709,6 +11828,8 @@ class CollectionSubscriber {
11709
11828
  subscriptionHolder.current = subscription;
11710
11829
  const truncateUnsubscribe = this.collection.on(`truncate`, () => {
11711
11830
  this.biggest = void 0;
11831
+ this.lastLoadRequestKey = void 0;
11832
+ this.pendingOrderedLoadPromise = void 0;
11712
11833
  this.sentToD2Keys.clear();
11713
11834
  });
11714
11835
  subscription.on(`unsubscribed`, () => {
@@ -11719,12 +11840,16 @@ class CollectionSubscriber {
11719
11840
  subscription.setOrderByIndex(index);
11720
11841
  subscription.requestLimitedSnapshot({
11721
11842
  limit: offset + limit,
11722
- orderBy: normalizedOrderBy
11843
+ orderBy: normalizedOrderBy,
11844
+ trackLoadSubsetPromise: false,
11845
+ onLoadSubsetResult: handleLoadSubsetResult
11723
11846
  });
11724
11847
  } else {
11725
11848
  subscription.requestSnapshot({
11726
11849
  orderBy: normalizedOrderBy,
11727
- limit: offset + limit
11850
+ limit: offset + limit,
11851
+ trackLoadSubsetPromise: false,
11852
+ onLoadSubsetResult: handleLoadSubsetResult
11728
11853
  });
11729
11854
  }
11730
11855
  return subscription;
@@ -11741,6 +11866,9 @@ class CollectionSubscriber {
11741
11866
  if (!dataNeeded) {
11742
11867
  return true;
11743
11868
  }
11869
+ if (this.pendingOrderedLoadPromise) {
11870
+ return true;
11871
+ }
11744
11872
  const n = dataNeeded();
11745
11873
  if (n > 0) {
11746
11874
  this.loadNextItems(n, subscription);
@@ -11753,11 +11881,10 @@ class CollectionSubscriber {
11753
11881
  this.sendChangesToPipeline(changes);
11754
11882
  return;
11755
11883
  }
11756
- const trackedChanges = this.trackSentValues(changes, orderByInfo.comparator);
11757
11884
  const subscriptionWithLoader = subscription;
11758
11885
  subscriptionWithLoader[loadMoreCallbackSymbol] ??= this.loadMoreIfNeeded.bind(this, subscription);
11759
11886
  this.sendChangesToPipeline(
11760
- trackedChanges,
11887
+ changes,
11761
11888
  subscriptionWithLoader[loadMoreCallbackSymbol]
11762
11889
  );
11763
11890
  }
@@ -11771,14 +11898,29 @@ class CollectionSubscriber {
11771
11898
  const { orderBy, valueExtractorForRawRow, offset } = orderByInfo;
11772
11899
  const biggestSentRow = this.biggest;
11773
11900
  const extractedValues = biggestSentRow ? valueExtractorForRawRow(biggestSentRow) : void 0;
11774
- const minValues = extractedValues !== void 0 ? Array.isArray(extractedValues) ? extractedValues : [extractedValues] : void 0;
11901
+ let minValues;
11902
+ if (extractedValues !== void 0) {
11903
+ minValues = Array.isArray(extractedValues) ? extractedValues : [extractedValues];
11904
+ }
11905
+ const loadRequestKey = this.getLoadRequestKey({
11906
+ minValues,
11907
+ offset,
11908
+ limit: n
11909
+ });
11910
+ if (this.lastLoadRequestKey === loadRequestKey) {
11911
+ return;
11912
+ }
11775
11913
  const normalizedOrderBy = normalizeOrderByPaths(orderBy, this.alias);
11776
11914
  subscription.requestLimitedSnapshot({
11777
11915
  orderBy: normalizedOrderBy,
11778
11916
  limit: n,
11779
11917
  minValues,
11780
- offset
11918
+ // Omit offset so requestLimitedSnapshot can advance the offset based on
11919
+ // the number of rows already loaded (supports offset-based backends).
11920
+ trackLoadSubsetPromise: false,
11921
+ onLoadSubsetResult: this.orderedLoadSubsetResult
11781
11922
  });
11923
+ this.lastLoadRequestKey = loadRequestKey;
11782
11924
  }
11783
11925
  getWhereClauseForAlias() {
11784
11926
  const sourceWhereClausesCache = this.collectionConfigBuilder.sourceWhereClausesCache;
@@ -11794,18 +11936,45 @@ class CollectionSubscriber {
11794
11936
  }
11795
11937
  return void 0;
11796
11938
  }
11797
- *trackSentValues(changes, comparator) {
11939
+ trackSentValues(changes, comparator) {
11798
11940
  for (const change of changes) {
11799
- if (change.type !== `delete`) {
11800
- if (!this.biggest) {
11801
- this.biggest = change.value;
11802
- } else if (comparator(this.biggest, change.value) < 0) {
11803
- this.biggest = change.value;
11804
- }
11941
+ if (change.type === `delete`) {
11942
+ continue;
11943
+ }
11944
+ const isNewKey = !this.sentToD2Keys.has(change.key);
11945
+ if (!this.biggest) {
11946
+ this.biggest = change.value;
11947
+ this.lastLoadRequestKey = void 0;
11948
+ } else if (comparator(this.biggest, change.value) < 0) {
11949
+ this.biggest = change.value;
11950
+ this.lastLoadRequestKey = void 0;
11951
+ } else if (isNewKey) {
11952
+ this.lastLoadRequestKey = void 0;
11805
11953
  }
11806
- yield change;
11807
11954
  }
11808
11955
  }
11956
+ ensureLoadingPromise(subscription) {
11957
+ if (this.subscriptionLoadingPromises.has(subscription)) {
11958
+ return;
11959
+ }
11960
+ let resolve;
11961
+ const promise = new Promise((res) => {
11962
+ resolve = res;
11963
+ });
11964
+ this.subscriptionLoadingPromises.set(subscription, {
11965
+ resolve
11966
+ });
11967
+ this.collectionConfigBuilder.liveQueryCollection._sync.trackLoadPromise(
11968
+ promise
11969
+ );
11970
+ }
11971
+ getLoadRequestKey(options) {
11972
+ return serializeValue({
11973
+ minValues: options.minValues ?? null,
11974
+ offset: options.offset,
11975
+ limit: options.limit
11976
+ });
11977
+ }
11809
11978
  }
11810
11979
  function sendChangesToInput(input, changes, getKey) {
11811
11980
  const multiSetArray = [];
@@ -12333,7 +12502,10 @@ class CollectionConfigBuilder {
12333
12502
  if (this.isInErrorState) {
12334
12503
  return;
12335
12504
  }
12336
- if (this.currentSyncState?.subscribedToAllCollections && this.allCollectionsReady() && !this.liveQueryCollection?.isLoadingSubset) {
12505
+ const subscribedToAll = this.currentSyncState?.subscribedToAllCollections;
12506
+ const allReady = this.allCollectionsReady();
12507
+ const isLoading = this.liveQueryCollection?.isLoadingSubset;
12508
+ if (subscribedToAll && allReady && !isLoading) {
12337
12509
  markReady();
12338
12510
  }
12339
12511
  }