@based/react 4.5.2 → 4.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ export declare const useQueries: <T = any>(name?: string, payloads?: any[], opts
7
7
  error?: BasedError;
8
8
  checksum?: string;
9
9
  }[];
10
- export declare const useQuery: <N extends string | number>(name: N, payload?: QueryMap[N]["payload"], opts?: {
10
+ export declare const useQuery: <N extends keyof QueryMap>(name: N, payload?: QueryMap[N]["payload"], opts?: {
11
11
  persistent: boolean;
12
12
  }) => {
13
13
  loading: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../src/useQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAIjE,eAAO,MAAM,UAAU,mBACd,MAAM,aACF,GAAG,EAAE,SACT;IACL,UAAU,EAAE,OAAO,CAAA;CACpB;aAEQ,OAAO;;YAER,UAAU;eACP,MAAM;GA4DlB,CAAA;AAED,eAAO,MAAM,QAAQ,gFAGZ;IACL,UAAU,EAAE,OAAO,CAAA;CACpB;aAEQ,OAAO;;YAER,UAAU;eACP,MAAM;CAsElB,CAAA"}
1
+ {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../src/useQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAIjE,eAAO,MAAM,UAAU,mBACd,MAAM,aACF,GAAG,EAAE,SACT;IACL,UAAU,EAAE,OAAO,CAAA;CACpB;aAEQ,OAAO;;YAER,UAAU;eACP,MAAM;GA4DlB,CAAA;AAED,eAAO,MAAM,QAAQ,+EAGZ;IACL,UAAU,EAAE,OAAO,CAAA;CACpB;aAEQ,OAAO;;YAER,UAAU;eACP,MAAM;CAsElB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@based/react",
3
- "version": "4.5.2",
3
+ "version": "4.5.4",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -17,7 +17,8 @@
17
17
  "ts-node": "10.9.1",
18
18
  "typescript": "^4.3.5",
19
19
  "react-dom": "^18.2.0",
20
- "@saulx/aristotle": "^4.7.1"
20
+ "@saulx/aristotle": "^4.7.1",
21
+ "@based/client": "^4.8.10"
21
22
  },
22
23
  "peerDependencies": {
23
24
  "@based/client": "^4.8.10",
package/src/Ctx.ts DELETED
@@ -1,4 +0,0 @@
1
- import { createContext } from 'react'
2
- import { BasedClient } from '@based/client'
3
-
4
- export const Ctx = createContext<BasedClient>(null)
package/src/Provider.ts DELETED
@@ -1,10 +0,0 @@
1
- import { createElement, FC, ReactNode } from 'react'
2
- import { BasedClient } from '@based/client'
3
- import { Ctx } from './Ctx'
4
-
5
- export const Provider: FC<{
6
- client: BasedClient
7
- children: ReactNode
8
- }> = ({ client, children }) => {
9
- return createElement(Ctx.Provider, { value: client }, children)
10
- }
package/src/index.ts DELETED
@@ -1,8 +0,0 @@
1
- export * from './Ctx'
2
- export * from './Provider'
3
- export * from './useAuthState'
4
- export * from './useClient'
5
- export * from './useConnected'
6
- export * from './useLoading'
7
- export * from './useQuery'
8
- export * from './useWindow'
@@ -1,21 +0,0 @@
1
- import { useContext, useState, useEffect } from 'react'
2
- import { BasedClient, AuthState } from '@based/client'
3
- import { Ctx } from './Ctx'
4
-
5
- export const useAuthState = (): AuthState => {
6
- const client: BasedClient = useContext(Ctx)
7
- const [state, setState] = useState<AuthState>(client?.authState || {})
8
-
9
- useEffect(() => {
10
- if (client) {
11
- setState(client.authState)
12
- const listener = (authState) => {
13
- setState(authState)
14
- }
15
- client.on('authstate-change', listener)
16
- return () => client.off('authstate-change', listener)
17
- }
18
- }, [client])
19
-
20
- return state
21
- }
package/src/useClient.ts DELETED
@@ -1,7 +0,0 @@
1
- import { useContext } from 'react'
2
- import { BasedClient } from '@based/client'
3
- import { Ctx } from './Ctx'
4
-
5
- export const useClient = (): BasedClient => {
6
- return useContext(Ctx)
7
- }
@@ -1,27 +0,0 @@
1
- import { useContext, useState, useEffect } from 'react'
2
- import { BasedClient } from '@based/client'
3
- import { Ctx } from './Ctx'
4
-
5
- export const useConnected = () => {
6
- const client: BasedClient = useContext(Ctx)
7
- const [connected, setConnected] = useState(client.connected)
8
-
9
- useEffect(() => {
10
- if (client) {
11
- setConnected(client.connected)
12
- const listener = () => {
13
- setConnected(client.connected)
14
- }
15
- client.on('disconnect', listener)
16
- client.on('reconnect', listener)
17
- client.on('connect', listener)
18
- return () => {
19
- client.off('disconnect', listener)
20
- client.off('reconnect', listener)
21
- client.off('connect', listener)
22
- }
23
- }
24
- }, [client])
25
-
26
- return { connected }
27
- }
package/src/useLoading.ts DELETED
@@ -1,14 +0,0 @@
1
- import { useState, useEffect } from 'react'
2
-
3
- export const useLoadingListeners: Set<Function> = new Set()
4
- export const hooksLoading: Set<number> = new Set()
5
- export const useLoading = () => {
6
- const [isLoading, setLoading] = useState(hooksLoading.size > 0)
7
- useEffect(() => {
8
- useLoadingListeners.add(setLoading)
9
- return () => {
10
- useLoadingListeners.delete(setLoading)
11
- }
12
- }, [])
13
- return isLoading
14
- }
package/src/useQuery.ts DELETED
@@ -1,158 +0,0 @@
1
- import { useContext, useState, useEffect } from 'react'
2
- import { BasedClient, BasedError, QueryMap } from '@based/client'
3
- import { Ctx } from './Ctx'
4
- import { hooksLoading, useLoadingListeners } from './useLoading'
5
-
6
- export const useQueries = <T = any>(
7
- name?: string,
8
- payloads?: any[],
9
- opts?: {
10
- persistent: boolean
11
- }
12
- ): {
13
- loading: boolean
14
- data?: T
15
- error?: BasedError
16
- checksum?: string
17
- }[] => {
18
- // TODO add error handling
19
- const client: BasedClient = useContext(Ctx)
20
- let key = ''
21
- let sum = ''
22
-
23
- if (client && name) {
24
- const queries = Array(payloads.length)
25
- const result = payloads.map((payload, i) => {
26
- // @ts-ignore
27
- const q = client.query(name, payload, opts)
28
- const { id, cache } = q
29
- queries[i] = q
30
- key += id
31
-
32
- if (cache) {
33
- sum += cache.checksum
34
- return { loading: false, data: cache.value, checksum: cache.checksum }
35
- }
36
-
37
- return { loading: true }
38
- })
39
-
40
- const [, update] = useState(sum)
41
-
42
- useEffect(() => {
43
- let raf
44
- const listener = () => {
45
- if (!raf) {
46
- raf = requestAnimationFrame(() => {
47
- raf = null
48
- update(
49
- queries.reduce((sum, { cache }) => {
50
- return cache ? sum + cache.checksum : sum
51
- }, '')
52
- )
53
- })
54
- }
55
- }
56
-
57
- const unsubs = queries.map((q) => {
58
- return q.subscribe(listener)
59
- })
60
-
61
- return () => {
62
- unsubs.forEach((unsubscribe) => unsubscribe())
63
- if (raf) {
64
- cancelAnimationFrame(raf)
65
- }
66
- }
67
- }, [key])
68
-
69
- return result
70
- }
71
-
72
- useState(sum)
73
- useEffect(() => {}, [key])
74
-
75
- return Array(payloads.length).fill({ loading: true })
76
- }
77
-
78
- export const useQuery = <N extends keyof QueryMap>(
79
- name: N,
80
- payload?: QueryMap[N]['payload'],
81
- opts?: {
82
- persistent: boolean
83
- }
84
- ): {
85
- loading: boolean
86
- data?: QueryMap[N]['result']
87
- error?: BasedError
88
- checksum?: number
89
- } => {
90
- const client: BasedClient = useContext(Ctx)
91
-
92
- if (client && name) {
93
- // @ts-ignore
94
- const q = client.query(name, payload, opts)
95
- const { id, cache } = q
96
- const [checksumOrError, update] = useState<number | BasedError>(
97
- cache?.checksum
98
- )
99
-
100
- useEffect(() => {
101
- const unsubscribe = q.subscribe(
102
- (_, checksum) => {
103
- update(checksum)
104
- },
105
- (err) => {
106
- update(err)
107
- }
108
- )
109
- return () => {
110
- const isLoading = hooksLoading.size > 0
111
- if (hooksLoading.delete(id) && !(hooksLoading.size > 0) && isLoading) {
112
- useLoadingListeners.forEach((fn) => {
113
- fn(false)
114
- })
115
- }
116
- unsubscribe()
117
- update(0)
118
- }
119
- }, [id])
120
-
121
- if (checksumOrError) {
122
- const isLoading = hooksLoading.size > 0
123
- if (hooksLoading.delete(id)) {
124
- if (!(hooksLoading.size > 0) && isLoading) {
125
- useLoadingListeners.forEach((fn) => {
126
- fn(false)
127
- })
128
- }
129
- }
130
-
131
- if (typeof checksumOrError === 'number') {
132
- if (!cache) {
133
- return { loading: true }
134
- }
135
-
136
- return { loading: false, data: cache.value, checksum: checksumOrError }
137
- }
138
-
139
- return { loading: false, error: checksumOrError }
140
- }
141
-
142
- const isLoading = hooksLoading.size > 0
143
- if (hooksLoading.add(id)) {
144
- if (!isLoading) {
145
- useLoadingListeners.forEach((fn) => {
146
- fn(true)
147
- })
148
- }
149
- }
150
-
151
- return { loading: true }
152
- }
153
-
154
- useState()
155
- useEffect(() => {}, [null])
156
-
157
- return { loading: true }
158
- }
package/src/useWindow.ts DELETED
@@ -1,151 +0,0 @@
1
- import { useState, useEffect, useContext, useRef } from 'react'
2
- import { Ctx } from './Ctx'
3
- import { BasedClient, BasedQuery } from '@based/client'
4
- import { hash } from '@saulx/hash'
5
-
6
- type UseWindowState = {
7
- loading: boolean
8
- items: any[]
9
- checksum?: number
10
- }
11
-
12
- export const useWindow = (
13
- name: string,
14
- getPayload: ({ offset, limit }) => any,
15
- opts: {
16
- path: string[]
17
- pages: number[]
18
- size: number
19
- persistent?: boolean
20
- },
21
- dependencies?: any
22
- ): UseWindowState => {
23
- const [checksum, setCheckum] = useState(0)
24
- const cache = useRef<UseWindowState>()
25
- const client: BasedClient = useContext(Ctx)
26
- const queries = useRef<BasedQuery[]>()
27
- const unsubs = useRef<{}>()
28
- const raf = useRef<number>()
29
- const currModifyHash = useRef<string>()
30
- const currResetHash = useRef<number>()
31
- const modifyHash = `${opts.size}.${opts.persistent}`
32
-
33
- if (dependencies) {
34
- // complete reset
35
- const resetHash = hash(dependencies)
36
- if (currResetHash.current !== resetHash) {
37
- currResetHash.current = resetHash
38
- currModifyHash.current = null
39
- cache.current = null
40
- }
41
- }
42
-
43
- if (currModifyHash.current !== modifyHash) {
44
- // reset queries but keep cache
45
- for (const n in unsubs.current) {
46
- unsubs.current[n]()
47
- }
48
- if (raf.current) {
49
- cancelAnimationFrame(raf.current)
50
- raf.current = null
51
- }
52
- queries.current = []
53
- unsubs.current = {}
54
- currModifyHash.current = modifyHash
55
-
56
- if (!cache.current) {
57
- cache.current = { items: [], loading: true, checksum: 0 }
58
- }
59
- }
60
-
61
- useEffect(() => {
62
- return () => {
63
- for (const n in unsubs.current) {
64
- unsubs.current[n]()
65
- }
66
- if (raf.current) {
67
- cancelAnimationFrame(raf.current)
68
- }
69
- }
70
- }, [])
71
-
72
- if (client && name) {
73
- const { pages, size, persistent = false, path } = opts
74
- const active = new Set()
75
-
76
- // add new subs
77
- pages.forEach((n) => {
78
- // pages start at 1 => shift to 0
79
- n -= 1
80
- active.add(n)
81
- if (!(n in queries.current)) {
82
- const payload = getPayload({ offset: n * size, limit: size })
83
- const q = client.query(name, payload, { persistent })
84
- queries.current[n] = q
85
- }
86
- if (n in unsubs.current) return
87
- unsubs.current[n] = queries.current[n].subscribe(() => {
88
- if (raf.current) return
89
- raf.current = requestAnimationFrame(() => {
90
- raf.current = null
91
- setCheckum(
92
- queries.current.reduce((combined, { cache }) => {
93
- const checksum = cache?.checksum
94
- return checksum ? combined + checksum : combined
95
- }, 0)
96
- )
97
- })
98
- })
99
- })
100
-
101
- // remove inactive subs
102
- queries.current.forEach((_, n) => {
103
- if (n in unsubs.current && !active.has(n)) {
104
- unsubs.current[n]()
105
- delete unsubs.current[n]
106
- }
107
- })
108
-
109
- if (cache.current.checksum === checksum) {
110
- return cache.current
111
- }
112
-
113
- let l = queries.current.length
114
- cache.current.items = []
115
- cache.current.loading = false
116
- cache.current.checksum = checksum
117
-
118
- while (l--) {
119
- let i = size * l
120
- const q = queries.current[l]
121
- const m = i + size
122
-
123
- if (q) {
124
- if (q.cache) {
125
- let data = q.cache.value
126
- for (const i of path) {
127
- data = data?.[i]
128
- }
129
- if (data) {
130
- for (let j = 0; i < m; i++) {
131
- const item = data[j++]
132
- if (!item) break
133
- cache.current.items[i] = item
134
- }
135
- }
136
- } else {
137
- cache.current.loading = true
138
- }
139
- }
140
-
141
- // // fill up empty items with null
142
- // for (; i < m; i++) {
143
- // if (!(i in cache.current.items)) {
144
- // cache.current.items[i] = null
145
- // }
146
- // }
147
- }
148
- }
149
-
150
- return cache.current
151
- }
@@ -1,58 +0,0 @@
1
- import { BasedServer } from '@based/server'
2
- import { BasedQueryFunction } from '@based/functions'
3
-
4
- const counter: BasedQueryFunction<{ speed: number }, { cnt: number }> = (
5
- _based,
6
- payload,
7
- update
8
- ) => {
9
- let cnt = 0
10
- // update({ cnt })
11
- const int = setInterval(() => {
12
- update({ cnt: ++cnt })
13
- }, payload.speed ?? 1e3)
14
- return () => {
15
- clearInterval(int)
16
- }
17
- }
18
-
19
- const fakeDb = (_based, { offset, limit }, update) => {
20
- let i
21
- let cnt = 0
22
- const timer = setTimeout(() => {
23
- const doit = () => {
24
- cnt++
25
- const things = Array.from(Array(limit)).map((_, i) => {
26
- return {
27
- id: `${i + offset} - ${cnt}`,
28
- }
29
- })
30
- update({ things })
31
- }
32
-
33
- i = setInterval(doit, 1e3)
34
- doit()
35
- }, 100)
36
- return () => {
37
- clearTimeout(timer)
38
- clearInterval(i)
39
- }
40
- }
41
-
42
- const server = new BasedServer({
43
- port: 8081,
44
- functions: {
45
- configs: {
46
- 'fake-db': {
47
- type: 'query',
48
- fn: fakeDb,
49
- },
50
- counter: {
51
- type: 'query',
52
- fn: counter,
53
- },
54
- },
55
- },
56
- })
57
-
58
- server.start()
package/test/browser.tsx DELETED
@@ -1,137 +0,0 @@
1
- import React, { useState } from 'react'
2
- import based from '@based/client'
3
- import { createRoot } from 'react-dom/client'
4
- import { Provider, useQuery, useLoading, useWindow } from '../src'
5
-
6
- const client = based({
7
- url: 'ws://localhost:8081',
8
- })
9
-
10
- const Tester = () => {
11
- const somethingIsLoading = useLoading()
12
-
13
- const [q, setP] = useState<any>({
14
- name: 'counter',
15
- payload: { bla: true },
16
- })
17
-
18
- // useQuery('')
19
-
20
- const x = useQuery(q.name, q.payload)
21
-
22
- const payloads = [
23
- { name: 'counter', payload: { bla: false } },
24
- { name: 'counter', payload: { bla: true } },
25
- { name: 'gurt', payload: { bla: false } },
26
- { name: null },
27
- ]
28
-
29
- return (
30
- <div>
31
- <div
32
- style={{
33
- display: 'flex',
34
- }}
35
- >
36
- <div
37
- style={{
38
- width: 50,
39
- height: 50,
40
- background: somethingIsLoading ? 'red' : 'blue',
41
- }}
42
- />
43
- {payloads.map((v, i) => {
44
- return (
45
- <div
46
- key={i}
47
- style={{
48
- border: '1px solid green',
49
- padding: 5,
50
- cursor: 'pointer',
51
- }}
52
- onClick={() => setP(v)}
53
- >
54
- <pre>{JSON.stringify(v, null, 2)}</pre>
55
- </div>
56
- )
57
- })}
58
- </div>
59
- </div>
60
- )
61
- }
62
-
63
- const UseWindowTester = () => {
64
- const [pages, setPages] = useState([1, 2])
65
- const [size, setSize] = useState(4)
66
- const { items, loading } = useWindow(
67
- 'fake-db',
68
- ({ offset, limit }) => {
69
- return {
70
- offset,
71
- limit,
72
- }
73
- },
74
- {
75
- path: ['things'], // where are the items in the response?
76
- pages, // array of page numbers - starts at 1
77
- size, // amount of items per page
78
- }
79
- )
80
-
81
- return (
82
- <>
83
- <div style={{ display: 'flex' }}>
84
- <pre>{JSON.stringify({ loading, items }, null, 2)}</pre>
85
- <div>
86
- {items.map((item, index) => {
87
- return <div key={index}>{item?.id || '-'}</div>
88
- })}
89
- </div>
90
- </div>
91
- <button
92
- style={{
93
- background: 'lightgrey',
94
- padding: 16,
95
- }}
96
- onClick={() => {
97
- setPages(
98
- pages.map((n) => {
99
- return n + 3
100
- })
101
- )
102
- }}
103
- >
104
- Move ({pages.join(',')})
105
- </button>
106
- <button
107
- style={{
108
- background: 'lightgrey',
109
- padding: 16,
110
- }}
111
- onClick={() => {
112
- setSize(size + 1)
113
- }}
114
- >
115
- Resize ({size})
116
- </button>
117
- </>
118
- )
119
- }
120
-
121
- function App() {
122
- return (
123
- <div
124
- style={{
125
- padding: 100,
126
- }}
127
- >
128
- <Provider client={client}>
129
- <Tester />
130
- <UseWindowTester />
131
- </Provider>
132
- </div>
133
- )
134
- }
135
-
136
- const root = createRoot(document.body)
137
- root.render(<App />)
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "rootDir": "src",
5
- "outDir": "dist"
6
- },
7
- "include": ["src/**/*", "src/**/*.json"],
8
- "exclude": ["node_modules", "test", "dist", "tmp", "examples"]
9
- }