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/old-actors-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/store': patch
---

derived createStore now returns readonly store
124 changes: 124 additions & 0 deletions docs/reference/classes/ReadonlyStore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
id: ReadonlyStore
title: ReadonlyStore
---

# Class: ReadonlyStore\<T\>

Defined in: [store.ts:31](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L31)

## Type Parameters

### T

`T`

## Implements

- `Omit`\<[`Store`](Store.md)\<`T`\>, `"setState"`\>

## Constructors

### Constructor

```ts
new ReadonlyStore<T>(getValue): ReadonlyStore<T>;
```

Defined in: [store.ts:33](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L33)

#### Parameters

##### getValue

(`prev?`) => `T`

#### Returns

`ReadonlyStore`\<`T`\>

### Constructor

```ts
new ReadonlyStore<T>(initialValue): ReadonlyStore<T>;
```

Defined in: [store.ts:34](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L34)

#### Parameters

##### initialValue

`T`

#### Returns

`ReadonlyStore`\<`T`\>

## Accessors

### state

#### Get Signature

```ts
get state(): T;
```

Defined in: [store.ts:42](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L42)

##### Returns

`T`

#### Implementation of

```ts
Omit.state
```

## Methods

### get()

```ts
get(): T;
```

Defined in: [store.ts:45](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L45)

#### Returns

`T`

#### Implementation of

```ts
Omit.get
```

***

### subscribe()

```ts
subscribe(observerOrFn): Subscription;
```

Defined in: [store.ts:48](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L48)

#### Parameters

##### observerOrFn

[`Observer`](../type-aliases/Observer.md)\<`T`\> | (`value`) => `void`

#### Returns

[`Subscription`](../interfaces/Subscription.md)

#### Implementation of

```ts
Omit.subscribe
```
8 changes: 4 additions & 4 deletions docs/reference/functions/createStore.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ title: createStore
## Call Signature

```ts
function createStore<T>(getValue): Store<T>;
function createStore<T>(getValue): ReadonlyStore<T>;
```

Defined in: [store.ts:31](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L31)
Defined in: [store.ts:55](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L55)

### Type Parameters

Expand All @@ -27,15 +27,15 @@ Defined in: [store.ts:31](https://github.com/TanStack/store/blob/main/packages/s

### Returns

[`Store`](../classes/Store.md)\<`T`\>
[`ReadonlyStore`](../classes/ReadonlyStore.md)\<`T`\>

## Call Signature

```ts
function createStore<T>(initialValue): Store<T>;
```

Defined in: [store.ts:32](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L32)
Defined in: [store.ts:58](https://github.com/TanStack/store/blob/main/packages/store/src/store.ts#L58)

### Type Parameters

Expand Down
1 change: 1 addition & 0 deletions docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ title: "@tanstack/store"

## Classes

- [ReadonlyStore](classes/ReadonlyStore.md)
- [Store](classes/Store.md)

## Interfaces
Expand Down
34 changes: 31 additions & 3 deletions packages/store/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,39 @@ export class Store<T> {
}
}

export function createStore<T>(getValue: (prev?: NoInfer<T>) => T): Store<T>
export class ReadonlyStore<T> implements Omit<Store<T>, 'setState'> {
private atom: Atom<T>
constructor(getValue: (prev?: NoInfer<T>) => T)
constructor(initialValue: T)
constructor(valueOrFn: T | ((prev?: T) => T)) {
// createAtom has overloads that return ReadonlyAtom<T> for functions and Atom<T> for values
// Store always needs Atom<T> for setState, so we assert the return type
this.atom = createAtom(
valueOrFn as T | ((prev?: NoInfer<T>) => T),
) as Atom<T>
}
public get state() {
return this.atom.get()
}
public get() {
return this.state
}
public subscribe(
observerOrFn: Observer<T> | ((value: T) => void),
): Subscription {
return this.atom.subscribe(toObserver(observerOrFn))
}
}

export function createStore<T>(
getValue: (prev?: NoInfer<T>) => T,
): ReadonlyStore<T>
export function createStore<T>(initialValue: T): Store<T>
export function createStore<T>(valueOrFn: T | ((prev?: T) => T)): Store<T> {
export function createStore<T>(
valueOrFn: T | ((prev?: T) => T),
): Store<T> | ReadonlyStore<T> {
if (typeof valueOrFn === 'function') {
return new Store(valueOrFn as (prev?: NoInfer<T>) => T)
return new ReadonlyStore(valueOrFn as (prev?: NoInfer<T>) => T)
}
return new Store(valueOrFn)
}
4 changes: 2 additions & 2 deletions packages/store/tests/derived.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { afterEach, describe, expect, test, vi } from 'vitest'
import { batch, createStore } from '../src'

import type { Store } from '../src'
import type { ReadonlyStore, Store } from '../src'

function viFnSubscribe(subscribable: Store<any>) {
function viFnSubscribe(subscribable: Store<any> | ReadonlyStore<any>) {
const fn = vi.fn()
const cleanup = subscribable.subscribe((s) => fn(s)).unsubscribe
afterEach(() => {
Expand Down
Loading