@tanstack/db 0.5.7 → 0.5.9

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.
@@ -371,11 +371,11 @@ export type RefsForContext<TContext extends Context> = {
371
371
  > extends true
372
372
  ? IsNonExactNullable<TContext[`schema`][K]> extends true
373
373
  ? // T is both non-exact optional and non-exact nullable (e.g., string | null | undefined)
374
- // Extract the non-undefined and non-null part and place undefined outside
375
- Ref<NonNullable<TContext[`schema`][K]>> | undefined
374
+ // Extract the non-undefined and non-null part and place undefined outside
375
+ Ref<NonNullable<TContext[`schema`][K]>> | undefined
376
376
  : // T is optional (T | undefined) but not exactly undefined, and not nullable
377
- // Extract the non-undefined part and place undefined outside
378
- Ref<NonUndefined<TContext[`schema`][K]>> | undefined
377
+ // Extract the non-undefined part and place undefined outside
378
+ Ref<NonUndefined<TContext[`schema`][K]>> | undefined
379
379
  : IsNonExactNullable<TContext[`schema`][K]> extends true
380
380
  ? // T is nullable (T | null) but not exactly null, and not optional
381
381
  // Extract the non-null part and place null outside
@@ -612,7 +612,7 @@ export type ApplyJoinOptionalityToMergedSchema<
612
612
  // Apply optionality to new schema based on join type
613
613
  [K in keyof TNewSchema]: TJoinType extends `left` | `full`
614
614
  ? // New table becomes optional for left and full joins
615
- TNewSchema[K] | undefined
615
+ TNewSchema[K] | undefined
616
616
  : // New table is required for inner and right joins
617
617
  TNewSchema[K]
618
618
  }
@@ -802,6 +802,33 @@ export function isPredicateSubset(
802
802
  subset: LoadSubsetOptions,
803
803
  superset: LoadSubsetOptions
804
804
  ): boolean {
805
+ // When the superset has a limit, we can only determine subset relationship
806
+ // if the where clauses are equal (not just subset relationship).
807
+ //
808
+ // This is because a limited query only loads a portion of the matching rows.
809
+ // A more restrictive where clause might require rows outside that portion.
810
+ //
811
+ // Example: superset = {where: undefined, limit: 10, orderBy: desc}
812
+ // subset = {where: LIKE 'search%', limit: 10, orderBy: desc}
813
+ // The top 10 items matching 'search%' might include items outside the overall top 10.
814
+ //
815
+ // However, if the where clauses are equal, then the subset relationship can
816
+ // be determined by orderBy and limit alone:
817
+ // Example: superset = {where: status='active', limit: 10, orderBy: desc}
818
+ // subset = {where: status='active', limit: 5, orderBy: desc}
819
+ // The top 5 active items ARE contained in the top 10 active items.
820
+ if (superset.limit !== undefined) {
821
+ // For limited supersets, where clauses must be equal
822
+ if (!areWhereClausesEqual(subset.where, superset.where)) {
823
+ return false
824
+ }
825
+ return (
826
+ isOrderBySubset(subset.orderBy, superset.orderBy) &&
827
+ isLimitSubset(subset.limit, superset.limit)
828
+ )
829
+ }
830
+
831
+ // For unlimited supersets, use the normal subset logic
805
832
  return (
806
833
  isWhereSubset(subset.where, superset.where) &&
807
834
  isOrderBySubset(subset.orderBy, superset.orderBy) &&
@@ -809,6 +836,23 @@ export function isPredicateSubset(
809
836
  )
810
837
  }
811
838
 
839
+ /**
840
+ * Check if two where clauses are structurally equal.
841
+ * Used for limited query subset checks where subset relationship isn't sufficient.
842
+ */
843
+ function areWhereClausesEqual(
844
+ a: BasicExpression<boolean> | undefined,
845
+ b: BasicExpression<boolean> | undefined
846
+ ): boolean {
847
+ if (a === undefined && b === undefined) {
848
+ return true
849
+ }
850
+ if (a === undefined || b === undefined) {
851
+ return false
852
+ }
853
+ return areExpressionsEqual(a, b)
854
+ }
855
+
812
856
  // ============================================================================
813
857
  // Helper functions
814
858
  // ============================================================================
package/src/types.ts CHANGED
@@ -13,9 +13,9 @@ export interface CollectionLike<
13
13
  T extends object = Record<string, unknown>,
14
14
  TKey extends string | number = string | number,
15
15
  > extends Pick<
16
- Collection<T, TKey>,
17
- `get` | `has` | `entries` | `indexes` | `id` | `compareOptions`
18
- > {}
16
+ Collection<T, TKey>,
17
+ `get` | `has` | `entries` | `indexes` | `id` | `compareOptions`
18
+ > {}
19
19
 
20
20
  /**
21
21
  * StringSortOpts - Options for string sorting behavior
@@ -727,8 +727,10 @@ export interface SubscribeChangesOptions {
727
727
  whereExpression?: BasicExpression<boolean>
728
728
  }
729
729
 
730
- export interface SubscribeChangesSnapshotOptions
731
- extends Omit<SubscribeChangesOptions, `includeInitialState`> {
730
+ export interface SubscribeChangesSnapshotOptions extends Omit<
731
+ SubscribeChangesOptions,
732
+ `includeInitialState`
733
+ > {
732
734
  orderBy?: OrderBy
733
735
  limit?: number
734
736
  }