Skip to content

Include value updates break with solidjs #1571

@Tarmean

Description

@Tarmean
  • I've validated the bug against the latest version of DB packages (@tanstack/solid-db@0.2.1 with @tanstack/db@0.6.7)

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)
}
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions