@tanstack/db 0.5.33 → 0.6.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.
Files changed (273) hide show
  1. package/dist/cjs/collection/change-events.cjs.map +1 -1
  2. package/dist/cjs/collection/change-events.d.cts +3 -2
  3. package/dist/cjs/collection/changes.cjs +13 -4
  4. package/dist/cjs/collection/changes.cjs.map +1 -1
  5. package/dist/cjs/collection/changes.d.cts +10 -1
  6. package/dist/cjs/collection/cleanup-queue.cjs +89 -0
  7. package/dist/cjs/collection/cleanup-queue.cjs.map +1 -0
  8. package/dist/cjs/collection/cleanup-queue.d.cts +30 -0
  9. package/dist/cjs/collection/events.cjs +14 -0
  10. package/dist/cjs/collection/events.cjs.map +1 -1
  11. package/dist/cjs/collection/events.d.cts +39 -1
  12. package/dist/cjs/collection/index.cjs +66 -28
  13. package/dist/cjs/collection/index.cjs.map +1 -1
  14. package/dist/cjs/collection/index.d.cts +49 -36
  15. package/dist/cjs/collection/indexes.cjs +211 -62
  16. package/dist/cjs/collection/indexes.cjs.map +1 -1
  17. package/dist/cjs/collection/indexes.d.cts +27 -17
  18. package/dist/cjs/collection/lifecycle.cjs +5 -22
  19. package/dist/cjs/collection/lifecycle.cjs.map +1 -1
  20. package/dist/cjs/collection/lifecycle.d.cts +0 -1
  21. package/dist/cjs/collection/mutations.cjs +18 -0
  22. package/dist/cjs/collection/mutations.cjs.map +1 -1
  23. package/dist/cjs/collection/mutations.d.cts +1 -0
  24. package/dist/cjs/collection/state.cjs +381 -53
  25. package/dist/cjs/collection/state.cjs.map +1 -1
  26. package/dist/cjs/collection/state.d.cts +65 -1
  27. package/dist/cjs/collection/subscription.cjs +6 -0
  28. package/dist/cjs/collection/subscription.cjs.map +1 -1
  29. package/dist/cjs/collection/subscription.d.cts +4 -0
  30. package/dist/cjs/collection/sync.cjs +108 -1
  31. package/dist/cjs/collection/sync.cjs.map +1 -1
  32. package/dist/cjs/collection/sync.d.cts +2 -0
  33. package/dist/cjs/collection/transaction-metadata.cjs +5 -0
  34. package/dist/cjs/collection/transaction-metadata.cjs.map +1 -0
  35. package/dist/cjs/collection/transaction-metadata.d.cts +1 -0
  36. package/dist/cjs/errors.cjs +8 -0
  37. package/dist/cjs/errors.cjs.map +1 -1
  38. package/dist/cjs/errors.d.cts +3 -0
  39. package/dist/cjs/index.cjs +22 -4
  40. package/dist/cjs/index.cjs.map +1 -1
  41. package/dist/cjs/index.d.cts +11 -3
  42. package/dist/cjs/indexes/auto-index.cjs +13 -6
  43. package/dist/cjs/indexes/auto-index.cjs.map +1 -1
  44. package/dist/cjs/indexes/base-index.cjs +0 -3
  45. package/dist/cjs/indexes/base-index.cjs.map +1 -1
  46. package/dist/cjs/indexes/base-index.d.cts +2 -6
  47. package/dist/cjs/indexes/basic-index.cjs +361 -0
  48. package/dist/cjs/indexes/basic-index.cjs.map +1 -0
  49. package/dist/cjs/indexes/basic-index.d.cts +102 -0
  50. package/dist/cjs/indexes/btree-index.cjs.map +1 -1
  51. package/dist/cjs/indexes/btree-index.d.cts +1 -1
  52. package/dist/cjs/indexes/index-options.d.cts +8 -9
  53. package/dist/cjs/indexes/index-registry.cjs +89 -0
  54. package/dist/cjs/indexes/index-registry.cjs.map +1 -0
  55. package/dist/cjs/indexes/index-registry.d.cts +61 -0
  56. package/dist/cjs/local-only.cjs +5 -0
  57. package/dist/cjs/local-only.cjs.map +1 -1
  58. package/dist/cjs/query/builder/functions.cjs +27 -11
  59. package/dist/cjs/query/builder/functions.cjs.map +1 -1
  60. package/dist/cjs/query/builder/functions.d.cts +25 -3
  61. package/dist/cjs/query/builder/index.cjs +200 -39
  62. package/dist/cjs/query/builder/index.cjs.map +1 -1
  63. package/dist/cjs/query/builder/index.d.cts +4 -3
  64. package/dist/cjs/query/builder/ref-proxy.cjs.map +1 -1
  65. package/dist/cjs/query/builder/ref-proxy.d.cts +14 -3
  66. package/dist/cjs/query/builder/types.d.cts +84 -19
  67. package/dist/cjs/query/compiler/evaluators.cjs +51 -0
  68. package/dist/cjs/query/compiler/evaluators.cjs.map +1 -1
  69. package/dist/cjs/query/compiler/group-by.cjs +100 -28
  70. package/dist/cjs/query/compiler/group-by.cjs.map +1 -1
  71. package/dist/cjs/query/compiler/group-by.d.cts +4 -2
  72. package/dist/cjs/query/compiler/index.cjs +283 -11
  73. package/dist/cjs/query/compiler/index.cjs.map +1 -1
  74. package/dist/cjs/query/compiler/index.d.cts +30 -2
  75. package/dist/cjs/query/compiler/order-by.cjs +29 -10
  76. package/dist/cjs/query/compiler/order-by.cjs.map +1 -1
  77. package/dist/cjs/query/compiler/order-by.d.cts +1 -1
  78. package/dist/cjs/query/compiler/select.cjs +8 -0
  79. package/dist/cjs/query/compiler/select.cjs.map +1 -1
  80. package/dist/cjs/query/index.d.cts +2 -1
  81. package/dist/cjs/query/ir.cjs +18 -1
  82. package/dist/cjs/query/ir.cjs.map +1 -1
  83. package/dist/cjs/query/ir.d.cts +21 -1
  84. package/dist/cjs/query/live/collection-config-builder.cjs +501 -5
  85. package/dist/cjs/query/live/collection-config-builder.cjs.map +1 -1
  86. package/dist/cjs/query/live/collection-config-builder.d.cts +7 -0
  87. package/dist/cjs/query/live/types.d.cts +3 -3
  88. package/dist/cjs/query/live/utils.cjs +43 -3
  89. package/dist/cjs/query/live/utils.cjs.map +1 -1
  90. package/dist/cjs/query/live/utils.d.cts +1 -0
  91. package/dist/cjs/query/live-query-collection.cjs.map +1 -1
  92. package/dist/cjs/query/live-query-collection.d.cts +9 -6
  93. package/dist/cjs/query/query-once.cjs.map +1 -1
  94. package/dist/cjs/query/query-once.d.cts +7 -5
  95. package/dist/cjs/query/subset-dedupe.cjs +9 -3
  96. package/dist/cjs/query/subset-dedupe.cjs.map +1 -1
  97. package/dist/cjs/types.d.cts +42 -8
  98. package/dist/cjs/utils/array-utils.cjs +27 -0
  99. package/dist/cjs/utils/array-utils.cjs.map +1 -0
  100. package/dist/cjs/utils/array-utils.d.cts +16 -0
  101. package/dist/cjs/utils/comparison.cjs +11 -0
  102. package/dist/cjs/utils/comparison.cjs.map +1 -1
  103. package/dist/cjs/utils/index-optimization.cjs +4 -0
  104. package/dist/cjs/utils/index-optimization.cjs.map +1 -1
  105. package/dist/cjs/utils.cjs +7 -9
  106. package/dist/cjs/utils.cjs.map +1 -1
  107. package/dist/cjs/utils.d.cts +6 -1
  108. package/dist/cjs/virtual-props.cjs +33 -0
  109. package/dist/cjs/virtual-props.cjs.map +1 -0
  110. package/dist/cjs/virtual-props.d.cts +196 -0
  111. package/dist/esm/collection/change-events.d.ts +3 -2
  112. package/dist/esm/collection/change-events.js.map +1 -1
  113. package/dist/esm/collection/changes.d.ts +10 -1
  114. package/dist/esm/collection/changes.js +13 -4
  115. package/dist/esm/collection/changes.js.map +1 -1
  116. package/dist/esm/collection/cleanup-queue.d.ts +30 -0
  117. package/dist/esm/collection/cleanup-queue.js +89 -0
  118. package/dist/esm/collection/cleanup-queue.js.map +1 -0
  119. package/dist/esm/collection/events.d.ts +39 -1
  120. package/dist/esm/collection/events.js +14 -0
  121. package/dist/esm/collection/events.js.map +1 -1
  122. package/dist/esm/collection/index.d.ts +49 -36
  123. package/dist/esm/collection/index.js +67 -29
  124. package/dist/esm/collection/index.js.map +1 -1
  125. package/dist/esm/collection/indexes.d.ts +27 -17
  126. package/dist/esm/collection/indexes.js +211 -62
  127. package/dist/esm/collection/indexes.js.map +1 -1
  128. package/dist/esm/collection/lifecycle.d.ts +0 -1
  129. package/dist/esm/collection/lifecycle.js +5 -22
  130. package/dist/esm/collection/lifecycle.js.map +1 -1
  131. package/dist/esm/collection/mutations.d.ts +1 -0
  132. package/dist/esm/collection/mutations.js +18 -0
  133. package/dist/esm/collection/mutations.js.map +1 -1
  134. package/dist/esm/collection/state.d.ts +65 -1
  135. package/dist/esm/collection/state.js +381 -53
  136. package/dist/esm/collection/state.js.map +1 -1
  137. package/dist/esm/collection/subscription.d.ts +4 -0
  138. package/dist/esm/collection/subscription.js +6 -0
  139. package/dist/esm/collection/subscription.js.map +1 -1
  140. package/dist/esm/collection/sync.d.ts +2 -0
  141. package/dist/esm/collection/sync.js +108 -1
  142. package/dist/esm/collection/sync.js.map +1 -1
  143. package/dist/esm/collection/transaction-metadata.d.ts +1 -0
  144. package/dist/esm/collection/transaction-metadata.js +5 -0
  145. package/dist/esm/collection/transaction-metadata.js.map +1 -0
  146. package/dist/esm/errors.d.ts +3 -0
  147. package/dist/esm/errors.js +8 -0
  148. package/dist/esm/errors.js.map +1 -1
  149. package/dist/esm/index.d.ts +11 -3
  150. package/dist/esm/index.js +25 -7
  151. package/dist/esm/index.js.map +1 -1
  152. package/dist/esm/indexes/auto-index.js +13 -6
  153. package/dist/esm/indexes/auto-index.js.map +1 -1
  154. package/dist/esm/indexes/base-index.d.ts +2 -6
  155. package/dist/esm/indexes/base-index.js +1 -4
  156. package/dist/esm/indexes/base-index.js.map +1 -1
  157. package/dist/esm/indexes/basic-index.d.ts +102 -0
  158. package/dist/esm/indexes/basic-index.js +361 -0
  159. package/dist/esm/indexes/basic-index.js.map +1 -0
  160. package/dist/esm/indexes/btree-index.d.ts +1 -1
  161. package/dist/esm/indexes/btree-index.js.map +1 -1
  162. package/dist/esm/indexes/index-options.d.ts +8 -9
  163. package/dist/esm/indexes/index-registry.d.ts +61 -0
  164. package/dist/esm/indexes/index-registry.js +89 -0
  165. package/dist/esm/indexes/index-registry.js.map +1 -0
  166. package/dist/esm/local-only.js +5 -0
  167. package/dist/esm/local-only.js.map +1 -1
  168. package/dist/esm/query/builder/functions.d.ts +25 -3
  169. package/dist/esm/query/builder/functions.js +27 -11
  170. package/dist/esm/query/builder/functions.js.map +1 -1
  171. package/dist/esm/query/builder/index.d.ts +4 -3
  172. package/dist/esm/query/builder/index.js +201 -40
  173. package/dist/esm/query/builder/index.js.map +1 -1
  174. package/dist/esm/query/builder/ref-proxy.d.ts +14 -3
  175. package/dist/esm/query/builder/ref-proxy.js.map +1 -1
  176. package/dist/esm/query/builder/types.d.ts +84 -19
  177. package/dist/esm/query/compiler/evaluators.js +51 -0
  178. package/dist/esm/query/compiler/evaluators.js.map +1 -1
  179. package/dist/esm/query/compiler/group-by.d.ts +4 -2
  180. package/dist/esm/query/compiler/group-by.js +101 -29
  181. package/dist/esm/query/compiler/group-by.js.map +1 -1
  182. package/dist/esm/query/compiler/index.d.ts +30 -2
  183. package/dist/esm/query/compiler/index.js +285 -13
  184. package/dist/esm/query/compiler/index.js.map +1 -1
  185. package/dist/esm/query/compiler/order-by.d.ts +1 -1
  186. package/dist/esm/query/compiler/order-by.js +30 -11
  187. package/dist/esm/query/compiler/order-by.js.map +1 -1
  188. package/dist/esm/query/compiler/select.js +8 -0
  189. package/dist/esm/query/compiler/select.js.map +1 -1
  190. package/dist/esm/query/index.d.ts +2 -1
  191. package/dist/esm/query/ir.d.ts +21 -1
  192. package/dist/esm/query/ir.js +18 -1
  193. package/dist/esm/query/ir.js.map +1 -1
  194. package/dist/esm/query/live/collection-config-builder.d.ts +7 -0
  195. package/dist/esm/query/live/collection-config-builder.js +503 -7
  196. package/dist/esm/query/live/collection-config-builder.js.map +1 -1
  197. package/dist/esm/query/live/types.d.ts +3 -3
  198. package/dist/esm/query/live/utils.d.ts +1 -0
  199. package/dist/esm/query/live/utils.js +43 -3
  200. package/dist/esm/query/live/utils.js.map +1 -1
  201. package/dist/esm/query/live-query-collection.d.ts +9 -6
  202. package/dist/esm/query/live-query-collection.js.map +1 -1
  203. package/dist/esm/query/query-once.d.ts +7 -5
  204. package/dist/esm/query/query-once.js.map +1 -1
  205. package/dist/esm/query/subset-dedupe.js +9 -3
  206. package/dist/esm/query/subset-dedupe.js.map +1 -1
  207. package/dist/esm/types.d.ts +42 -8
  208. package/dist/esm/utils/array-utils.d.ts +16 -0
  209. package/dist/esm/utils/array-utils.js +27 -0
  210. package/dist/esm/utils/array-utils.js.map +1 -0
  211. package/dist/esm/utils/comparison.js +11 -0
  212. package/dist/esm/utils/comparison.js.map +1 -1
  213. package/dist/esm/utils/index-optimization.js +4 -0
  214. package/dist/esm/utils/index-optimization.js.map +1 -1
  215. package/dist/esm/utils.d.ts +6 -1
  216. package/dist/esm/utils.js +7 -9
  217. package/dist/esm/utils.js.map +1 -1
  218. package/dist/esm/virtual-props.d.ts +196 -0
  219. package/dist/esm/virtual-props.js +33 -0
  220. package/dist/esm/virtual-props.js.map +1 -0
  221. package/package.json +2 -2
  222. package/skills/db-core/collection-setup/references/electric-adapter.md +1 -1
  223. package/src/collection/change-events.ts +13 -9
  224. package/src/collection/changes.ts +30 -7
  225. package/src/collection/cleanup-queue.ts +105 -0
  226. package/src/collection/events.ts +65 -0
  227. package/src/collection/index.ts +110 -45
  228. package/src/collection/indexes.ts +283 -76
  229. package/src/collection/lifecycle.ts +5 -26
  230. package/src/collection/mutations.ts +21 -0
  231. package/src/collection/state.ts +545 -71
  232. package/src/collection/subscription.ts +7 -0
  233. package/src/collection/sync.ts +137 -0
  234. package/src/collection/transaction-metadata.ts +1 -0
  235. package/src/errors.ts +9 -0
  236. package/src/index.ts +46 -3
  237. package/src/indexes/auto-index.ts +18 -8
  238. package/src/indexes/base-index.ts +2 -10
  239. package/src/indexes/basic-index.ts +507 -0
  240. package/src/indexes/btree-index.ts +1 -1
  241. package/src/indexes/index-options.ts +17 -37
  242. package/src/indexes/index-registry.ts +174 -0
  243. package/src/local-only.ts +7 -0
  244. package/src/query/builder/functions.ts +84 -7
  245. package/src/query/builder/index.ts +329 -9
  246. package/src/query/builder/ref-proxy.ts +22 -4
  247. package/src/query/builder/types.ts +257 -62
  248. package/src/query/compiler/evaluators.ts +57 -0
  249. package/src/query/compiler/group-by.ts +156 -35
  250. package/src/query/compiler/index.ts +445 -15
  251. package/src/query/compiler/order-by.ts +51 -12
  252. package/src/query/compiler/select.ts +9 -0
  253. package/src/query/index.ts +7 -0
  254. package/src/query/ir.ts +23 -2
  255. package/src/query/live/collection-config-builder.ts +809 -9
  256. package/src/query/live/types.ts +10 -4
  257. package/src/query/live/utils.ts +64 -3
  258. package/src/query/live-query-collection.ts +43 -18
  259. package/src/query/query-once.ts +31 -12
  260. package/src/query/subset-dedupe.ts +11 -7
  261. package/src/types.ts +49 -9
  262. package/src/utils/array-utils.ts +49 -0
  263. package/src/utils/comparison.ts +14 -0
  264. package/src/utils/index-optimization.ts +4 -0
  265. package/src/utils.ts +12 -9
  266. package/src/virtual-props.ts +282 -0
  267. package/dist/cjs/indexes/lazy-index.cjs +0 -190
  268. package/dist/cjs/indexes/lazy-index.cjs.map +0 -1
  269. package/dist/cjs/indexes/lazy-index.d.cts +0 -96
  270. package/dist/esm/indexes/lazy-index.d.ts +0 -96
  271. package/dist/esm/indexes/lazy-index.js +0 -190
  272. package/dist/esm/indexes/lazy-index.js.map +0 -1
  273. package/src/indexes/lazy-index.ts +0 -251
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Virtual Properties for TanStack DB
3
+ *
4
+ * Virtual properties are computed, read-only properties that provide metadata about rows
5
+ * (sync status, source, selection state) without being part of the persisted data model.
6
+ *
7
+ * Virtual properties are prefixed with `$` to distinguish them from user data fields.
8
+ * User schemas should not include `$`-prefixed fields as they are reserved.
9
+ */
10
+
11
+ /**
12
+ * Origin of the last confirmed change to a row, from the current client's perspective.
13
+ *
14
+ * - `'local'`: The change originated from this client (e.g., a mutation made here)
15
+ * - `'remote'`: The change was received via sync from another client/server
16
+ *
17
+ * Note: This reflects the client's perspective, not the original creator.
18
+ * User A creates order → $origin = 'local' on User A's client
19
+ * Order syncs to server
20
+ * User B receives order → $origin = 'remote' on User B's client
21
+ */
22
+ export type VirtualOrigin = 'local' | 'remote'
23
+
24
+ /**
25
+ * Virtual properties available on every row in TanStack DB collections.
26
+ *
27
+ * These properties are:
28
+ * - Computed (not stored in the data model)
29
+ * - Read-only (cannot be mutated directly)
30
+ * - Available in queries (WHERE, ORDER BY, SELECT)
31
+ * - Included when spreading rows (`...user`)
32
+ *
33
+ * @template TKey - The type of the row's key (string or number)
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * // Accessing virtual properties on a row
38
+ * const user = collection.get('user-1')
39
+ * if (user.$synced) {
40
+ * console.log('Confirmed by backend')
41
+ * }
42
+ * if (user.$origin === 'local') {
43
+ * console.log('Created/modified locally')
44
+ * }
45
+ * ```
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Using virtual properties in queries
50
+ * const confirmedOrders = createLiveQueryCollection({
51
+ * query: (q) => q
52
+ * .from({ order: orders })
53
+ * .where(({ order }) => eq(order.$synced, true))
54
+ * })
55
+ * ```
56
+ */
57
+ export interface VirtualRowProps<
58
+ TKey extends string | number = string | number,
59
+ > {
60
+ /**
61
+ * Whether this row reflects confirmed state from the backend.
62
+ *
63
+ * - `true`: Row is confirmed by the backend (no pending optimistic mutations)
64
+ * - `false`: Row has pending optimistic mutations that haven't been confirmed
65
+ *
66
+ * For local-only collections (no sync), this is always `true`.
67
+ * For live query collections, this is passed through from the source collection.
68
+ */
69
+ readonly $synced: boolean
70
+
71
+ /**
72
+ * Origin of the last confirmed change to this row, from the current client's perspective.
73
+ *
74
+ * - `'local'`: The change originated from this client
75
+ * - `'remote'`: The change was received via sync
76
+ *
77
+ * For local-only collections, this is always `'local'`.
78
+ * For live query collections, this is passed through from the source collection.
79
+ */
80
+ readonly $origin: VirtualOrigin
81
+
82
+ /**
83
+ * The row's key (primary identifier).
84
+ *
85
+ * This is the same value returned by `collection.config.getKey(row)`.
86
+ * Useful when you need the key in projections or computations.
87
+ */
88
+ readonly $key: TKey
89
+
90
+ /**
91
+ * The ID of the source collection this row originated from.
92
+ *
93
+ * In joins, this can help identify which collection each row came from.
94
+ * For live query collections, this is the ID of the upstream collection.
95
+ */
96
+ readonly $collectionId: string
97
+ }
98
+
99
+ /**
100
+ * Adds virtual properties to a row type.
101
+ *
102
+ * @template T - The base row type
103
+ * @template TKey - The type of the row's key
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * type User = { id: string; name: string }
108
+ * type UserWithVirtual = WithVirtualProps<User, string>
109
+ * // { id: string; name: string; $synced: boolean; $origin: 'local' | 'remote'; $key: string; $collectionId: string }
110
+ * ```
111
+ */
112
+ export type WithVirtualProps<
113
+ T extends object,
114
+ TKey extends string | number = string | number,
115
+ > = T & VirtualRowProps<TKey>
116
+
117
+ /**
118
+ * Extracts the base type from a type that may have virtual properties.
119
+ * Useful when you need to work with the raw data without virtual properties.
120
+ *
121
+ * @template T - The type that may include virtual properties
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * type UserWithVirtual = { id: string; name: string; $synced: boolean; $origin: 'local' | 'remote' }
126
+ * type User = WithoutVirtualProps<UserWithVirtual>
127
+ * // { id: string; name: string }
128
+ * ```
129
+ */
130
+ export type WithoutVirtualProps<T> = Omit<T, keyof VirtualRowProps>
131
+
132
+ /**
133
+ * Checks if a value has virtual properties attached.
134
+ *
135
+ * @param value - The value to check
136
+ * @returns true if the value has virtual properties
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * if (hasVirtualProps(row)) {
141
+ * console.log('Synced:', row.$synced)
142
+ * }
143
+ * ```
144
+ */
145
+ export function hasVirtualProps(
146
+ value: unknown,
147
+ ): value is VirtualRowProps<string | number> {
148
+ return (
149
+ typeof value === 'object' &&
150
+ value !== null &&
151
+ VIRTUAL_PROP_NAMES.every((name) => name in value)
152
+ )
153
+ }
154
+
155
+ /**
156
+ * Creates virtual properties for a row in a source collection.
157
+ *
158
+ * This is the internal function used by collections to add virtual properties
159
+ * to rows when emitting change messages.
160
+ *
161
+ * @param key - The row's key
162
+ * @param collectionId - The collection's ID
163
+ * @param isSynced - Whether the row is synced (not optimistic)
164
+ * @param origin - Whether the change was local or remote
165
+ * @returns Virtual properties object to merge with the row
166
+ *
167
+ * @internal
168
+ */
169
+ export function createVirtualProps<TKey extends string | number>(
170
+ key: TKey,
171
+ collectionId: string,
172
+ isSynced: boolean,
173
+ origin: VirtualOrigin,
174
+ ): VirtualRowProps<TKey> {
175
+ return {
176
+ $synced: isSynced,
177
+ $origin: origin,
178
+ $key: key,
179
+ $collectionId: collectionId,
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Enriches a row with virtual properties using the "add-if-missing" pattern.
185
+ *
186
+ * If the row already has virtual properties (from an upstream collection),
187
+ * they are preserved. If not, new virtual properties are computed and added.
188
+ *
189
+ * This is the key function that enables pass-through semantics for nested
190
+ * live query collections.
191
+ *
192
+ * @param row - The row to enrich
193
+ * @param key - The row's key
194
+ * @param collectionId - The collection's ID
195
+ * @param computeSynced - Function to compute $synced if missing
196
+ * @param computeOrigin - Function to compute $origin if missing
197
+ * @returns The row with virtual properties (possibly the same object if already present)
198
+ *
199
+ * @internal
200
+ */
201
+ export function enrichRowWithVirtualProps<
202
+ T extends object,
203
+ TKey extends string | number,
204
+ >(
205
+ row: T,
206
+ key: TKey,
207
+ collectionId: string,
208
+ computeSynced: () => boolean,
209
+ computeOrigin: () => VirtualOrigin,
210
+ ): WithVirtualProps<T, TKey> {
211
+ // Use nullish coalescing to preserve existing virtual properties (pass-through)
212
+ // This is the "add-if-missing" pattern described in the RFC
213
+ const existingRow = row as Partial<VirtualRowProps<TKey>>
214
+
215
+ return {
216
+ ...row,
217
+ $synced: existingRow.$synced ?? computeSynced(),
218
+ $origin: existingRow.$origin ?? computeOrigin(),
219
+ $key: existingRow.$key ?? key,
220
+ $collectionId: existingRow.$collectionId ?? collectionId,
221
+ } as WithVirtualProps<T, TKey>
222
+ }
223
+
224
+ /**
225
+ * Computes aggregate virtual properties for a group of rows.
226
+ *
227
+ * For aggregates:
228
+ * - `$synced`: true if ALL rows in the group are synced; false if ANY row is optimistic
229
+ * - `$origin`: 'local' if ANY row in the group is local; otherwise 'remote'
230
+ *
231
+ * @param rows - The rows in the group
232
+ * @param groupKey - The group key
233
+ * @param collectionId - The collection ID
234
+ * @returns Virtual properties for the aggregate row
235
+ *
236
+ * @internal
237
+ */
238
+ export function computeAggregateVirtualProps<TKey extends string | number>(
239
+ rows: Array<Partial<VirtualRowProps<string | number>>>,
240
+ groupKey: TKey,
241
+ collectionId: string,
242
+ ): VirtualRowProps<TKey> {
243
+ // $synced = true only if ALL rows are synced (false if ANY is optimistic)
244
+ const allSynced = rows.every((row) => row.$synced ?? true)
245
+
246
+ // $origin = 'local' if ANY row is local (consistent with "local influence" semantics)
247
+ const hasLocal = rows.some((row) => row.$origin === 'local')
248
+
249
+ return {
250
+ $synced: allSynced,
251
+ $origin: hasLocal ? 'local' : 'remote',
252
+ $key: groupKey,
253
+ $collectionId: collectionId,
254
+ }
255
+ }
256
+
257
+ /**
258
+ * List of virtual property names for iteration and checking.
259
+ * @internal
260
+ */
261
+ export const VIRTUAL_PROP_NAMES = [
262
+ '$synced',
263
+ '$origin',
264
+ '$key',
265
+ '$collectionId',
266
+ ] as const
267
+
268
+ /**
269
+ * Checks if a property name is a virtual property.
270
+ * @internal
271
+ */
272
+ export function isVirtualPropName(name: string): boolean {
273
+ return VIRTUAL_PROP_NAMES.includes(name as any)
274
+ }
275
+
276
+ /**
277
+ * Checks whether a property path references a virtual property.
278
+ * @internal
279
+ */
280
+ export function hasVirtualPropPath(path: Array<string>): boolean {
281
+ return path.some((segment) => isVirtualPropName(segment))
282
+ }
@@ -1,190 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- function isConstructor(resolver) {
4
- return typeof resolver === `function` && resolver.prototype !== void 0 && resolver.prototype.constructor === resolver;
5
- }
6
- async function resolveIndexConstructor(resolver) {
7
- if (isConstructor(resolver)) {
8
- return resolver;
9
- } else {
10
- return await resolver();
11
- }
12
- }
13
- class LazyIndexWrapper {
14
- constructor(id, expression, name, resolver, options, collectionEntries) {
15
- this.id = id;
16
- this.expression = expression;
17
- this.name = name;
18
- this.resolver = resolver;
19
- this.options = options;
20
- this.collectionEntries = collectionEntries;
21
- this.indexPromise = null;
22
- this.resolvedIndex = null;
23
- if (isConstructor(this.resolver)) {
24
- this.resolvedIndex = new this.resolver(
25
- this.id,
26
- this.expression,
27
- this.name,
28
- this.options
29
- );
30
- if (this.collectionEntries) {
31
- this.resolvedIndex.build(this.collectionEntries);
32
- }
33
- }
34
- }
35
- /**
36
- * Resolve the actual index
37
- */
38
- async resolve() {
39
- if (this.resolvedIndex) {
40
- return this.resolvedIndex;
41
- }
42
- if (!this.indexPromise) {
43
- this.indexPromise = this.createIndex();
44
- }
45
- this.resolvedIndex = await this.indexPromise;
46
- return this.resolvedIndex;
47
- }
48
- /**
49
- * Check if already resolved
50
- */
51
- isResolved() {
52
- return this.resolvedIndex !== null;
53
- }
54
- /**
55
- * Get resolved index (throws if not ready)
56
- */
57
- getResolved() {
58
- if (!this.resolvedIndex) {
59
- throw new Error(
60
- `Index ${this.id} has not been resolved yet. Ensure collection is synced.`
61
- );
62
- }
63
- return this.resolvedIndex;
64
- }
65
- /**
66
- * Get the index ID
67
- */
68
- getId() {
69
- return this.id;
70
- }
71
- /**
72
- * Get the index name
73
- */
74
- getName() {
75
- return this.name;
76
- }
77
- /**
78
- * Get the index expression
79
- */
80
- getExpression() {
81
- return this.expression;
82
- }
83
- async createIndex() {
84
- const IndexClass = await resolveIndexConstructor(this.resolver);
85
- return new IndexClass(this.id, this.expression, this.name, this.options);
86
- }
87
- }
88
- class IndexProxy {
89
- constructor(indexId, lazyIndex) {
90
- this.indexId = indexId;
91
- this.lazyIndex = lazyIndex;
92
- }
93
- /**
94
- * Get the resolved index (throws if not ready)
95
- */
96
- get index() {
97
- return this.lazyIndex.getResolved();
98
- }
99
- /**
100
- * Check if index is ready
101
- */
102
- get isReady() {
103
- return this.lazyIndex.isResolved();
104
- }
105
- /**
106
- * Wait for index to be ready
107
- */
108
- async whenReady() {
109
- return await this.lazyIndex.resolve();
110
- }
111
- /**
112
- * Get the index ID
113
- */
114
- get id() {
115
- return this.indexId;
116
- }
117
- /**
118
- * Get the index name (throws if not ready)
119
- */
120
- get name() {
121
- if (this.isReady) {
122
- return this.index.name;
123
- }
124
- return this.lazyIndex.getName();
125
- }
126
- /**
127
- * Get the index expression (available immediately)
128
- */
129
- get expression() {
130
- return this.lazyIndex.getExpression();
131
- }
132
- /**
133
- * Check if index supports an operation (throws if not ready)
134
- */
135
- supports(operation) {
136
- return this.index.supports(operation);
137
- }
138
- /**
139
- * Get index statistics (throws if not ready)
140
- */
141
- getStats() {
142
- return this.index.getStats();
143
- }
144
- /**
145
- * Check if index matches a field path (available immediately)
146
- */
147
- matchesField(fieldPath) {
148
- const expr = this.expression;
149
- return expr.type === `ref` && expr.path.length === fieldPath.length && expr.path.every((part, i) => part === fieldPath[i]);
150
- }
151
- /**
152
- * Get the key count (throws if not ready)
153
- */
154
- get keyCount() {
155
- return this.index.keyCount;
156
- }
157
- // Test compatibility properties - delegate to resolved index
158
- get indexedKeysSet() {
159
- const resolved = this.index;
160
- return resolved.indexedKeysSet;
161
- }
162
- get orderedEntriesArray() {
163
- const resolved = this.index;
164
- return resolved.orderedEntriesArray;
165
- }
166
- get valueMapData() {
167
- const resolved = this.index;
168
- return resolved.valueMapData;
169
- }
170
- // BTreeIndex compatibility methods
171
- equalityLookup(value) {
172
- const resolved = this.index;
173
- return resolved.equalityLookup?.(value) ?? /* @__PURE__ */ new Set();
174
- }
175
- rangeQuery(options) {
176
- const resolved = this.index;
177
- return resolved.rangeQuery?.(options) ?? /* @__PURE__ */ new Set();
178
- }
179
- inArrayLookup(values) {
180
- const resolved = this.index;
181
- return resolved.inArrayLookup?.(values) ?? /* @__PURE__ */ new Set();
182
- }
183
- // Internal method for the collection to get the lazy wrapper
184
- _getLazyWrapper() {
185
- return this.lazyIndex;
186
- }
187
- }
188
- exports.IndexProxy = IndexProxy;
189
- exports.LazyIndexWrapper = LazyIndexWrapper;
190
- //# sourceMappingURL=lazy-index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lazy-index.cjs","sources":["../../../src/indexes/lazy-index.ts"],"sourcesContent":["import type {\n BaseIndex,\n IndexConstructor,\n IndexResolver,\n} from './base-index.js'\nimport type { BasicExpression } from '../query/ir.js'\n\n/**\n * Utility to determine if a resolver is a constructor or async loader\n */\nfunction isConstructor<TKey extends string | number>(\n resolver: IndexResolver<TKey>,\n): resolver is IndexConstructor<TKey> {\n // Check if it's a function with a prototype (constructor)\n return (\n typeof resolver === `function` &&\n resolver.prototype !== undefined &&\n resolver.prototype.constructor === resolver\n )\n}\n\n/**\n * Resolve index constructor from resolver\n */\nasync function resolveIndexConstructor<TKey extends string | number>(\n resolver: IndexResolver<TKey>,\n): Promise<IndexConstructor<TKey>> {\n if (isConstructor(resolver)) {\n return resolver\n } else {\n // It's an async loader function\n return await resolver()\n }\n}\n\n/**\n * Wrapper that defers index creation until first sync\n */\nexport class LazyIndexWrapper<TKey extends string | number = string | number> {\n private indexPromise: Promise<BaseIndex<TKey>> | null = null\n private resolvedIndex: BaseIndex<TKey> | null = null\n\n constructor(\n private id: number,\n private expression: BasicExpression,\n private name: string | undefined,\n private resolver: IndexResolver<TKey>,\n private options: any,\n private collectionEntries?: Iterable<[TKey, any]>,\n ) {\n // For synchronous constructors, resolve immediately\n if (isConstructor(this.resolver)) {\n this.resolvedIndex = new this.resolver(\n this.id,\n this.expression,\n this.name,\n this.options,\n )\n // Build with initial data if provided\n if (this.collectionEntries) {\n this.resolvedIndex.build(this.collectionEntries)\n }\n }\n }\n\n /**\n * Resolve the actual index\n */\n async resolve(): Promise<BaseIndex<TKey>> {\n if (this.resolvedIndex) {\n return this.resolvedIndex\n }\n\n if (!this.indexPromise) {\n this.indexPromise = this.createIndex()\n }\n\n this.resolvedIndex = await this.indexPromise\n return this.resolvedIndex\n }\n\n /**\n * Check if already resolved\n */\n isResolved(): boolean {\n return this.resolvedIndex !== null\n }\n\n /**\n * Get resolved index (throws if not ready)\n */\n getResolved(): BaseIndex<TKey> {\n if (!this.resolvedIndex) {\n throw new Error(\n `Index ${this.id} has not been resolved yet. Ensure collection is synced.`,\n )\n }\n return this.resolvedIndex\n }\n\n /**\n * Get the index ID\n */\n getId(): number {\n return this.id\n }\n\n /**\n * Get the index name\n */\n getName(): string | undefined {\n return this.name\n }\n\n /**\n * Get the index expression\n */\n getExpression(): BasicExpression {\n return this.expression\n }\n\n private async createIndex(): Promise<BaseIndex<TKey>> {\n const IndexClass = await resolveIndexConstructor(this.resolver)\n return new IndexClass(this.id, this.expression, this.name, this.options)\n }\n}\n\n/**\n * Proxy that provides synchronous interface while index loads asynchronously\n */\nexport class IndexProxy<TKey extends string | number = string | number> {\n constructor(\n private indexId: number,\n private lazyIndex: LazyIndexWrapper<TKey>,\n ) {}\n\n /**\n * Get the resolved index (throws if not ready)\n */\n get index(): BaseIndex<TKey> {\n return this.lazyIndex.getResolved()\n }\n\n /**\n * Check if index is ready\n */\n get isReady(): boolean {\n return this.lazyIndex.isResolved()\n }\n\n /**\n * Wait for index to be ready\n */\n async whenReady(): Promise<BaseIndex<TKey>> {\n return await this.lazyIndex.resolve()\n }\n\n /**\n * Get the index ID\n */\n get id(): number {\n return this.indexId\n }\n\n /**\n * Get the index name (throws if not ready)\n */\n get name(): string | undefined {\n if (this.isReady) {\n return this.index.name\n }\n return this.lazyIndex.getName()\n }\n\n /**\n * Get the index expression (available immediately)\n */\n get expression(): BasicExpression {\n return this.lazyIndex.getExpression()\n }\n\n /**\n * Check if index supports an operation (throws if not ready)\n */\n supports(operation: any): boolean {\n return this.index.supports(operation)\n }\n\n /**\n * Get index statistics (throws if not ready)\n */\n getStats() {\n return this.index.getStats()\n }\n\n /**\n * Check if index matches a field path (available immediately)\n */\n matchesField(fieldPath: Array<string>): boolean {\n const expr = this.expression\n return (\n expr.type === `ref` &&\n expr.path.length === fieldPath.length &&\n expr.path.every((part, i) => part === fieldPath[i])\n )\n }\n\n /**\n * Get the key count (throws if not ready)\n */\n get keyCount(): number {\n return this.index.keyCount\n }\n\n // Test compatibility properties - delegate to resolved index\n get indexedKeysSet(): Set<TKey> {\n const resolved = this.index as any\n return resolved.indexedKeysSet\n }\n\n get orderedEntriesArray(): Array<[any, Set<TKey>]> {\n const resolved = this.index as any\n return resolved.orderedEntriesArray\n }\n\n get valueMapData(): Map<any, Set<TKey>> {\n const resolved = this.index as any\n return resolved.valueMapData\n }\n\n // BTreeIndex compatibility methods\n equalityLookup(value: any): Set<TKey> {\n const resolved = this.index as any\n return resolved.equalityLookup?.(value) ?? new Set()\n }\n\n rangeQuery(options: any): Set<TKey> {\n const resolved = this.index as any\n return resolved.rangeQuery?.(options) ?? new Set()\n }\n\n inArrayLookup(values: Array<any>): Set<TKey> {\n const resolved = this.index as any\n return resolved.inArrayLookup?.(values) ?? new Set()\n }\n\n // Internal method for the collection to get the lazy wrapper\n _getLazyWrapper(): LazyIndexWrapper<TKey> {\n return this.lazyIndex\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,96 +0,0 @@
1
- import { BaseIndex, IndexResolver } from './base-index.js';
2
- import { BasicExpression } from '../query/ir.js';
3
- /**
4
- * Wrapper that defers index creation until first sync
5
- */
6
- export declare class LazyIndexWrapper<TKey extends string | number = string | number> {
7
- private id;
8
- private expression;
9
- private name;
10
- private resolver;
11
- private options;
12
- private collectionEntries?;
13
- private indexPromise;
14
- private resolvedIndex;
15
- constructor(id: number, expression: BasicExpression, name: string | undefined, resolver: IndexResolver<TKey>, options: any, collectionEntries?: Iterable<[TKey, any]> | undefined);
16
- /**
17
- * Resolve the actual index
18
- */
19
- resolve(): Promise<BaseIndex<TKey>>;
20
- /**
21
- * Check if already resolved
22
- */
23
- isResolved(): boolean;
24
- /**
25
- * Get resolved index (throws if not ready)
26
- */
27
- getResolved(): BaseIndex<TKey>;
28
- /**
29
- * Get the index ID
30
- */
31
- getId(): number;
32
- /**
33
- * Get the index name
34
- */
35
- getName(): string | undefined;
36
- /**
37
- * Get the index expression
38
- */
39
- getExpression(): BasicExpression;
40
- private createIndex;
41
- }
42
- /**
43
- * Proxy that provides synchronous interface while index loads asynchronously
44
- */
45
- export declare class IndexProxy<TKey extends string | number = string | number> {
46
- private indexId;
47
- private lazyIndex;
48
- constructor(indexId: number, lazyIndex: LazyIndexWrapper<TKey>);
49
- /**
50
- * Get the resolved index (throws if not ready)
51
- */
52
- get index(): BaseIndex<TKey>;
53
- /**
54
- * Check if index is ready
55
- */
56
- get isReady(): boolean;
57
- /**
58
- * Wait for index to be ready
59
- */
60
- whenReady(): Promise<BaseIndex<TKey>>;
61
- /**
62
- * Get the index ID
63
- */
64
- get id(): number;
65
- /**
66
- * Get the index name (throws if not ready)
67
- */
68
- get name(): string | undefined;
69
- /**
70
- * Get the index expression (available immediately)
71
- */
72
- get expression(): BasicExpression;
73
- /**
74
- * Check if index supports an operation (throws if not ready)
75
- */
76
- supports(operation: any): boolean;
77
- /**
78
- * Get index statistics (throws if not ready)
79
- */
80
- getStats(): import('./base-index.js').IndexStats;
81
- /**
82
- * Check if index matches a field path (available immediately)
83
- */
84
- matchesField(fieldPath: Array<string>): boolean;
85
- /**
86
- * Get the key count (throws if not ready)
87
- */
88
- get keyCount(): number;
89
- get indexedKeysSet(): Set<TKey>;
90
- get orderedEntriesArray(): Array<[any, Set<TKey>]>;
91
- get valueMapData(): Map<any, Set<TKey>>;
92
- equalityLookup(value: any): Set<TKey>;
93
- rangeQuery(options: any): Set<TKey>;
94
- inArrayLookup(values: Array<any>): Set<TKey>;
95
- _getLazyWrapper(): LazyIndexWrapper<TKey>;
96
- }
@@ -1,96 +0,0 @@
1
- import { BaseIndex, IndexResolver } from './base-index.js';
2
- import { BasicExpression } from '../query/ir.js';
3
- /**
4
- * Wrapper that defers index creation until first sync
5
- */
6
- export declare class LazyIndexWrapper<TKey extends string | number = string | number> {
7
- private id;
8
- private expression;
9
- private name;
10
- private resolver;
11
- private options;
12
- private collectionEntries?;
13
- private indexPromise;
14
- private resolvedIndex;
15
- constructor(id: number, expression: BasicExpression, name: string | undefined, resolver: IndexResolver<TKey>, options: any, collectionEntries?: Iterable<[TKey, any]> | undefined);
16
- /**
17
- * Resolve the actual index
18
- */
19
- resolve(): Promise<BaseIndex<TKey>>;
20
- /**
21
- * Check if already resolved
22
- */
23
- isResolved(): boolean;
24
- /**
25
- * Get resolved index (throws if not ready)
26
- */
27
- getResolved(): BaseIndex<TKey>;
28
- /**
29
- * Get the index ID
30
- */
31
- getId(): number;
32
- /**
33
- * Get the index name
34
- */
35
- getName(): string | undefined;
36
- /**
37
- * Get the index expression
38
- */
39
- getExpression(): BasicExpression;
40
- private createIndex;
41
- }
42
- /**
43
- * Proxy that provides synchronous interface while index loads asynchronously
44
- */
45
- export declare class IndexProxy<TKey extends string | number = string | number> {
46
- private indexId;
47
- private lazyIndex;
48
- constructor(indexId: number, lazyIndex: LazyIndexWrapper<TKey>);
49
- /**
50
- * Get the resolved index (throws if not ready)
51
- */
52
- get index(): BaseIndex<TKey>;
53
- /**
54
- * Check if index is ready
55
- */
56
- get isReady(): boolean;
57
- /**
58
- * Wait for index to be ready
59
- */
60
- whenReady(): Promise<BaseIndex<TKey>>;
61
- /**
62
- * Get the index ID
63
- */
64
- get id(): number;
65
- /**
66
- * Get the index name (throws if not ready)
67
- */
68
- get name(): string | undefined;
69
- /**
70
- * Get the index expression (available immediately)
71
- */
72
- get expression(): BasicExpression;
73
- /**
74
- * Check if index supports an operation (throws if not ready)
75
- */
76
- supports(operation: any): boolean;
77
- /**
78
- * Get index statistics (throws if not ready)
79
- */
80
- getStats(): import('./base-index.js').IndexStats;
81
- /**
82
- * Check if index matches a field path (available immediately)
83
- */
84
- matchesField(fieldPath: Array<string>): boolean;
85
- /**
86
- * Get the key count (throws if not ready)
87
- */
88
- get keyCount(): number;
89
- get indexedKeysSet(): Set<TKey>;
90
- get orderedEntriesArray(): Array<[any, Set<TKey>]>;
91
- get valueMapData(): Map<any, Set<TKey>>;
92
- equalityLookup(value: any): Set<TKey>;
93
- rangeQuery(options: any): Set<TKey>;
94
- inArrayLookup(values: Array<any>): Set<TKey>;
95
- _getLazyWrapper(): LazyIndexWrapper<TKey>;
96
- }