Describe the bug
In solid-db's useLiveQuery, toArray includes are not reactive. For query includes, if the initial include is empty it starts as a non-observable null value. In this case the child query is also not reactive.
To Reproduce
Steps to reproduce the behavior:
- Create two empty collections
- Create a query which has an include between them
- Create a solidjs subscription on the query
- Fill the empty collections (not in a single solidjs batch so solid sees an intermediate value)
For a query with an toArray include the initial collection does not have to be empty, the include is never reactive.
Expected behavior
That solidjs updates when the include changes
Additional context
flushIncludesState clones the rows for the events.
But solidjs reads currentCollection.values() on any update, and these rows are updated in place. Since the pointers are stable, reconcile prunes them and nothing downstream sees the update.
This is relevant when the update is a value (e.g. toArray), or if the initial include collection was empty. In that case the include field starts as null and solidjs doesn't see the change to a non-null reference.
|
reconcile(Array.from(currentCollection.values()))(prev).filter(Boolean), |
If an include is initially empty, the proxy is not attached to the parent. It remains null. This is why the initial child field can be null, breaking reactivity for collection includes as well.
|
function attachChildCollectionToParent( |
|
parentCollection: Collection<any, any, any>, |
|
resultPath: Array<string>, |
|
correlationKey: unknown, |
|
correlationToParentKeys: Map<unknown, Set<unknown>>, |
|
childCollection: Collection<any, any, any>, |
|
): void { |
|
const parentKeys = correlationToParentKeys.get(correlationKey) |
|
if (!parentKeys) return |
|
|
|
for (const parentKey of parentKeys) { |
|
const item = parentCollection.get(parentKey as any) |
|
if (item) { |
|
setIncludedValue(item, resultPath, childCollection) |
|
} |
|
} |
|
} |
Describe the bug
In solid-db's useLiveQuery, toArray includes are not reactive. For query includes, if the initial include is empty it starts as a non-observable null value. In this case the child query is also not reactive.
To Reproduce
Steps to reproduce the behavior:
For a query with an toArray include the initial collection does not have to be empty, the include is never reactive.
Expected behavior
That solidjs updates when the include changes
Additional context
flushIncludesState clones the rows for the events.
But solidjs reads currentCollection.values() on any update, and these rows are updated in place. Since the pointers are stable, reconcile prunes them and nothing downstream sees the update.
This is relevant when the update is a value (e.g. toArray), or if the initial include collection was empty. In that case the include field starts as null and solidjs doesn't see the change to a non-null reference.
db/packages/solid-db/src/useLiveQuery.ts
Line 349 in be656be
If an include is initially empty, the proxy is not attached to the parent. It remains null. This is why the initial child field can be null, breaking reactivity for collection includes as well.
db/packages/db/src/query/live/collection-config-builder.ts
Lines 1851 to 1867 in be656be