Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate store and derived implementation #147

Merged
merged 8 commits into from
Dec 26, 2024
Merged
84 changes: 47 additions & 37 deletions docs/reference/classes/derived.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,71 +29,85 @@ new Derived<TState, TArr>(options): Derived<TState, TArr>

#### Defined in

[derived.ts:95](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L95)
[derived.ts:87](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L87)

## Properties

### options
### lastSeenDepValues

```ts
options: DerivedOptions<TState, TArr>;
lastSeenDepValues: unknown[] = [];
```

#### Defined in

[derived.ts:72](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L72)
[derived.ts:71](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L71)

## Accessors

### prevState
***

#### Get Signature
### listeners

```ts
get prevState(): TState
listeners: Set<Listener<TState>>;
```

##### Returns
#### Defined in

`TState`
[derived.ts:60](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L60)

#### Set Signature
***

### options

```ts
set prevState(val): void
options: DerivedOptions<TState, TArr>;
```

##### Parameters
#### Defined in

• **val**: `TState`
[derived.ts:63](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L63)

##### Returns
***

`void`
### prevState

```ts
prevState: undefined | TState;
```

#### Defined in

[derived.ts:117](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L117)
[derived.ts:62](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L62)

***

### state

#### Get Signature
```ts
state: TState;
```

#### Defined in

[derived.ts:61](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L61)

## Methods

### checkIfRecalculationNeededDeeply()

```ts
get state(): TState
checkIfRecalculationNeededDeeply(): void
```

##### Returns
#### Returns

`TState`
`void`

#### Defined in

[derived.ts:109](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L109)
[derived.ts:157](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L157)

## Methods
***

### getDepVals()

Expand All @@ -108,13 +122,13 @@ getDepVals(): object
##### currDepVals

```ts
currDepVals: never;
currDepVals: unknown[];
```

##### prevDepVals

```ts
prevDepVals: never;
prevDepVals: unknown[];
```

##### prevVal
Expand All @@ -125,20 +139,16 @@ prevVal: undefined | NonNullable<TState>;

#### Defined in

[derived.ts:80](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L80)
[derived.ts:72](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L72)

***

### mount()

```ts
mount(__namedParameters): () => void
mount(): () => void
```

#### Parameters

• **\_\_namedParameters**: [`DerivedMountOptions`](../interfaces/derivedmountoptions.md) = `{}`

#### Returns

`Function`
Expand All @@ -149,7 +159,7 @@ mount(__namedParameters): () => void

#### Defined in

[derived.ts:181](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L181)
[derived.ts:178](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L178)

***

Expand All @@ -165,7 +175,7 @@ recompute(): void

#### Defined in

[derived.ts:170](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L170)
[derived.ts:145](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L145)

***

Expand All @@ -185,7 +195,7 @@ registerOnGraph(deps): void

#### Defined in

[derived.ts:121](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L121)
[derived.ts:96](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L96)

***

Expand All @@ -209,7 +219,7 @@ subscribe(listener): () => void

#### Defined in

[derived.ts:195](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L195)
[derived.ts:190](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L190)

***

Expand All @@ -229,4 +239,4 @@ unregisterFromGraph(deps): void

#### Defined in

[derived.ts:150](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L150)
[derived.ts:125](https://github.com/TanStack/store/blob/main/packages/store/src/derived.ts#L125)
2 changes: 1 addition & 1 deletion docs/reference/functions/batch.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ function batch(fn): void

## Defined in

[scheduler.ts:100](https://github.com/TanStack/store/blob/main/packages/store/src/scheduler.ts#L100)
[scheduler.ts:129](https://github.com/TanStack/store/blob/main/packages/store/src/scheduler.ts#L129)
1 change: 0 additions & 1 deletion docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ title: "@tanstack/store"
## Interfaces

- [DerivedFnProps](interfaces/derivedfnprops.md)
- [DerivedMountOptions](interfaces/derivedmountoptions.md)
- [DerivedOptions](interfaces/derivedoptions.md)
- [StoreOptions](interfaces/storeoptions.md)

Expand Down
26 changes: 0 additions & 26 deletions docs/reference/interfaces/derivedmountoptions.md

This file was deleted.

92 changes: 46 additions & 46 deletions packages/store/src/derived.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,15 @@ export interface DerivedOptions<
fn: (props: DerivedFnProps<TArr>) => TState
}

export interface DerivedMountOptions {
/**
* Should recompute the value on mount?
* @default {true}
*/
recompute?: boolean
}

export class Derived<
TState,
const TArr extends ReadonlyArray<
Derived<any> | Store<any>
> = ReadonlyArray<any>,
> {
/**
* @private
*/
_store: Store<TState>
listeners = new Set<Listener<TState>>()
state: TState
prevState: TState | undefined
options: DerivedOptions<TState, TArr>

/**
Expand All @@ -77,45 +68,29 @@ export class Derived<
*/
_subscriptions: Array<() => void> = []

lastSeenDepValues: Array<unknown> = []
getDepVals = () => {
const prevDepVals = [] as Array<unknown>
const currDepVals = [] as Array<unknown>
for (const dep of this.options.deps) {
prevDepVals.push(dep.prevState)
currDepVals.push(dep.state)
}
this.lastSeenDepValues = currDepVals
return {
prevDepVals: prevDepVals as never,
currDepVals: currDepVals as never,
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
prevVal: this._store?.prevState ?? undefined,
prevDepVals,
currDepVals,
prevVal: this.prevState ?? undefined,
}
}

constructor(options: DerivedOptions<TState, TArr>) {
this.options = options
const initVal = options.fn({
this.state = options.fn({
prevDepVals: undefined,
prevVal: undefined,
currDepVals: this.getDepVals().currDepVals,
currDepVals: this.getDepVals().currDepVals as never,
})

this._store = new Store(initVal, {
onSubscribe: options.onSubscribe?.bind(this) as never,
onUpdate: options.onUpdate,
})
}

get state() {
return this._store.state
}

set prevState(val: TState) {
this._store.prevState = val
}

get prevState() {
return this._store.prevState
}

registerOnGraph(
Expand Down Expand Up @@ -168,21 +143,41 @@ export class Derived<
}

recompute = () => {
this._store.setState(() => {
const { prevDepVals, currDepVals, prevVal } = this.getDepVals()
return this.options.fn({
prevDepVals,
currDepVals,
prevVal,
})
this.prevState = this.state
const { prevDepVals, currDepVals, prevVal } = this.getDepVals()
this.state = this.options.fn({
prevDepVals: prevDepVals as never,
currDepVals: currDepVals as never,
prevVal,
})

this.options.onUpdate?.()
}

mount = ({ recompute = true }: DerivedMountOptions = {}) => {
this.registerOnGraph()
if (recompute) {
checkIfRecalculationNeededDeeply = () => {
for (const dep of this.options.deps) {
if (dep instanceof Derived) {
dep.checkIfRecalculationNeededDeeply()
}
}
let shouldRecompute = false
const lastSeenDepValues = this.lastSeenDepValues
const { currDepVals } = this.getDepVals()
for (let i = 0; i < currDepVals.length; i++) {
if (currDepVals[i] !== lastSeenDepValues[i]) {
shouldRecompute = true
break
}
}

if (shouldRecompute) {
this.recompute()
}
}

mount = () => {
this.registerOnGraph()
this.checkIfRecalculationNeededDeeply()

return () => {
this.unregisterFromGraph()
Expand All @@ -193,6 +188,11 @@ export class Derived<
}

subscribe = (listener: Listener<TState>) => {
return this._store.subscribe(listener)
this.listeners.add(listener)
const unsub = this.options.onSubscribe?.(listener, this)
return () => {
this.listeners.delete(listener)
unsub?.()
}
}
}
2 changes: 1 addition & 1 deletion packages/store/src/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ export class Effect {
}

mount() {
return this._derived.mount({ recompute: false })
return this._derived.mount()
}
}
Loading