Skip to content
Merged
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-flags-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/store': patch
---

Inline reactive flag constants in generated builds to improve tree-shaking.
2 changes: 1 addition & 1 deletion docs/reference/functions/batch.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: batch
function batch(fn): void;
```

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

## 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 @@ -9,7 +9,7 @@ title: createAsyncAtom
function createAsyncAtom<T>(getValue, options?): ReadonlyAtom<AsyncAtomState<T, unknown>>;
```

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

## 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 @@ -11,7 +11,7 @@ title: createAtom
function createAtom<T>(getValue, options?): ReadonlyAtom<T>;
```

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

### Type Parameters

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

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

### 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 @@ -9,7 +9,7 @@ title: flush
function flush(): void;
```

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

## Returns

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/functions/toObserver.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function toObserver<T>(
completionHandler?): Observer<T>;
```

Defined in: [atom.ts:12](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L12)
Defined in: [atom.ts:20](https://github.com/TanStack/store/blob/main/packages/store/src/atom.ts#L20)

## Type Parameters

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/interfaces/InternalReadonlyAtom.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ ReactiveNode.depsTail
### flags

```ts
flags: ReactiveFlags;
flags: number;
```

Defined in: [alien.ts:10](https://github.com/TanStack/store/blob/main/packages/store/src/alien.ts#L10)
Expand Down
6 changes: 4 additions & 2 deletions knip.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{
"$schema": "https://unpkg.com/knip@5/schema.json",
"workspaces": {
"packages/store": {
"entry": ["src/signal.ts"]
},
"packages/vue-store": {
"ignoreDependencies": ["vue2", "vue2.7"]
}
},
"ignoreWorkspaces": ["examples/**"],
"ignore": ["packages/store/src/signal.ts"]
"ignoreWorkspaces": ["examples/**"]
}
81 changes: 28 additions & 53 deletions packages/store/src/alien.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ interface Stack<T> {
prev: Stack<T> | undefined
}

export const enum ReactiveFlags {
None = 0,
Mutable = 1,
Watching = 2,
RecursedCheck = 4,
Recursed = 8,
Dirty = 16,
Pending = 32,
}
export type ReactiveFlags = number

export const NONE = 0
export const MUTABLE = 1
export const WATCHING = 2
export const RECURSED_CHECK = 4
export const RECURSED = 8
export const DIRTY = 16
export const PENDING = 32
/*@__NO_SIDE_EFFECTS__*/
export function createReactiveSystem({
update,
Expand Down Expand Up @@ -135,37 +135,24 @@ export function createReactiveSystem({
const sub = link.sub
let flags = sub.flags

if (
!(
flags &
(ReactiveFlags.RecursedCheck |
ReactiveFlags.Recursed |
ReactiveFlags.Dirty |
ReactiveFlags.Pending)
)
) {
sub.flags = flags | ReactiveFlags.Pending
} else if (
!(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))
) {
flags = ReactiveFlags.None
} else if (!(flags & ReactiveFlags.RecursedCheck)) {
sub.flags = (flags & ~ReactiveFlags.Recursed) | ReactiveFlags.Pending
} else if (
!(flags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)) &&
isValidLink(link, sub)
) {
sub.flags = flags | (ReactiveFlags.Recursed | ReactiveFlags.Pending)
flags &= ReactiveFlags.Mutable
if (!(flags & (RECURSED_CHECK | RECURSED | DIRTY | PENDING))) {
sub.flags = flags | PENDING
} else if (!(flags & (RECURSED_CHECK | RECURSED))) {
flags = NONE
} else if (!(flags & RECURSED_CHECK)) {
sub.flags = (flags & ~RECURSED) | PENDING
} else if (!(flags & (DIRTY | PENDING)) && isValidLink(link, sub)) {
sub.flags = flags | (RECURSED | PENDING)
flags &= MUTABLE
} else {
flags = ReactiveFlags.None
flags = NONE
}

if (flags & ReactiveFlags.Watching) {
if (flags & WATCHING) {
notify(sub)
}

if (flags & ReactiveFlags.Mutable) {
if (flags & MUTABLE) {
const subSubs = sub.subs
if (subSubs !== undefined) {
const nextSub = (link = subSubs).nextSub
Expand Down Expand Up @@ -204,23 +191,17 @@ export function createReactiveSystem({
const dep = link.dep
const flags = dep.flags

if (sub.flags & ReactiveFlags.Dirty) {
if (sub.flags & DIRTY) {
dirty = true
} else if (
(flags & (ReactiveFlags.Mutable | ReactiveFlags.Dirty)) ===
(ReactiveFlags.Mutable | ReactiveFlags.Dirty)
) {
} else if ((flags & (MUTABLE | DIRTY)) === (MUTABLE | DIRTY)) {
if (update(dep)) {
const subs = dep.subs!
if (subs.nextSub !== undefined) {
shallowPropagate(subs)
}
dirty = true
}
} else if (
(flags & (ReactiveFlags.Mutable | ReactiveFlags.Pending)) ===
(ReactiveFlags.Mutable | ReactiveFlags.Pending)
) {
} else if ((flags & (MUTABLE | PENDING)) === (MUTABLE | PENDING)) {
if (link.nextSub !== undefined || link.prevSub !== undefined) {
stack = { value: link, prev: stack }
}
Expand Down Expand Up @@ -257,7 +238,7 @@ export function createReactiveSystem({
}
dirty = false
} else {
sub.flags &= ~ReactiveFlags.Pending
sub.flags &= ~PENDING
}
sub = link.sub
const nextDep = link.nextDep
Expand All @@ -275,15 +256,9 @@ export function createReactiveSystem({
do {
const sub = link.sub
const flags = sub.flags
if (
(flags & (ReactiveFlags.Pending | ReactiveFlags.Dirty)) ===
ReactiveFlags.Pending
) {
sub.flags = flags | ReactiveFlags.Dirty
if (
(flags & (ReactiveFlags.Watching | ReactiveFlags.RecursedCheck)) ===
ReactiveFlags.Watching
) {
if ((flags & (PENDING | DIRTY)) === PENDING) {
sub.flags = flags | DIRTY
if ((flags & (WATCHING | RECURSED_CHECK)) === WATCHING) {
notify(sub)
}
}
Expand Down
46 changes: 24 additions & 22 deletions packages/store/src/atom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { ReactiveFlags, createReactiveSystem } from './alien'
import {
DIRTY,
MUTABLE,
NONE,
PENDING,
RECURSED_CHECK,
WATCHING,
createReactiveSystem,
} from './alien'

import type { ReactiveNode } from './alien'
import type {
Expand Down Expand Up @@ -43,12 +51,12 @@ const { link, unlink, propagate, checkDirty, shallowPropagate } =
// eslint-disable-next-line no-shadow
notify(effect: Effect): void {
queuedEffects[queuedEffectsLength++] = effect
effect.flags &= ~ReactiveFlags.Watching
effect.flags &= ~WATCHING
},
unwatched(atom: InternalAtom<any>): void {
if (atom.depsTail !== undefined) {
atom.depsTail = undefined
atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty
atom.flags = MUTABLE | DIRTY
purgeDeps(atom)
}
},
Expand Down Expand Up @@ -158,7 +166,7 @@ export function createAtom<T>(
subsTail: undefined,
deps: undefined,
depsTail: undefined,
flags: isComputed ? ReactiveFlags.None : ReactiveFlags.Mutable,
flags: isComputed ? NONE : MUTABLE,

get(): T {
if (activeSub !== undefined) {
Expand Down Expand Up @@ -198,7 +206,7 @@ export function createAtom<T>(
return false
}
if (isComputed) {
atom.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck
atom.flags = MUTABLE | RECURSED_CHECK
}
try {
const oldValue = atom._snapshot
Expand All @@ -216,29 +224,26 @@ export function createAtom<T>(
} finally {
activeSub = prevSub
if (isComputed) {
atom.flags &= ~ReactiveFlags.RecursedCheck
atom.flags &= ~RECURSED_CHECK
}
purgeDeps(atom)
}
},
}

if (isComputed) {
atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty
atom.flags = MUTABLE | DIRTY
atom.get = function (): T {
const flags = atom.flags
if (
flags & ReactiveFlags.Dirty ||
(flags & ReactiveFlags.Pending && checkDirty(atom.deps!, atom))
) {
if (flags & DIRTY || (flags & PENDING && checkDirty(atom.deps!, atom))) {
if (atom._update()) {
const subs = atom.subs
if (subs !== undefined) {
shallowPropagate(subs)
}
}
} else if (flags & ReactiveFlags.Pending) {
atom.flags = flags & ~ReactiveFlags.Pending
} else if (flags & PENDING) {
atom.flags = flags & ~PENDING
}
if (activeSub !== undefined) {
link(atom, activeSub, cycle)
Expand Down Expand Up @@ -275,12 +280,12 @@ function effect<T>(fn: () => T): Effect {
activeSub = effectObj
++cycle
effectObj.depsTail = undefined
effectObj.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck
effectObj.flags = WATCHING | RECURSED_CHECK
try {
return fn()
} finally {
activeSub = prevSub
effectObj.flags &= ~ReactiveFlags.RecursedCheck
effectObj.flags &= ~RECURSED_CHECK
purgeDeps(effectObj)
}
}
Expand All @@ -289,22 +294,19 @@ function effect<T>(fn: () => T): Effect {
depsTail: undefined,
subs: undefined,
subsTail: undefined,
flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,
flags: WATCHING | RECURSED_CHECK,

notify(): void {
const flags = this.flags
if (
flags & ReactiveFlags.Dirty ||
(flags & ReactiveFlags.Pending && checkDirty(this.deps!, this))
) {
if (flags & DIRTY || (flags & PENDING && checkDirty(this.deps!, this))) {
run()
} else {
this.flags = ReactiveFlags.Watching
this.flags = WATCHING
}
},

stop(): void {
this.flags = ReactiveFlags.None
this.flags = NONE
this.depsTail = undefined
purgeDeps(this)
},
Expand Down
Loading
Loading