@based/react 4.2.7 → 4.3.1

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.
package/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { FC, ReactNode } from 'react';
2
2
  import { BasedClient, AuthState } from '@based/client';
3
+ import { BasedError } from '@based/client';
3
4
  export declare const Provider: FC<{
4
5
  client: BasedClient;
5
6
  children: ReactNode;
6
7
  }>;
7
8
  export declare const useAuthState: () => AuthState;
9
+ export declare const useLoading: () => boolean;
8
10
  export declare const useConnected: () => {
9
11
  connected: boolean;
10
12
  };
@@ -13,6 +15,7 @@ export declare const useQuery: <T = any>(name?: string, payload?: any, opts?: {
13
15
  }) => {
14
16
  loading: boolean;
15
17
  data?: T;
18
+ error?: BasedError;
16
19
  checksum?: number;
17
20
  };
18
21
  export declare const useClient: () => BasedClient;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useClient = exports.useQuery = exports.useConnected = exports.useAuthState = exports.Provider = void 0;
3
+ exports.useClient = exports.useQuery = exports.useConnected = exports.useLoading = exports.useAuthState = exports.Provider = void 0;
4
4
  const react_1 = require("react");
5
5
  const Ctx = (0, react_1.createContext)(null);
6
6
  const Provider = ({ client, children }) => {
@@ -23,6 +23,19 @@ const useAuthState = () => {
23
23
  return state;
24
24
  };
25
25
  exports.useAuthState = useAuthState;
26
+ const useLoadingListeners = new Set();
27
+ const hooksLoading = new Set();
28
+ const useLoading = () => {
29
+ const [isLoading, setLoading] = (0, react_1.useState)(hooksLoading.size > 0);
30
+ (0, react_1.useEffect)(() => {
31
+ useLoadingListeners.add(setLoading);
32
+ return () => {
33
+ useLoadingListeners.delete(setLoading);
34
+ };
35
+ }, []);
36
+ return isLoading;
37
+ };
38
+ exports.useLoading = useLoading;
26
39
  const useConnected = () => {
27
40
  const client = (0, react_1.useContext)(Ctx);
28
41
  const [connected, setConnected] = (0, react_1.useState)(client.connected);
@@ -50,28 +63,58 @@ const useQuery = (name, payload, opts) => {
50
63
  if (client && name) {
51
64
  const q = client.query(name, payload, opts);
52
65
  const { id, cache } = q;
53
- const [checksum, update] = (0, react_1.useState)(cache?.checksum);
66
+ const [checksumOrError, update] = (0, react_1.useState)(cache?.checksum);
54
67
  (0, react_1.useEffect)(() => {
55
68
  const unsubscribe = q.subscribe((_, checksum) => {
56
69
  update(checksum);
70
+ }, (err) => {
71
+ update(err);
57
72
  });
58
73
  return () => {
74
+ const isLoading = hooksLoading.size > 0;
75
+ if (hooksLoading.delete(id) && !(hooksLoading.size > 0) && isLoading) {
76
+ useLoadingListeners.forEach((fn) => {
77
+ fn(false);
78
+ });
79
+ }
59
80
  unsubscribe();
81
+ update(0);
60
82
  };
61
83
  }, [id]);
62
- return cache
63
- ? { loading: false, data: cache.value, checksum }
64
- : { loading: true };
84
+ if (checksumOrError) {
85
+ const isLoading = hooksLoading.size > 0;
86
+ if (hooksLoading.delete(id)) {
87
+ if (!(hooksLoading.size > 0) && isLoading) {
88
+ useLoadingListeners.forEach((fn) => {
89
+ fn(false);
90
+ });
91
+ }
92
+ }
93
+ if (typeof checksumOrError === 'number') {
94
+ if (!cache) {
95
+ return { loading: true };
96
+ }
97
+ return { loading: false, data: cache.value, checksum: checksumOrError };
98
+ }
99
+ return { loading: false, error: checksumOrError };
100
+ }
101
+ const isLoading = hooksLoading.size > 0;
102
+ if (hooksLoading.add(id)) {
103
+ if (!isLoading) {
104
+ useLoadingListeners.forEach((fn) => {
105
+ fn(true);
106
+ });
107
+ }
108
+ }
109
+ return { loading: true };
65
110
  }
66
- // stubs
67
111
  (0, react_1.useState)();
68
112
  (0, react_1.useEffect)(() => { }, [null]);
69
113
  return { loading: true };
70
114
  };
71
115
  exports.useQuery = useQuery;
72
116
  const useClient = () => {
73
- const client = (0, react_1.useContext)(Ctx);
74
- return client;
117
+ return (0, react_1.useContext)(Ctx);
75
118
  };
76
119
  exports.useClient = useClient;
77
120
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@based/react",
3
- "version": "4.2.7",
3
+ "version": "4.3.1",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
+ "browser": "npx aristotle watch -t ./test/browser.tsx",
8
+ "server": "npx ts-node ./test/based-server.ts",
7
9
  "build": "npx tsc",
8
10
  "watch": "npm run build -- --watch",
9
11
  "clean": "rimraf {.turbo,dist,node_modules}"
@@ -13,7 +15,9 @@
13
15
  "@types/react": "^18.0.29",
14
16
  "rimraf": "^3.0.2",
15
17
  "ts-node": "10.9.1",
16
- "typescript": "^4.3.5"
18
+ "typescript": "^4.3.5",
19
+ "react-dom": "^18.2.0",
20
+ "@saulx/aristotle": "^4.7.1"
17
21
  },
18
22
  "peerDependencies": {
19
23
  "@based/client": "^4.6.1",
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  ReactNode,
9
9
  } from 'react'
10
10
  import { BasedClient, AuthState } from '@based/client'
11
+ import { BasedError } from '@based/client'
11
12
 
12
13
  const Ctx = createContext<BasedClient>(null)
13
14
 
@@ -36,6 +37,20 @@ export const useAuthState = (): AuthState => {
36
37
  return state
37
38
  }
38
39
 
40
+ const useLoadingListeners: Set<Function> = new Set()
41
+ const hooksLoading: Set<number> = new Set()
42
+
43
+ export const useLoading = () => {
44
+ const [isLoading, setLoading] = useState(hooksLoading.size > 0)
45
+ useEffect(() => {
46
+ useLoadingListeners.add(setLoading)
47
+ return () => {
48
+ useLoadingListeners.delete(setLoading)
49
+ }
50
+ }, [])
51
+ return isLoading
52
+ }
53
+
39
54
  export const useConnected = () => {
40
55
  const client: BasedClient = useContext(Ctx)
41
56
  const [connected, setConnected] = useState(client.connected)
@@ -69,6 +84,7 @@ export const useQuery = <T = any>(
69
84
  ): {
70
85
  loading: boolean
71
86
  data?: T
87
+ error?: BasedError
72
88
  checksum?: number
73
89
  } => {
74
90
  const client: BasedClient = useContext(Ctx)
@@ -76,24 +92,64 @@ export const useQuery = <T = any>(
76
92
  if (client && name) {
77
93
  const q = client.query(name, payload, opts)
78
94
  const { id, cache } = q
79
- const [checksum, update] = useState(cache?.checksum)
95
+ const [checksumOrError, update] = useState<number | BasedError>(
96
+ cache?.checksum
97
+ )
80
98
 
81
99
  useEffect(() => {
82
- const unsubscribe = q.subscribe((_, checksum) => {
83
- update(checksum)
84
- })
85
-
100
+ const unsubscribe = q.subscribe(
101
+ (_, checksum) => {
102
+ update(checksum)
103
+ },
104
+ (err) => {
105
+ update(err)
106
+ }
107
+ )
86
108
  return () => {
109
+ const isLoading = hooksLoading.size > 0
110
+ if (hooksLoading.delete(id) && !(hooksLoading.size > 0) && isLoading) {
111
+ useLoadingListeners.forEach((fn) => {
112
+ fn(false)
113
+ })
114
+ }
87
115
  unsubscribe()
116
+ update(0)
88
117
  }
89
118
  }, [id])
90
119
 
91
- return cache
92
- ? { loading: false, data: cache.value, checksum }
93
- : { loading: true }
120
+ if (checksumOrError) {
121
+ const isLoading = hooksLoading.size > 0
122
+ if (hooksLoading.delete(id)) {
123
+ if (!(hooksLoading.size > 0) && isLoading) {
124
+ useLoadingListeners.forEach((fn) => {
125
+ fn(false)
126
+ })
127
+ }
128
+ }
129
+
130
+ if (typeof checksumOrError === 'number') {
131
+ if (!cache) {
132
+ return { loading: true }
133
+ }
134
+
135
+ return { loading: false, data: cache.value, checksum: checksumOrError }
136
+ }
137
+
138
+ return { loading: false, error: checksumOrError }
139
+ }
140
+
141
+ const isLoading = hooksLoading.size > 0
142
+ if (hooksLoading.add(id)) {
143
+ if (!isLoading) {
144
+ useLoadingListeners.forEach((fn) => {
145
+ fn(true)
146
+ })
147
+ }
148
+ }
149
+
150
+ return { loading: true }
94
151
  }
95
152
 
96
- // stubs
97
153
  useState()
98
154
  useEffect(() => {}, [null])
99
155
 
@@ -101,6 +157,5 @@ export const useQuery = <T = any>(
101
157
  }
102
158
 
103
159
  export const useClient = (): BasedClient => {
104
- const client = useContext(Ctx)
105
- return client
160
+ return useContext(Ctx)
106
161
  }
@@ -0,0 +1,31 @@
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 server = new BasedServer({
20
+ port: 8081,
21
+ functions: {
22
+ configs: {
23
+ counter: {
24
+ type: 'query',
25
+ fn: counter,
26
+ },
27
+ },
28
+ },
29
+ })
30
+
31
+ server.start()
@@ -0,0 +1,77 @@
1
+ import React, { useState } from 'react'
2
+ import based from '@based/client'
3
+ import { createRoot } from 'react-dom/client'
4
+ import { Provider, useQuery, useLoading } 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
+ const x = useQuery(q.name, q.payload)
19
+
20
+ const payloads = [
21
+ { name: 'counter', payload: { bla: false } },
22
+ { name: 'counter', payload: { bla: true } },
23
+ { name: 'gurt', payload: { bla: false } },
24
+ { name: null },
25
+ ]
26
+
27
+ return (
28
+ <div>
29
+ <div
30
+ style={{
31
+ display: 'flex',
32
+ }}
33
+ >
34
+ <div
35
+ style={{
36
+ width: 50,
37
+ height: 50,
38
+ background: somethingIsLoading ? 'red' : 'blue',
39
+ }}
40
+ ></div>
41
+ {payloads.map((v) => {
42
+ return (
43
+ <div
44
+ style={{
45
+ border: '1px solid green',
46
+ padding: 5,
47
+ cursor: 'pointer',
48
+ }}
49
+ onClick={() => setP(v)}
50
+ >
51
+ <pre>{JSON.stringify(v, null, 2)}</pre>
52
+ </div>
53
+ )
54
+ })}
55
+ </div>
56
+
57
+ <pre>{JSON.stringify(x, null, 2)}</pre>
58
+ </div>
59
+ )
60
+ }
61
+
62
+ function App() {
63
+ return (
64
+ <div
65
+ style={{
66
+ padding: 100,
67
+ }}
68
+ >
69
+ <Provider client={client}>
70
+ <Tester />
71
+ </Provider>
72
+ </div>
73
+ )
74
+ }
75
+
76
+ const root = createRoot(document.body)
77
+ root.render(<App />)
package/test/index.tsx DELETED
File without changes