fix(store): release unobserved computed atoms with retained dependency links by Sheraff · Pull Request #373 · TanStack/store · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tidy-unobserved-atoms.md
2 changes: 1 addition & 1 deletion docs/reference/functions/batch.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: batch
function batch(fn): void;
```

Defined in: [atom.ts:70](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L70)
Defined in: [atom.ts:67](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L67)

## Parameters

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/functions/createAsyncAtom.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: createAsyncAtom
function createAsyncAtom<T>(getValue, options?): ReadonlyAtom<AsyncAtomState<T, unknown>>;
```

Defined in: [atom.ts:108](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L108)
Defined in: [atom.ts:121](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L121)

## Type Parameters

Expand Down
4 changes: 2 additions & 2 deletions docs/reference/functions/createAtom.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: createAtom
function createAtom<T>(getValue, options?): ReadonlyAtom<T>;
```

Defined in: [atom.ts:146](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L146)
Defined in: [atom.ts:159](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L159)

### Type Parameters

Expand Down Expand Up @@ -37,7 +37,7 @@ Defined in: [atom.ts:146](https://github.com/TanStack/store/blob/main/packages/s
function createAtom<T>(initialValue, options?): Atom<T>;
```

Defined in: [atom.ts:150](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L150)
Defined in: [atom.ts:163](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L163)

### Type Parameters

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/functions/flush.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: flush
function flush(): void;
```

Defined in: [atom.ts:89](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L89)
Defined in: [atom.ts:102](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L102)

## Returns

Expand Down
96 changes: 56 additions & 40 deletions packages/store/src/alien.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,62 +57,76 @@ export function createReactiveSystem({
if (prevDep !== undefined && prevDep.dep === dep) {
return
}
const nextDep = prevDep !== undefined ? prevDep.nextDep : sub.deps
let nextDep = prevDep !== undefined ? prevDep.nextDep : sub.deps
const prevSub = dep.subsTail
if (nextDep !== undefined && nextDep.dep === dep) {
nextDep.version = version
sub.depsTail = nextDep
return
}
const prevSub = dep.subsTail
if (
prevSub !== undefined &&
prevSub.version === version &&
prevSub.sub === sub
) {
return
}
const newLink =
(sub.depsTail =
dep.subsTail =
{
version,
dep,
sub,
prevDep,
nextDep,
prevSub,
nextSub: undefined,
})
if (nextDep !== undefined) {
nextDep.prevDep = newLink
}
if (prevDep !== undefined) {
prevDep.nextDep = newLink
// A self pointer marks a retained link absent from the subscriber list.
if (nextDep.prevSub !== nextDep) {
return
}
} else {
sub.deps = newLink
if (
prevSub !== undefined &&
prevSub.version === version &&
prevSub.sub === sub
) {
return
}
const newLink = (sub.depsTail = {
version,
dep,
sub,
prevDep,
nextDep,
prevSub,
nextSub: undefined,
})
if (nextDep !== undefined) {
nextDep.prevDep = newLink
}
if (prevDep !== undefined) {
prevDep.nextDep = newLink
} else {
sub.deps = newLink
}
nextDep = newLink
}
dep.subsTail = nextDep
nextDep.prevSub = prevSub
if (prevSub !== undefined) {
prevSub.nextSub = newLink
prevSub.nextSub = nextDep
} else {
dep.subs = newLink
dep.subs = nextDep
}
}

function unlink(link: Link, sub = link.sub): Link | undefined {
function unlink(
link: Link,
sub = link.sub,
keepDeps = false,
): Link | undefined {
const dep = link.dep
const prevDep = link.prevDep
const nextDep = link.nextDep
const nextSub = link.nextSub
const prevSub = link.prevSub
if (nextDep !== undefined) {
nextDep.prevDep = prevDep
} else {
sub.depsTail = prevDep
// Unobserved atoms retain their forward links for validation and reuse.
if (!keepDeps) {
if (nextDep !== undefined) {
nextDep.prevDep = prevDep
} else {
sub.depsTail = prevDep
}
if (prevDep !== undefined) {
prevDep.nextDep = nextDep
} else {
sub.deps = nextDep
}
}
if (prevDep !== undefined) {
prevDep.nextDep = nextDep
} else {
sub.deps = nextDep
if (prevSub === link) {
return nextDep
}
if (nextSub !== undefined) {
nextSub.prevSub = prevSub
Expand All @@ -124,6 +138,8 @@ export function createReactiveSystem({
} else if ((dep.subs = nextSub) === undefined) {
unwatched(dep)
}
link.prevSub = link
link.nextSub = undefined
return nextDep
}

Expand Down
107 changes: 87 additions & 20 deletions packages/store/src/atom.ts
Loading
Loading