Skip to content

Commit

Permalink
Fix broken types for Vue, React and Preact (#101)
Browse files Browse the repository at this point in the history
* chore: improve tests delays

* tests(vue): add types and errors tests

* fix(vue): sync-map types

* tests(react): add types and errors tests

* fix(react): sync-map types

* tests(preact): add types and errors tests

* fix(preact): sync-map types

* chore: cleanup
  • Loading branch information
euaaaio authored Sep 27, 2023
1 parent f6d8777 commit 499440e
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 11 deletions.
2 changes: 1 addition & 1 deletion encrypt-actions/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ it('encrypts and decrypts actions', async () => {
])

client1.log.add({ type: 'sync', value: 'secret' }, { sync: true })
await delay(50)
await delay(100)
expect(getPair(client1).leftSent[0][2].d.length).not.toEqual(
getPair(client1).leftSent[1][2].d.length
)
Expand Down
34 changes: 34 additions & 0 deletions preact/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { MapStore} from 'nanostores'
import { map } from 'nanostores'

import { syncMapTemplate } from '../sync-map-template/index.js'
import { useFilter, useSync } from './index.js'

type Post = {
id: string
title: string
}

let $post = syncMapTemplate<Post>('posts')

let post = useSync($post, '10')
let postList = useFilter($post, { id: '10' })

let $custom = (id: string): MapStore<Post> => map({ id, text: 'A' })
let custom = useSync($custom, '10')

if (post.isLoading) {
// THROWS Property 'title' does not exist
post.title = 'New title'
}

let postListItem = postList.stores.get('10')!.value!
if (postListItem.isLoading) {
// THROWS Property 'title' does not exist
postListItem.title = 'New title'
}

if (custom.isLoading) {
// THROWS Property 'title' does not exist
custom.title = 'B'
}
6 changes: 3 additions & 3 deletions preact/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ export class ChannelErrors extends Component<PreactErrorHandlers> {
* @returns Store value.
*/
export function useSync<Value extends SyncMapValues>(
Template: SyncMapTemplateLike<Value>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value>,
id: string
): SyncMapValue<Value>
export function useSync<Value extends object, Args extends any[]>(
Template: SyncMapTemplateLike<Value, [Client, ...Args]>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value, Args>,
id: string,
...args: Args
): Value
Expand Down Expand Up @@ -156,7 +156,7 @@ export function useSync<Value extends object, Args extends any[]>(
* @returns Filter store to use with map.
*/
export function useFilter<Value extends SyncMapValues>(
Template: SyncMapTemplate<Value>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value>,
filter?: Filter<Value>,
opts?: FilterOptions
): StoreValue<FilterStore<Value>>
Expand Down
21 changes: 21 additions & 0 deletions preact/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { MapStore} from 'nanostores'
import { map } from 'nanostores'

import { syncMapTemplate } from '../sync-map-template/index.js'
import { useFilter, useSync } from './index.js'

type Post = {
id: string
title: string
}

let $post = syncMapTemplate<Post>('posts')

let post = useSync($post, '10')
let postList = useFilter($post, { id: '10' })

let $custom = (id: string): MapStore<Post> => map({ id, text: 'A' })
let custom = useSync($custom, '10')
let customList = useFilter($custom, { id: '10' })

console.log({ custom, customList, post, postList })
34 changes: 34 additions & 0 deletions react/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { MapStore} from 'nanostores'
import { map } from 'nanostores'

import { syncMapTemplate } from '../sync-map-template/index.js'
import { useFilter, useSync } from './index.js'

type Post = {
id: string
title: string
}

let $post = syncMapTemplate<Post>('posts')

let post = useSync($post, '10')
let postList = useFilter($post, { id: '10' })

let $custom = (id: string): MapStore<Post> => map({ id, text: 'A' })
let custom = useSync($custom, '10')

if (post.isLoading) {
// THROWS Property 'title' does not exist
post.title = 'New title'
}

let postListItem = postList.stores.get('10')!.value!
if (postListItem.isLoading) {
// THROWS Property 'title' does not exist
postListItem.title = 'New title'
}

if (custom.isLoading) {
// THROWS Property 'title' does not exist
custom.title = 'B'
}
7 changes: 4 additions & 3 deletions react/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
ChannelNotFoundError
} from '../logux-undo-error/index.js'
import type {
SyncMapTemplate,
SyncMapTemplateLike,
SyncMapValue
} from '../sync-map-template/index.js'
Expand Down Expand Up @@ -119,11 +120,11 @@ export class ChannelErrors extends Component<
* @returns Store value.
*/
export function useSync<Value extends SyncMapValues>(
Template: SyncMapTemplateLike<Value>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value>,
id: string
): SyncMapValue<Value>
export function useSync<Value extends object, Args extends any[]>(
Template: SyncMapTemplateLike<Value, Args>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value, Args>,
id: string,
...args: Args
): Value
Expand Down Expand Up @@ -151,7 +152,7 @@ export function useSync<Value extends object, Args extends any[]>(
* @returns Filter store to use with map.
*/
export function useFilter<Value extends SyncMapValues>(
Template: SyncMapTemplateLike<Value>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value>,
filter?: Filter<Value>,
opts?: FilterOptions
): StoreValue<FilterStore<Value>>
Expand Down
21 changes: 21 additions & 0 deletions react/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { MapStore} from 'nanostores'
import { map } from 'nanostores'

import { syncMapTemplate } from '../sync-map-template/index.js'
import { useFilter, useSync } from './index.js'

type Post = {
id: string
title: string
}

let $post = syncMapTemplate<Post>('posts')

let post = useSync($post, '10')
let postList = useFilter($post, { id: '10' })

let $custom = (id: string): MapStore<Post> => map({ id, text: 'A' })
let custom = useSync($custom, '10')
let customList = useFilter($custom, { id: '10' })

console.log({ custom, customList, post, postList })
43 changes: 43 additions & 0 deletions vue/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { MapStore} from 'nanostores'
import { map } from 'nanostores'

import { syncMapTemplate } from '../sync-map-template/index.js'
import { useFilter, useSync } from './index.js'

type Post = {
id: string
title: string
}

let $post = syncMapTemplate<Post>('posts')

let post = useSync($post, '10')
let postList = useFilter($post, { id: '10' })

let $custom = (id: string): MapStore<Post> => map({ id, text: 'A' })
let custom = useSync($custom, '10')

if (post.value.isLoading) {
// THROWS Property 'title' does not exist
post.value.title = 'New title'
} else {
// THROWS Cannot assign to 'title' because it is a read-only
post.value.title = 'New title'
}

let postListItem = postList.value.stores.get('10')!.value!
if (postListItem.isLoading) {
// THROWS Property 'title' does not exist
postListItem.title = 'New title'
} else {
// THROWS Cannot assign to 'title' because it is a read-only
postListItem.title = 'New title'
}

if (custom.value.isLoading) {
// THROWS Property 'title' does not exist
custom.value.title = 'B'
} else {
// THROWS Cannot assign to 'title' because it is a read-only
custom.value.title = 'B'
}
12 changes: 8 additions & 4 deletions vue/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import type {
} from 'vue'

import type { Client } from '../client/index.js'
import type { Filter, FilterOptions, FilterStore } from '../create-filter/index.js'
import type {
Filter,
FilterOptions,
FilterStore
} from '../create-filter/index.js'
import type { ChannelError } from '../logux-undo-error/index.js'
import type {
SyncMapTemplate,
Expand Down Expand Up @@ -89,11 +93,11 @@ export function useClient(): Client
* @returns Store value.
*/
export function useSync<Value extends SyncMapValues>(
Template: SyncMapTemplateLike<Value>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value>,
id: Refable<string>
): ReadonlyRef<SyncMapValue<Value>>
export function useSync<Value extends object, Args extends any[]>(
Template: SyncMapTemplateLike<Value, Args>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value, Args>,
id: Refable<string>,
...args: Args
): ReadonlyRef<Value>
Expand Down Expand Up @@ -128,7 +132,7 @@ export function useSync<Value extends object, Args extends any[]>(
* @returns Filter store to use with map.
*/
export function useFilter<Value extends SyncMapValues>(
Template: SyncMapTemplate<Value>,
Template: SyncMapTemplate<Value> | SyncMapTemplateLike<Value>,
filter?: Refable<Filter<Value>>,
opts?: Refable<FilterOptions>
): ReadonlyRef<StoreValue<FilterStore<Value>>>
Expand Down
21 changes: 21 additions & 0 deletions vue/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { MapStore} from 'nanostores'
import { map } from 'nanostores'

import { syncMapTemplate } from '../sync-map-template/index.js'
import { useFilter, useSync } from './index.js'

type Post = {
id: string
title: string
}

let $post = syncMapTemplate<Post>('posts')

let post = useSync($post, '10')
let postList = useFilter($post, { id: '10' })

let $custom = (id: string): MapStore<Post> => map({ id, text: 'A' })
let custom = useSync($custom, '10')
let customList = useFilter($custom, { id: '10' })

console.log({ custom, customList, post, postList })

0 comments on commit 499440e

Please sign in to comment.