@latticexyz/react 2.0.0-alpha.94 → 2.0.0-foundry-js-c7b0289b

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/CHANGELOG.md CHANGED
@@ -1,8 +1,264 @@
1
1
  # Change Log
2
2
 
3
+ ## 2.0.0-foundry-js-c7b0289b
4
+
5
+ ### Major Changes
6
+
7
+ - e3de1a33: Removes `useRow` and `useRows` hooks, previously powered by `store-cache`, which is now deprecated. Please use `recs` and the corresponding `useEntityQuery` and `useComponentValue` hooks. We'll have more hooks soon for SQL.js sync backends.
8
+
9
+ ### Minor Changes
10
+
11
+ - 939916bc: Adds a `usePromise` hook that returns a [native `PromiseSettledResult` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled).
12
+
13
+ ```tsx
14
+ const promise = fetch(url);
15
+ const result = usePromise(promise);
16
+
17
+ if (result.status === "idle" || result.status === "pending") {
18
+ return <>fetching</>;
19
+ }
20
+
21
+ if (result.status === "rejected") {
22
+ return <>error fetching: {String(result.reason)}</>;
23
+ }
24
+
25
+ if (result.status === "fulfilled") {
26
+ return <>fetch status: {result.value.status}</>;
27
+ }
28
+ ```
29
+
30
+ ### Patch Changes
31
+
32
+ - Updated dependencies [7ce82b6f]
33
+ - Updated dependencies [c963b46c]
34
+ - Updated dependencies [ce7125a1]
35
+ - Updated dependencies [aea67c58]
36
+ - Updated dependencies [07dd6f32]
37
+ - Updated dependencies [c14f8bf1]
38
+ - Updated dependencies [90e4161b]
39
+ - Updated dependencies [331dbfdc]
40
+ - Updated dependencies [1d60930d]
41
+ - Updated dependencies [f9f9609e]
42
+ - Updated dependencies [904fd7d4]
43
+ - Updated dependencies [b9e562d8]
44
+ - Updated dependencies [759514d8]
45
+ - Updated dependencies [952cd534]
46
+ - Updated dependencies [d5094a24]
47
+ - Updated dependencies [a2588116]
48
+ - Updated dependencies [c4d5eb4e]
49
+ - Updated dependencies [f62c767e]
50
+ - Updated dependencies [de151fec]
51
+ - Updated dependencies [ae340b2b]
52
+ - Updated dependencies [211be2a1]
53
+ - Updated dependencies [0f3e2e02]
54
+ - Updated dependencies [d0878928]
55
+ - Updated dependencies [5c965a91]
56
+ - Updated dependencies [f99e8898]
57
+ - Updated dependencies [d5b73b12]
58
+ - Updated dependencies [433078c5]
59
+ - Updated dependencies [b2d2aa71]
60
+ - Updated dependencies [83583a50]
61
+ - Updated dependencies [5e723b90]
62
+ - Updated dependencies [6573e38e]
63
+ - Updated dependencies [afaf2f5f]
64
+ - Updated dependencies [44a5432a]
65
+ - Updated dependencies [6e66c5b7]
66
+ - Updated dependencies [8d51a034]
67
+ - Updated dependencies [1e2ad78e]
68
+ - Updated dependencies [65c9546c]
69
+ - Updated dependencies [48909d15]
70
+ - Updated dependencies [48c51b52]
71
+ - Updated dependencies [66cc35a8]
72
+ - Updated dependencies [672d05ca]
73
+ - Updated dependencies [63831a26]
74
+ - Updated dependencies [a7b30c79]
75
+ - Updated dependencies [92de5998]
76
+ - Updated dependencies [22ee4470]
77
+ - Updated dependencies [be313068]
78
+ - Updated dependencies [ac508bf1]
79
+ - Updated dependencies [bb91edaa]
80
+ - Updated dependencies [bfcb293d]
81
+ - Updated dependencies [1890f1a0]
82
+ - Updated dependencies [9b43029c]
83
+ - Updated dependencies [55ab88a6]
84
+ - Updated dependencies [53522998]
85
+ - Updated dependencies [af639a26]
86
+ - Updated dependencies [5e723b90]
87
+ - Updated dependencies [99ab9cd6]
88
+ - Updated dependencies [0d12db8c]
89
+ - Updated dependencies [c049c23f]
90
+ - Updated dependencies [80dd6992]
91
+ - Updated dependencies [60cfd089]
92
+ - Updated dependencies [24a6cd53]
93
+ - Updated dependencies [708b49c5]
94
+ - Updated dependencies [22ba7b67]
95
+ - Updated dependencies [5e71e1cb]
96
+ - Updated dependencies [8025c350]
97
+ - Updated dependencies [afdba793]
98
+ - Updated dependencies [cea754dd]
99
+ - Updated dependencies [cc2c8da0]
100
+ - @latticexyz/store@2.0.0-foundry-js-c7b0289b
101
+ - @latticexyz/recs@2.0.0-foundry-js-c7b0289b
102
+
103
+ ## 2.0.0-next.14
104
+
105
+ ### Patch Changes
106
+
107
+ - Updated dependencies [b2d2aa71]
108
+ - Updated dependencies [bb91edaa]
109
+ - @latticexyz/store@2.0.0-next.14
110
+ - @latticexyz/recs@2.0.0-next.14
111
+
112
+ ## 2.0.0-next.13
113
+
114
+ ### Patch Changes
115
+
116
+ - @latticexyz/recs@2.0.0-next.13
117
+ - @latticexyz/store@2.0.0-next.13
118
+
119
+ ## 2.0.0-next.12
120
+
121
+ ### Patch Changes
122
+
123
+ - Updated dependencies [7ce82b6f]
124
+ - Updated dependencies [f62c767e]
125
+ - @latticexyz/store@2.0.0-next.12
126
+ - @latticexyz/recs@2.0.0-next.12
127
+
128
+ ## 2.0.0-next.11
129
+
130
+ ### Patch Changes
131
+
132
+ - Updated dependencies [f99e8898]
133
+ - @latticexyz/store@2.0.0-next.11
134
+ - @latticexyz/recs@2.0.0-next.11
135
+
136
+ ## 2.0.0-next.10
137
+
138
+ ### Patch Changes
139
+
140
+ - Updated dependencies []:
141
+ - @latticexyz/recs@2.0.0-next.10
142
+ - @latticexyz/store@2.0.0-next.10
143
+
144
+ ## 2.0.0-next.9
145
+
146
+ ### Patch Changes
147
+
148
+ - Updated dependencies [[`aea67c58`](https://github.com/latticexyz/mud/commit/aea67c5804efb2a8b919f5aa3a053d9b04184e84), [`07dd6f32`](https://github.com/latticexyz/mud/commit/07dd6f32c9bb9f0e807bac3586c5cc9833f14ab9), [`90e4161b`](https://github.com/latticexyz/mud/commit/90e4161bb8574a279d9edb517ce7def3624adaa8), [`331dbfdc`](https://github.com/latticexyz/mud/commit/331dbfdcbbda404de4b0fd4d439d636ae2033853), [`f9f9609e`](https://github.com/latticexyz/mud/commit/f9f9609ef69d7fa58cad6a9af3fe6d2eed6d8aa2), [`759514d8`](https://github.com/latticexyz/mud/commit/759514d8b980fa5fe49a4ef919d8008b215f2af8), [`d5094a24`](https://github.com/latticexyz/mud/commit/d5094a2421cf2882a317e3ad9600c8de004b20d4), [`de151fec`](https://github.com/latticexyz/mud/commit/de151fec07b63a6022483c1ad133c556dd44992e), [`ae340b2b`](https://github.com/latticexyz/mud/commit/ae340b2bfd98f4812ed3a94c746af3611645a623), [`211be2a1`](https://github.com/latticexyz/mud/commit/211be2a1eba8600ad53be6f8c70c64a8523113b9), [`0f3e2e02`](https://github.com/latticexyz/mud/commit/0f3e2e02b5114e08fe700c18326db76816ffad3c), [`d0878928`](https://github.com/latticexyz/mud/commit/d08789282c8b8d4c12897e2ff5a688af9115fb1c), [`83583a50`](https://github.com/latticexyz/mud/commit/83583a5053de4e5e643572e3b1c0f49467e8e2ab), [`5e723b90`](https://github.com/latticexyz/mud/commit/5e723b90e6b18bc70d357ff4b0a1b217611236ae), [`6573e38e`](https://github.com/latticexyz/mud/commit/6573e38e9064121540aa46ce204d8ca5d61ed847), [`44a5432a`](https://github.com/latticexyz/mud/commit/44a5432acb9c5af3dca1447c50219a00894c45a9), [`6e66c5b7`](https://github.com/latticexyz/mud/commit/6e66c5b745a036c5bc5422819de9c518a6f6cc96), [`65c9546c`](https://github.com/latticexyz/mud/commit/65c9546c4ee8a410b21d032f02b0050442152e7e), [`672d05ca`](https://github.com/latticexyz/mud/commit/672d05ca130649bd90df337c2bf03204a5878840), [`63831a26`](https://github.com/latticexyz/mud/commit/63831a264b6b09501f380a4601f82ba7bf07a619), [`92de5998`](https://github.com/latticexyz/mud/commit/92de59982fb9fc4e00e50c4a5232ed541f3ce71a), [`22ee4470`](https://github.com/latticexyz/mud/commit/22ee4470047e4611a3cae62e9d0af4713aa1e612), [`be313068`](https://github.com/latticexyz/mud/commit/be313068b158265c2deada55eebfd6ba753abb87), [`ac508bf1`](https://github.com/latticexyz/mud/commit/ac508bf189b098e66b59a725f58a2008537be130), [`bfcb293d`](https://github.com/latticexyz/mud/commit/bfcb293d1931edde7f8a3e077f6f555a26fd1d2f), [`1890f1a0`](https://github.com/latticexyz/mud/commit/1890f1a0603982477bfde1b7335969f51e2dce70), [`9b43029c`](https://github.com/latticexyz/mud/commit/9b43029c3c888f8e82b146312f5c2e92321c28a7), [`55ab88a6`](https://github.com/latticexyz/mud/commit/55ab88a60adb3ad72ebafef4d50513eb71e3c314), [`af639a26`](https://github.com/latticexyz/mud/commit/af639a26446ca4b689029855767f8a723557f62c), [`5e723b90`](https://github.com/latticexyz/mud/commit/5e723b90e6b18bc70d357ff4b0a1b217611236ae), [`99ab9cd6`](https://github.com/latticexyz/mud/commit/99ab9cd6fff1a732b47d63ead894292661682380), [`c049c23f`](https://github.com/latticexyz/mud/commit/c049c23f48b93ac7881fb1a5a8417831611d5cbf), [`80dd6992`](https://github.com/latticexyz/mud/commit/80dd6992e98c90a91d417fc785d0d53260df6ce2), [`24a6cd53`](https://github.com/latticexyz/mud/commit/24a6cd536f0c31cab93fb7644751cb9376be383d), [`708b49c5`](https://github.com/latticexyz/mud/commit/708b49c50e05f7b67b596e72ebfcbd76e1ff6280), [`22ba7b67`](https://github.com/latticexyz/mud/commit/22ba7b675bd50d1bb18b8a71c0de17c6d70d78c7), [`cea754dd`](https://github.com/latticexyz/mud/commit/cea754dde0d8abf7392e93faa319b260956ae92b)]:
149
+ - @latticexyz/store@2.0.0-next.9
150
+ - @latticexyz/recs@2.0.0-next.9
151
+
152
+ ## 2.0.0-next.8
153
+
154
+ ### Patch Changes
155
+
156
+ - Updated dependencies [[`1d60930d`](https://github.com/latticexyz/mud/commit/1d60930d6d4c9a0bda262e5e23a5f719b9dd48c7), [`b9e562d8`](https://github.com/latticexyz/mud/commit/b9e562d8f7a6051bb1a7262979b268fd2c83daac), [`5e71e1cb`](https://github.com/latticexyz/mud/commit/5e71e1cb541b0a18ee414e18dd80f1dd24a92b98)]:
157
+ - @latticexyz/store@2.0.0-next.8
158
+ - @latticexyz/recs@2.0.0-next.8
159
+
160
+ ## 2.0.0-next.7
161
+
162
+ ### Patch Changes
163
+
164
+ - Updated dependencies [[`c4d5eb4e`](https://github.com/latticexyz/mud/commit/c4d5eb4e4e4737112b981a795a9c347e3578cb15)]:
165
+ - @latticexyz/store@2.0.0-next.7
166
+ - @latticexyz/recs@2.0.0-next.7
167
+
168
+ ## 2.0.0-next.6
169
+
170
+ ### Patch Changes
171
+
172
+ - Updated dependencies [[`8025c350`](https://github.com/latticexyz/mud/commit/8025c3505a7411d8539b1cfd72265aed27e04561)]:
173
+ - @latticexyz/store@2.0.0-next.6
174
+ - @latticexyz/recs@2.0.0-next.6
175
+
176
+ ## 2.0.0-next.5
177
+
178
+ ### Patch Changes
179
+
180
+ - Updated dependencies []:
181
+ - @latticexyz/recs@2.0.0-next.5
182
+ - @latticexyz/store@2.0.0-next.5
183
+
184
+ ## 2.0.0-next.4
185
+
186
+ ### Major Changes
187
+
188
+ - [#1343](https://github.com/latticexyz/mud/pull/1343) [`e3de1a33`](https://github.com/latticexyz/mud/commit/e3de1a338fe110ac33ba9fb833366541e4cf4cf1) Thanks [@holic](https://github.com/holic)! - Removes `useRow` and `useRows` hooks, previously powered by `store-cache`, which is now deprecated. Please use `recs` and the corresponding `useEntityQuery` and `useComponentValue` hooks. We'll have more hooks soon for SQL.js sync backends.
189
+
190
+ ### Patch Changes
191
+
192
+ - Updated dependencies [[`ce7125a1`](https://github.com/latticexyz/mud/commit/ce7125a1b97efd3db47c5ea1593d5a37ba143f64), [`c14f8bf1`](https://github.com/latticexyz/mud/commit/c14f8bf1ec8c199902c12899853ac144aa69bb9c)]:
193
+ - @latticexyz/recs@2.0.0-next.4
194
+ - @latticexyz/store@2.0.0-next.4
195
+
196
+ ## 2.0.0-next.3
197
+
198
+ ### Patch Changes
199
+
200
+ - Updated dependencies [[`952cd534`](https://github.com/latticexyz/mud/commit/952cd534447d08e6231ab147ed1cc24fb49bbb57), [`d5b73b12`](https://github.com/latticexyz/mud/commit/d5b73b12666699c442d182ee904fa8747b78fefd), [`433078c5`](https://github.com/latticexyz/mud/commit/433078c54c22fa1b4e32d7204fb41bd5f79ca1db), [`afaf2f5f`](https://github.com/latticexyz/mud/commit/afaf2f5ffb36fe389a3aba8da2f6d8c84bdb26ab), [`0d12db8c`](https://github.com/latticexyz/mud/commit/0d12db8c2170905f5116111e6bc417b6dca8eb61)]:
201
+ - @latticexyz/store@2.0.0-next.3
202
+ - @latticexyz/store-cache@2.0.0-next.3
203
+ - @latticexyz/recs@2.0.0-next.3
204
+
205
+ ## 2.0.0-next.2
206
+
207
+ ### Minor Changes
208
+
209
+ - [#1284](https://github.com/latticexyz/mud/pull/1284) [`939916bc`](https://github.com/latticexyz/mud/commit/939916bcd5c9f3caf0399e9ab7689e77e6bef7ad) Thanks [@holic](https://github.com/holic)! - Adds a `usePromise` hook that returns a [native `PromiseSettledResult` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled).
210
+
211
+ ```tsx
212
+ const promise = fetch(url);
213
+ const result = usePromise(promise);
214
+
215
+ if (result.status === "idle" || result.status === "pending") {
216
+ return <>fetching</>;
217
+ }
218
+
219
+ if (result.status === "rejected") {
220
+ return <>error fetching: {String(result.reason)}</>;
221
+ }
222
+
223
+ if (result.status === "fulfilled") {
224
+ return <>fetch status: {result.value.status}</>;
225
+ }
226
+ ```
227
+
228
+ ### Patch Changes
229
+
230
+ - Updated dependencies [[`a2588116`](https://github.com/latticexyz/mud/commit/a25881160cb3283e11d218be7b8a9fe38ee83062), [`48c51b52`](https://github.com/latticexyz/mud/commit/48c51b52acab147a2ed97903c43bafa9b6769473)]:
231
+ - @latticexyz/store@2.0.0-next.2
232
+ - @latticexyz/store-cache@2.0.0-next.2
233
+ - @latticexyz/recs@2.0.0-next.2
234
+
235
+ ## 2.0.0-next.1
236
+
237
+ ### Patch Changes
238
+
239
+ - Updated dependencies [[`c963b46c`](https://github.com/latticexyz/mud/commit/c963b46c7eaceebc652930936643365b8c48a021), [`5c965a91`](https://github.com/latticexyz/mud/commit/5c965a919355bf98d7ea69463890fe605bcde206), [`60cfd089`](https://github.com/latticexyz/mud/commit/60cfd089fc7a17b98864b631d265f36718df35a9), [`afdba793`](https://github.com/latticexyz/mud/commit/afdba793fd84abf17eef5ef59dd56fabe353c8bd), [`cc2c8da0`](https://github.com/latticexyz/mud/commit/cc2c8da000c32c02a82a1a0fd17075d11eac56c3)]:
240
+ - @latticexyz/store@2.0.0-next.1
241
+ - @latticexyz/recs@2.0.0-next.1
242
+ - @latticexyz/store-cache@2.0.0-next.1
243
+
244
+ ## 2.0.0-next.0
245
+
246
+ ### Patch Changes
247
+
248
+ - Updated dependencies [[`904fd7d4`](https://github.com/latticexyz/mud/commit/904fd7d4ee06a86e481e3e02fd5744224376d0c9), [`8d51a034`](https://github.com/latticexyz/mud/commit/8d51a03486bc20006d8cc982f798dfdfe16f169f), [`1e2ad78e`](https://github.com/latticexyz/mud/commit/1e2ad78e277b551dd1b8efb0e4438fb10441644c), [`48909d15`](https://github.com/latticexyz/mud/commit/48909d151b3dfceab128c120bc6bb77de53c456b), [`66cc35a8`](https://github.com/latticexyz/mud/commit/66cc35a8ccb21c50a1882d6c741dd045acd8bc11), [`a7b30c79`](https://github.com/latticexyz/mud/commit/a7b30c79bcc78530d2d01858de46a0fb87954fda), [`53522998`](https://github.com/latticexyz/mud/commit/535229984565539e6168042150b45fe0f9b48b0f)]:
249
+ - @latticexyz/store@2.0.0-next.0
250
+ - @latticexyz/recs@2.0.0-next.0
251
+ - @latticexyz/store-cache@2.0.0-next.0
252
+
3
253
  All notable changes to this project will be documented in this file.
4
254
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
255
 
256
+ # [1.42.0](https://github.com/latticexyz/mud/compare/v1.41.0...v1.42.0) (2023-04-13)
257
+
258
+ ### Features
259
+
260
+ - v2 event decoding ([#415](https://github.com/latticexyz/mud/issues/415)) ([374ed54](https://github.com/latticexyz/mud/commit/374ed542c3387a4ec2b36ab68ae534419aa58763))
261
+
6
262
  # [1.41.0](https://github.com/latticexyz/mud/compare/v1.40.0...v1.41.0) (2023-03-09)
7
263
 
8
264
  ### Features
package/README.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  React hooks (and more) for building MUD clients.
4
4
 
5
+ ## Hooks for `recs`
6
+
5
7
  ### useComponentValue
6
8
 
7
9
  Returns the value of the component for the entity, and triggers a re-render as the component is added/removed/updated.
8
10
 
9
- ```
11
+ ```typescript
10
12
  const position = useComponentValue(Position, entity);
11
13
  ```
12
14
 
@@ -14,7 +16,7 @@ const position = useComponentValue(Position, entity);
14
16
 
15
17
  Returns all matching `EntityIndex`es for a given entity query, and triggers a re-render as new query results come in.
16
18
 
17
- ```
19
+ ```typescript
18
20
  const entities = useEntityQuery([Has(Position)]);
19
21
  const playersAtPosition = useEntityQuery([Has(Player), HasValue(Position, { x: 0, y: 0 })]);
20
22
  ```
package/dist/index.js CHANGED
@@ -1,128 +1,2 @@
1
- import { getComponentValue, defineQuery, Has, isComponentUpdate } from '@latticexyz/recs';
2
- import { useState, useEffect, useMemo } from 'react';
3
- import { map, distinctUntilChanged } from 'rxjs';
4
-
5
- function useComponentValue(component, entityIndex, defaultValue) {
6
- const [value, setValue] = useState(entityIndex != null ? getComponentValue(component, entityIndex) : undefined);
7
- useEffect(() => {
8
- // component or entityIndex changed, update state to latest value
9
- setValue(entityIndex != null ? getComponentValue(component, entityIndex) : undefined);
10
- if (entityIndex == null)
11
- return;
12
- const queryResult = defineQuery([Has(component)], { runOnInit: false });
13
- const subscription = queryResult.update$.subscribe((update) => {
14
- if (isComponentUpdate(update, component) && update.entity === entityIndex) {
15
- const [nextValue] = update.value;
16
- setValue(nextValue);
17
- }
18
- });
19
- return () => subscription.unsubscribe();
20
- }, [component, entityIndex]);
21
- return value ?? defaultValue;
22
- }
23
-
24
- /** @deprecated See https://github.com/latticexyz/mud/issues/339 */
25
- const useDeprecatedComputedValue = (computedValue) => {
26
- const [value, setValue] = useState(computedValue.get());
27
- useEffect(() => {
28
- const unsubscribe = computedValue.observe_(() => setValue(computedValue.get()));
29
- return () => unsubscribe();
30
- }, [computedValue]);
31
- return value;
32
- };
33
-
34
- // do not edit .js files directly - edit src/index.jst
35
-
36
-
37
-
38
- var fastDeepEqual = function equal(a, b) {
39
- if (a === b) return true;
40
-
41
- if (a && b && typeof a == 'object' && typeof b == 'object') {
42
- if (a.constructor !== b.constructor) return false;
43
-
44
- var length, i, keys;
45
- if (Array.isArray(a)) {
46
- length = a.length;
47
- if (length != b.length) return false;
48
- for (i = length; i-- !== 0;)
49
- if (!equal(a[i], b[i])) return false;
50
- return true;
51
- }
52
-
53
-
54
-
55
- if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
56
- if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
57
- if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
58
-
59
- keys = Object.keys(a);
60
- length = keys.length;
61
- if (length !== Object.keys(b).length) return false;
62
-
63
- for (i = length; i-- !== 0;)
64
- if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
65
-
66
- for (i = length; i-- !== 0;) {
67
- var key = keys[i];
68
-
69
- if (!equal(a[key], b[key])) return false;
70
- }
71
-
72
- return true;
73
- }
74
-
75
- // true if both NaN, false otherwise
76
- return a!==a && b!==b;
77
- };
78
-
79
- const useDeepMemo = (currentValue) => {
80
- const [stableValue, setStableValue] = useState(currentValue);
81
- useEffect(() => {
82
- if (!fastDeepEqual(currentValue, stableValue)) {
83
- setStableValue(currentValue);
84
- }
85
- // eslint-disable-next-line react-hooks/exhaustive-deps
86
- }, [currentValue]);
87
- return stableValue;
88
- };
89
-
90
- // This does a little more rendering than is necessary when arguments change,
91
- // but at least it's giving correct results now. Will optimize later!
92
- /**
93
- * Returns all matching `EntityIndex`es for a given entity query,
94
- * and triggers a re-render as new query results come in.
95
- *
96
- * @param fragments Query fragments to match against, executed from left to right.
97
- * @param options.updateOnValueChange False - re-renders only on entity array changes. True (default) - also on component value changes.
98
- * @returns Set of entities matching the query fragments.
99
- */
100
- function useEntityQuery(fragments, options) {
101
- const updateOnValueChange = options?.updateOnValueChange ?? true;
102
- const stableFragments = useDeepMemo(fragments);
103
- const query = useMemo(() => defineQuery(stableFragments, { runOnInit: true }), [stableFragments]);
104
- const [entities, setEntities] = useState([...query.matching]);
105
- useEffect(() => {
106
- setEntities([...query.matching]);
107
- let observable = query.update$.pipe(map(() => [...query.matching]));
108
- if (!updateOnValueChange) {
109
- // re-render only on entity array changes
110
- observable = observable.pipe(distinctUntilChanged((a, b) => fastDeepEqual(a, b)));
111
- }
112
- const subscription = observable.subscribe((entities) => setEntities(entities));
113
- return () => subscription.unsubscribe();
114
- }, [query, updateOnValueChange]);
115
- return entities;
116
- }
117
-
118
- function useObservableValue(observable, defaultValue) {
119
- const [value, setValue] = useState(defaultValue);
120
- useEffect(() => {
121
- const subscription = observable.subscribe(setValue);
122
- return () => subscription.unsubscribe();
123
- }, [observable]);
124
- return value;
125
- }
126
-
127
- export { useComponentValue, useDeprecatedComputedValue, useEntityQuery, useObservableValue };
128
- //# sourceMappingURL=index.js.map
1
+ import{defineQuery as b,getComponentValue as f,Has as d,isComponentUpdate as S}from"@latticexyz/recs";import{useEffect as C,useState as T}from"react";function H(e,t,n){let[s,u]=T(t!=null?f(e,t):void 0);return C(()=>{if(u(t!=null?f(e,t):void 0),t==null)return;let r=b([d(e)],{runOnInit:!1}).update$.subscribe(o=>{if(S(o,e)&&o.entity===t){let[a]=o.value;u(a)}});return()=>r.unsubscribe()},[e,t]),s??n}import{useEffect as x,useState as V}from"react";var z=e=>{let[t,n]=V(e.get());return x(()=>{let s=e.observe_(()=>n(e.get()));return()=>s()},[e]),t};import{defineQuery as h}from"@latticexyz/recs";import{useEffect as y,useMemo as O,useState as R}from"react";import{useEffect as g,useState as v}from"react";import E from"fast-deep-equal";var m=e=>{let[t,n]=v(e);return g(()=>{E(e,t)||n(e)},[e]),t};import P from"fast-deep-equal";import{distinctUntilChanged as q,map as Q}from"rxjs";function te(e,t){let n=t?.updateOnValueChange??!0,s=m(e),u=O(()=>h(s,{runOnInit:!0}),[s]),[l,r]=R([...u.matching]);return y(()=>{r([...u.matching]);let o=u.update$.pipe(Q(()=>[...u.matching]));n||(o=o.pipe(q((i,c)=>P(i,c))));let a=o.subscribe(i=>r(i));return()=>a.unsubscribe()},[u,n]),l}import{useEffect as I,useState as U}from"react";function se(e,t){let[n,s]=U(t);return I(()=>{let u=e.subscribe(s);return()=>u.unsubscribe()},[e]),n}import{useEffect as p,useRef as D,useState as F}from"react";function ae(e){let t=D(e),[n,s]=F(e==null?{status:"idle"}:{status:"pending"});return p(()=>{e!==t.current&&(t.current=e,s(e==null?{status:"idle"}:{status:"pending"}))},[e]),p(()=>{e!=null&&Promise.allSettled([e]).then(([u])=>{e===t.current&&s(u)})},[e]),n}export{H as useComponentValue,z as useDeprecatedComputedValue,te as useEntityQuery,se as useObservableValue,ae as usePromise};
2
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/useComponentValue.ts","../src/useDeprecatedComputedValue.ts","../../../node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js","../src/utils/useDeepMemo.ts","../src/useEntityQuery.ts","../src/useObservableValue.ts"],"sourcesContent":[null,null,"'use strict';\n\n// do not edit .js files directly - edit src/index.jst\n\n\n\nmodule.exports = function equal(a, b) {\n if (a === b) return true;\n\n if (a && b && typeof a == 'object' && typeof b == 'object') {\n if (a.constructor !== b.constructor) return false;\n\n var length, i, keys;\n if (Array.isArray(a)) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (!equal(a[i], b[i])) return false;\n return true;\n }\n\n\n\n if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;\n if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();\n if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();\n\n keys = Object.keys(a);\n length = keys.length;\n if (length !== Object.keys(b).length) return false;\n\n for (i = length; i-- !== 0;)\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\n\n for (i = length; i-- !== 0;) {\n var key = keys[i];\n\n if (!equal(a[key], b[key])) return false;\n }\n\n return true;\n }\n\n // true if both NaN, false otherwise\n return a!==a && b!==b;\n};\n",null,null,null],"names":["isEqual"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/useComponentValue.ts","../src/useDeprecatedComputedValue.ts","../src/useEntityQuery.ts","../src/utils/useDeepMemo.ts","../src/useObservableValue.ts","../src/usePromise.ts"],"sourcesContent":["import {\n Component,\n ComponentValue,\n defineQuery,\n Entity,\n getComponentValue,\n Has,\n isComponentUpdate,\n Schema,\n} from \"@latticexyz/recs\";\nimport { useEffect, useState } from \"react\";\n\nexport function useComponentValue<S extends Schema>(\n component: Component<S>,\n entity: Entity | undefined,\n defaultValue: ComponentValue<S>\n): ComponentValue<S>;\n\nexport function useComponentValue<S extends Schema>(\n component: Component<S>,\n entity: Entity | undefined\n): ComponentValue<S> | undefined;\n\nexport function useComponentValue<S extends Schema>(\n component: Component<S>,\n entity: Entity | undefined,\n defaultValue?: ComponentValue<S>\n) {\n const [value, setValue] = useState(entity != null ? getComponentValue(component, entity) : undefined);\n\n useEffect(() => {\n // component or entity changed, update state to latest value\n setValue(entity != null ? getComponentValue(component, entity) : undefined);\n if (entity == null) return;\n\n const queryResult = defineQuery([Has(component)], { runOnInit: false });\n const subscription = queryResult.update$.subscribe((update) => {\n if (isComponentUpdate(update, component) && update.entity === entity) {\n const [nextValue] = update.value;\n setValue(nextValue);\n }\n });\n return () => subscription.unsubscribe();\n }, [component, entity]);\n\n return value ?? defaultValue;\n}\n","import { IComputedValue } from \"mobx\";\nimport { useEffect, useState } from \"react\";\n\n/** @deprecated See https://github.com/latticexyz/mud/issues/339 */\nexport const useDeprecatedComputedValue = <T>(computedValue: IComputedValue<T> & { observe_: any }) => {\n const [value, setValue] = useState<T>(computedValue.get());\n\n useEffect(() => {\n const unsubscribe = computedValue.observe_(() => setValue(computedValue.get()));\n return () => unsubscribe();\n }, [computedValue]);\n\n return value;\n};\n","import { defineQuery, QueryFragment } from \"@latticexyz/recs\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useDeepMemo } from \"./utils/useDeepMemo\";\nimport isEqual from \"fast-deep-equal\";\nimport { distinctUntilChanged, map } from \"rxjs\";\n\n// This does a little more rendering than is necessary when arguments change,\n// but at least it's giving correct results now. Will optimize later!\n\n/**\n * Returns all matching entities for a given entity query,\n * and triggers a re-render as new query results come in.\n *\n * @param fragments Query fragments to match against, executed from left to right.\n * @param options.updateOnValueChange False - re-renders only on entity array changes. True (default) - also on component value changes.\n * @returns Set of entities matching the query fragments.\n */\nexport function useEntityQuery(fragments: QueryFragment[], options?: { updateOnValueChange?: boolean }) {\n const updateOnValueChange = options?.updateOnValueChange ?? true;\n\n const stableFragments = useDeepMemo(fragments);\n const query = useMemo(() => defineQuery(stableFragments, { runOnInit: true }), [stableFragments]);\n const [entities, setEntities] = useState([...query.matching]);\n\n useEffect(() => {\n setEntities([...query.matching]);\n let observable = query.update$.pipe(map(() => [...query.matching]));\n if (!updateOnValueChange) {\n // re-render only on entity array changes\n observable = observable.pipe(distinctUntilChanged((a, b) => isEqual(a, b)));\n }\n const subscription = observable.subscribe((entities) => setEntities(entities));\n return () => subscription.unsubscribe();\n }, [query, updateOnValueChange]);\n\n return entities;\n}\n","import { useEffect, useState } from \"react\";\nimport isEqual from \"fast-deep-equal\";\n\nexport const useDeepMemo = <T>(currentValue: T): T => {\n const [stableValue, setStableValue] = useState(currentValue);\n\n useEffect(() => {\n if (!isEqual(currentValue, stableValue)) {\n setStableValue(currentValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentValue]);\n\n return stableValue;\n};\n","import { useEffect, useState } from \"react\";\nimport { Observable } from \"rxjs\";\n\nexport function useObservableValue<T>(observable: Observable<T>, defaultValue: T): T;\n\nexport function useObservableValue<T>(observable: Observable<T>): T | undefined;\n\nexport function useObservableValue<T>(observable: Observable<T>, defaultValue?: T) {\n const [value, setValue] = useState(defaultValue);\n\n useEffect(() => {\n const subscription = observable.subscribe(setValue);\n return () => subscription.unsubscribe();\n }, [observable]);\n\n return value;\n}\n","import { useEffect, useRef, useState } from \"react\";\n\n// TODO: narrow type so `null`/`undefined` always return `{status: \"idle\"}`?\n\nexport type UsePromiseResult<T> = PromiseSettledResult<Awaited<T>> | { status: \"pending\" } | { status: \"idle\" };\n\nexport function usePromise<T>(promise: PromiseLike<T> | null | undefined) {\n const promiseRef = useRef(promise);\n const [result, setResult] = useState<UsePromiseResult<T>>(\n promise == null ? { status: \"idle\" } : { status: \"pending\" }\n );\n\n useEffect(() => {\n if (promise !== promiseRef.current) {\n promiseRef.current = promise;\n setResult(promise == null ? { status: \"idle\" } : { status: \"pending\" });\n }\n }, [promise]);\n\n useEffect(() => {\n if (promise == null) return;\n // TODO: do we need to check if result is already populated?\n Promise.allSettled([promise]).then(([settled]) => {\n if (promise === promiseRef.current) {\n setResult(settled);\n }\n });\n }, [promise]);\n\n return result;\n}\n"],"mappings":"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","names":["defineQuery","getComponentValue","Has","isComponentUpdate","useEffect","useState","useComponentValue","component","entity","defaultValue","value","setValue","subscription","update","nextValue","useEffect","useState","useDeprecatedComputedValue","computedValue","value","setValue","unsubscribe","defineQuery","useEffect","useMemo","useState","useEffect","useState","isEqual","useDeepMemo","currentValue","stableValue","setStableValue","isEqual","distinctUntilChanged","map","useEntityQuery","fragments","options","updateOnValueChange","stableFragments","useDeepMemo","query","useMemo","defineQuery","entities","setEntities","useState","useEffect","observable","a","b","subscription","useEffect","useState","useObservableValue","observable","defaultValue","value","setValue","subscription","useEffect","useRef","useState","usePromise","promise","promiseRef","result","setResult","settled"]}
package/package.json CHANGED
@@ -1,57 +1,46 @@
1
1
  {
2
2
  "name": "@latticexyz/react",
3
- "version": "2.0.0-alpha.94+010740d0",
3
+ "version": "2.0.0-foundry-js-c7b0289b",
4
4
  "description": "React tools for MUD client.",
5
- "license": "MIT",
6
- "source": "src/index.ts",
7
- "main": "dist/index.js",
8
5
  "repository": {
9
6
  "type": "git",
10
7
  "url": "https://github.com/latticexyz/mud.git",
11
8
  "directory": "packages/react"
12
9
  },
13
- "scripts": {
14
- "prepare": "pnpm build",
15
- "docs": "rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml",
16
- "test": "tsc --noEmit && jest",
17
- "prepack": "mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ",
18
- "postpack": "mv package.json.bak package.json || echo 'no package.json.bak'",
19
- "build": "rimraf dist && rollup -c rollup.config.js",
20
- "release": "npm publish --access=public"
21
- },
22
- "peerDependencies": {
23
- "@latticexyz/recs": "latest",
24
- "mobx": "^6.4.2",
25
- "react": "^18.2.0",
26
- "rxjs": "^7.5.5"
10
+ "license": "MIT",
11
+ "type": "module",
12
+ "exports": {
13
+ ".": "./dist/index.js"
27
14
  },
15
+ "types": "src/index.ts",
28
16
  "dependencies": {
29
- "fast-deep-equal": "^3.1.3"
17
+ "fast-deep-equal": "^3.1.3",
18
+ "mobx": "^6.7.0",
19
+ "react": "^18.2.0",
20
+ "rxjs": "7.5.5",
21
+ "@latticexyz/recs": "2.0.0-foundry-js-c7b0289b",
22
+ "@latticexyz/store": "2.0.0-foundry-js-c7b0289b"
30
23
  },
31
24
  "devDependencies": {
32
- "@latticexyz/recs": "2.0.0-alpha.94+010740d0",
33
- "@rollup/plugin-json": "^4.1.0",
34
- "@rollup/plugin-node-resolve": "^13.1.3",
35
- "@rollup/plugin-typescript": "^11.0.0",
36
25
  "@testing-library/react-hooks": "^8.0.1",
37
- "@types/jest": "^27.4.1",
38
- "@types/react": "^18.0.12",
39
- "eslint-plugin-react": "^7.31.11",
40
- "eslint-plugin-react-hooks": "^4.6.0",
41
- "jest": "^29.3.1",
42
- "mobx": "^6.4.2",
43
- "react": "^18.2.0",
26
+ "@types/react": "18.2.22",
27
+ "@vitejs/plugin-react": "^4.0.0",
28
+ "eslint-plugin-react": "7.31.11",
29
+ "eslint-plugin-react-hooks": "4.6.0",
30
+ "jsdom": "^22.1.0",
44
31
  "react-test-renderer": "^18.2.0",
45
- "rimraf": "^3.0.2",
46
- "rollup": "^2.69.0",
47
- "rollup-plugin-commonjs": "^10.1.0",
48
- "rollup-plugin-peer-deps-external": "^2.2.4",
49
- "rxjs": "^7.5.5",
50
- "ts-jest": "^29.0.5",
51
- "tslib": "^2.5.0",
52
- "typedoc": "0.23.21",
53
- "typedoc-plugin-markdown": "^3.13.6",
54
- "typescript": "^4.9.5"
32
+ "tsup": "^6.7.0",
33
+ "vite": "^4.3.6",
34
+ "vitest": "0.31.4"
55
35
  },
56
- "gitHead": "010740d09d40d4ff6d95538d498a513fbb65ca45"
57
- }
36
+ "gitHead": "914a1e0ae4a573d685841ca2ea921435057deb8f",
37
+ "scripts": {
38
+ "build": "pnpm run build:js",
39
+ "build:js": "tsup",
40
+ "clean": "pnpm run clean:js",
41
+ "clean:js": "rimraf dist",
42
+ "dev": "tsup --watch",
43
+ "test": "tsc --noEmit && vitest --run",
44
+ "test:ci": "pnpm run test"
45
+ }
46
+ }
@@ -2,3 +2,4 @@ export * from "./useComponentValue";
2
2
  export * from "./useDeprecatedComputedValue";
3
3
  export * from "./useEntityQuery";
4
4
  export * from "./useObservableValue";
5
+ export * from "./usePromise";
@@ -0,0 +1,89 @@
1
+ import { renderHook, act } from "@testing-library/react-hooks";
2
+ import {
3
+ World,
4
+ Type,
5
+ createWorld,
6
+ defineComponent,
7
+ Component,
8
+ createEntity,
9
+ withValue,
10
+ setComponent,
11
+ removeComponent,
12
+ } from "@latticexyz/recs";
13
+ import { useComponentValue } from "./useComponentValue";
14
+ import { describe, it, expect, beforeEach } from "vitest";
15
+
16
+ describe("useComponentValue", () => {
17
+ let world: World;
18
+ let Position: Component<{
19
+ x: Type.Number;
20
+ y: Type.Number;
21
+ }>;
22
+
23
+ beforeEach(() => {
24
+ world = createWorld();
25
+ Position = defineComponent(world, { x: Type.Number, y: Type.Number }, { id: "Position" });
26
+ });
27
+
28
+ it("should return Position value for entity", () => {
29
+ const entity = createEntity(world, [withValue(Position, { x: 1, y: 1 })]);
30
+
31
+ const { result } = renderHook(() => useComponentValue(Position, entity));
32
+ expect(result.current).toEqual({ x: 1, y: 1 });
33
+
34
+ act(() => {
35
+ setComponent(Position, entity, { x: 0, y: 0 });
36
+ });
37
+ expect(result.current).toEqual({ x: 0, y: 0 });
38
+
39
+ act(() => {
40
+ removeComponent(Position, entity);
41
+ });
42
+ expect(result.current).toBe(undefined);
43
+ });
44
+
45
+ it("should re-render only when Position changes for entity", () => {
46
+ const entity = createEntity(world, [withValue(Position, { x: 1, y: 1 })]);
47
+ const otherEntity = createEntity(world, [withValue(Position, { x: 2, y: 2 })]);
48
+
49
+ const { result } = renderHook(() => useComponentValue(Position, entity));
50
+ expect(result.all.length).toBe(2);
51
+ expect(result.current).toEqual({ x: 1, y: 1 });
52
+
53
+ act(() => {
54
+ setComponent(Position, entity, { x: 0, y: 0 });
55
+ });
56
+ expect(result.all.length).toBe(3);
57
+ expect(result.current).toEqual({ x: 0, y: 0 });
58
+
59
+ act(() => {
60
+ setComponent(Position, otherEntity, { x: 0, y: 0 });
61
+ removeComponent(Position, otherEntity);
62
+ });
63
+ expect(result.all.length).toBe(3);
64
+ expect(result.current).toEqual({ x: 0, y: 0 });
65
+
66
+ act(() => {
67
+ removeComponent(Position, entity);
68
+ });
69
+ expect(result.all.length).toBe(4);
70
+ expect(result.current).toBe(undefined);
71
+ });
72
+
73
+ it("should return default value when Position is not set", () => {
74
+ const entity = createEntity(world);
75
+
76
+ const { result } = renderHook(() => useComponentValue(Position, entity, { x: -1, y: -1 }));
77
+ expect(result.current).toEqual({ x: -1, y: -1 });
78
+
79
+ act(() => {
80
+ setComponent(Position, entity, { x: 0, y: 0 });
81
+ });
82
+ expect(result.current).toEqual({ x: 0, y: 0 });
83
+
84
+ act(() => {
85
+ removeComponent(Position, entity);
86
+ });
87
+ expect(result.current).toEqual({ x: -1, y: -1 });
88
+ });
89
+ });
@@ -0,0 +1,47 @@
1
+ import {
2
+ Component,
3
+ ComponentValue,
4
+ defineQuery,
5
+ Entity,
6
+ getComponentValue,
7
+ Has,
8
+ isComponentUpdate,
9
+ Schema,
10
+ } from "@latticexyz/recs";
11
+ import { useEffect, useState } from "react";
12
+
13
+ export function useComponentValue<S extends Schema>(
14
+ component: Component<S>,
15
+ entity: Entity | undefined,
16
+ defaultValue: ComponentValue<S>
17
+ ): ComponentValue<S>;
18
+
19
+ export function useComponentValue<S extends Schema>(
20
+ component: Component<S>,
21
+ entity: Entity | undefined
22
+ ): ComponentValue<S> | undefined;
23
+
24
+ export function useComponentValue<S extends Schema>(
25
+ component: Component<S>,
26
+ entity: Entity | undefined,
27
+ defaultValue?: ComponentValue<S>
28
+ ) {
29
+ const [value, setValue] = useState(entity != null ? getComponentValue(component, entity) : undefined);
30
+
31
+ useEffect(() => {
32
+ // component or entity changed, update state to latest value
33
+ setValue(entity != null ? getComponentValue(component, entity) : undefined);
34
+ if (entity == null) return;
35
+
36
+ const queryResult = defineQuery([Has(component)], { runOnInit: false });
37
+ const subscription = queryResult.update$.subscribe((update) => {
38
+ if (isComponentUpdate(update, component) && update.entity === entity) {
39
+ const [nextValue] = update.value;
40
+ setValue(nextValue);
41
+ }
42
+ });
43
+ return () => subscription.unsubscribe();
44
+ }, [component, entity]);
45
+
46
+ return value ?? defaultValue;
47
+ }
@@ -0,0 +1,14 @@
1
+ import { IComputedValue } from "mobx";
2
+ import { useEffect, useState } from "react";
3
+
4
+ /** @deprecated See https://github.com/latticexyz/mud/issues/339 */
5
+ export const useDeprecatedComputedValue = <T>(computedValue: IComputedValue<T> & { observe_: any }) => {
6
+ const [value, setValue] = useState<T>(computedValue.get());
7
+
8
+ useEffect(() => {
9
+ const unsubscribe = computedValue.observe_(() => setValue(computedValue.get()));
10
+ return () => unsubscribe();
11
+ }, [computedValue]);
12
+
13
+ return value;
14
+ };
@@ -0,0 +1,164 @@
1
+ import { renderHook, act } from "@testing-library/react-hooks";
2
+ import {
3
+ World,
4
+ Type,
5
+ createWorld,
6
+ defineComponent,
7
+ Component,
8
+ createEntity,
9
+ withValue,
10
+ Has,
11
+ setComponent,
12
+ HasValue,
13
+ removeComponent,
14
+ } from "@latticexyz/recs";
15
+ import { useEntityQuery } from "./useEntityQuery";
16
+ import { describe, beforeEach, it, expect } from "vitest";
17
+
18
+ describe("useEntityQuery", () => {
19
+ let world: World;
20
+ let Position: Component<{
21
+ x: Type.Number;
22
+ y: Type.Number;
23
+ }>;
24
+ let OwnedBy: Component<{ value: Type.Entity }>;
25
+
26
+ beforeEach(() => {
27
+ world = createWorld();
28
+ Position = defineComponent(world, { x: Type.Number, y: Type.Number }, { id: "Position" });
29
+ OwnedBy = defineComponent(world, { value: Type.Entity }, { id: "OwnedBy" });
30
+ });
31
+
32
+ it("should find entities with Position component", () => {
33
+ const entity1 = createEntity(world, [withValue(Position, { x: 1, y: 1 })]);
34
+ const entity2 = createEntity(world, [withValue(Position, { x: 2, y: 2 })]);
35
+ const entity3 = createEntity(world, []);
36
+
37
+ const { result } = renderHook(() => useEntityQuery([Has(Position)], { updateOnValueChange: false }));
38
+ const { result: resultOnValueChange } = renderHook(() =>
39
+ useEntityQuery([Has(Position)], { updateOnValueChange: true })
40
+ );
41
+
42
+ expect(result.current.length).toBe(2);
43
+ expect(result.current).toContain(entity1);
44
+ expect(result.current).toContain(entity2);
45
+ expect(result.current).not.toContain(entity3);
46
+ expect(resultOnValueChange.current).toEqual(result.current);
47
+
48
+ act(() => {
49
+ setComponent(Position, entity3, { x: 0, y: 0 });
50
+ });
51
+
52
+ expect(result.current.length).toBe(3);
53
+ expect(result.current).toContain(entity1);
54
+ expect(result.current).toContain(entity2);
55
+ expect(result.current).toContain(entity3);
56
+ expect(resultOnValueChange.current).toEqual(result.current);
57
+
58
+ act(() => {
59
+ removeComponent(Position, entity1);
60
+ removeComponent(Position, entity3);
61
+ });
62
+
63
+ expect(result.current.length).toBe(1);
64
+ expect(result.current).not.toContain(entity1);
65
+ expect(result.current).toContain(entity2);
66
+ expect(result.current).not.toContain(entity3);
67
+ expect(resultOnValueChange.current).toEqual(result.current);
68
+
69
+ act(() => {
70
+ removeComponent(Position, entity2);
71
+ });
72
+
73
+ expect(result.current.length).toBe(0);
74
+ });
75
+
76
+ it("should re-render only when Position changes", () => {
77
+ const entity1 = createEntity(world, [withValue(Position, { x: 1, y: 1 })]);
78
+ const entity2 = createEntity(world, [withValue(Position, { x: 2, y: 2 })]);
79
+ const entity3 = createEntity(world, []);
80
+
81
+ const { result } = renderHook(() => useEntityQuery([Has(Position)], { updateOnValueChange: false }));
82
+ const { result: resultOnValueChange } = renderHook(() =>
83
+ useEntityQuery([Has(Position)], { updateOnValueChange: true })
84
+ );
85
+
86
+ expect(result.all).toHaveLength(2);
87
+ expect(result.current).toHaveLength(2);
88
+ expect(result.current).toContain(entity1);
89
+ expect(result.current).toContain(entity2);
90
+ expect(result.current).not.toContain(entity3);
91
+
92
+ // Changing an entity's component value should NOT re-render,
93
+ // unless updateOnValueChange === true
94
+ act(() => {
95
+ setComponent(Position, entity2, { x: 0, y: 0 });
96
+ });
97
+
98
+ expect(result.all).toHaveLength(2);
99
+ expect(resultOnValueChange.all).toHaveLength(3);
100
+
101
+ // Changing a different component value should NOT re-render
102
+ act(() => {
103
+ setComponent(OwnedBy, entity2, { value: entity1 });
104
+ setComponent(OwnedBy, entity3, { value: entity1 });
105
+ });
106
+
107
+ expect(result.all).toHaveLength(2);
108
+ expect(resultOnValueChange.all).toHaveLength(3);
109
+
110
+ // Changing which entities have the component should re-render
111
+ act(() => {
112
+ setComponent(Position, entity3, { x: 0, y: 0 });
113
+ });
114
+
115
+ expect(result.all).toHaveLength(3);
116
+ expect(resultOnValueChange.all).toHaveLength(4);
117
+ expect(result.current).toHaveLength(3);
118
+ expect(result.current).toContain(entity1);
119
+ expect(result.current).toContain(entity2);
120
+ expect(result.current).toContain(entity3);
121
+
122
+ // Changing which entities have the component should re-render
123
+ act(() => {
124
+ removeComponent(Position, entity1);
125
+ });
126
+
127
+ expect(result.all).toHaveLength(4);
128
+ expect(resultOnValueChange.all).toHaveLength(5);
129
+ expect(result.current).toHaveLength(2);
130
+ expect(result.current).toContain(entity2);
131
+ expect(result.current).toContain(entity3);
132
+ });
133
+
134
+ it("should re-render as hook arguments change", () => {
135
+ // TODO: reduce re-renders during argument changes?
136
+
137
+ const entity1 = createEntity(world, [withValue(Position, { x: 1, y: 1 })]);
138
+ const entity2 = createEntity(world, [withValue(Position, { x: 2, y: 2 })]);
139
+ const entity3 = createEntity(world, [withValue(Position, { x: 2, y: 2 })]);
140
+
141
+ const { result, rerender } = renderHook(({ x, y }) => useEntityQuery([HasValue(Position, { x, y })]), {
142
+ initialProps: { x: 1, y: 1 },
143
+ });
144
+
145
+ expect(result.all).toHaveLength(2);
146
+ expect(result.current).toHaveLength(1);
147
+ expect(result.current).toContain(entity1);
148
+
149
+ rerender({ x: 1, y: 1 });
150
+ expect(result.all).toHaveLength(3);
151
+ expect(result.current).toHaveLength(1);
152
+ expect(result.current).toContain(entity1);
153
+
154
+ rerender({ x: 2, y: 2 });
155
+ expect(result.all).toHaveLength(6);
156
+ expect(result.current).toHaveLength(2);
157
+ expect(result.current).toContain(entity2);
158
+ expect(result.current).toContain(entity3);
159
+
160
+ rerender({ x: -1, y: -1 });
161
+ expect(result.all).toHaveLength(9);
162
+ expect(result.current).toHaveLength(0);
163
+ });
164
+ });
@@ -0,0 +1,37 @@
1
+ import { defineQuery, QueryFragment } from "@latticexyz/recs";
2
+ import { useEffect, useMemo, useState } from "react";
3
+ import { useDeepMemo } from "./utils/useDeepMemo";
4
+ import isEqual from "fast-deep-equal";
5
+ import { distinctUntilChanged, map } from "rxjs";
6
+
7
+ // This does a little more rendering than is necessary when arguments change,
8
+ // but at least it's giving correct results now. Will optimize later!
9
+
10
+ /**
11
+ * Returns all matching entities for a given entity query,
12
+ * and triggers a re-render as new query results come in.
13
+ *
14
+ * @param fragments Query fragments to match against, executed from left to right.
15
+ * @param options.updateOnValueChange False - re-renders only on entity array changes. True (default) - also on component value changes.
16
+ * @returns Set of entities matching the query fragments.
17
+ */
18
+ export function useEntityQuery(fragments: QueryFragment[], options?: { updateOnValueChange?: boolean }) {
19
+ const updateOnValueChange = options?.updateOnValueChange ?? true;
20
+
21
+ const stableFragments = useDeepMemo(fragments);
22
+ const query = useMemo(() => defineQuery(stableFragments, { runOnInit: true }), [stableFragments]);
23
+ const [entities, setEntities] = useState([...query.matching]);
24
+
25
+ useEffect(() => {
26
+ setEntities([...query.matching]);
27
+ let observable = query.update$.pipe(map(() => [...query.matching]));
28
+ if (!updateOnValueChange) {
29
+ // re-render only on entity array changes
30
+ observable = observable.pipe(distinctUntilChanged((a, b) => isEqual(a, b)));
31
+ }
32
+ const subscription = observable.subscribe((entities) => setEntities(entities));
33
+ return () => subscription.unsubscribe();
34
+ }, [query, updateOnValueChange]);
35
+
36
+ return entities;
37
+ }
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from "react";
2
+ import { Observable } from "rxjs";
3
+
4
+ export function useObservableValue<T>(observable: Observable<T>, defaultValue: T): T;
5
+
6
+ export function useObservableValue<T>(observable: Observable<T>): T | undefined;
7
+
8
+ export function useObservableValue<T>(observable: Observable<T>, defaultValue?: T) {
9
+ const [value, setValue] = useState(defaultValue);
10
+
11
+ useEffect(() => {
12
+ const subscription = observable.subscribe(setValue);
13
+ return () => subscription.unsubscribe();
14
+ }, [observable]);
15
+
16
+ return value;
17
+ }
@@ -0,0 +1,31 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+
3
+ // TODO: narrow type so `null`/`undefined` always return `{status: "idle"}`?
4
+
5
+ export type UsePromiseResult<T> = PromiseSettledResult<Awaited<T>> | { status: "pending" } | { status: "idle" };
6
+
7
+ export function usePromise<T>(promise: PromiseLike<T> | null | undefined) {
8
+ const promiseRef = useRef(promise);
9
+ const [result, setResult] = useState<UsePromiseResult<T>>(
10
+ promise == null ? { status: "idle" } : { status: "pending" }
11
+ );
12
+
13
+ useEffect(() => {
14
+ if (promise !== promiseRef.current) {
15
+ promiseRef.current = promise;
16
+ setResult(promise == null ? { status: "idle" } : { status: "pending" });
17
+ }
18
+ }, [promise]);
19
+
20
+ useEffect(() => {
21
+ if (promise == null) return;
22
+ // TODO: do we need to check if result is already populated?
23
+ Promise.allSettled([promise]).then(([settled]) => {
24
+ if (promise === promiseRef.current) {
25
+ setResult(settled);
26
+ }
27
+ });
28
+ }, [promise]);
29
+
30
+ return result;
31
+ }
@@ -0,0 +1,15 @@
1
+ import { useEffect, useState } from "react";
2
+ import isEqual from "fast-deep-equal";
3
+
4
+ export const useDeepMemo = <T>(currentValue: T): T => {
5
+ const [stableValue, setStableValue] = useState(currentValue);
6
+
7
+ useEffect(() => {
8
+ if (!isEqual(currentValue, stableValue)) {
9
+ setStableValue(currentValue);
10
+ }
11
+ // eslint-disable-next-line react-hooks/exhaustive-deps
12
+ }, [currentValue]);
13
+
14
+ return stableValue;
15
+ };
@@ -0,0 +1,23 @@
1
+ import { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from "react";
2
+
3
+ /**
4
+ * Use in place of useState when the component may be unmounted before the state is updated.
5
+ */
6
+ export function useMountedState<T>(initialState: T | (() => T)): [T, Dispatch<SetStateAction<T>>] {
7
+ const [state, setState] = useState<T>(initialState);
8
+ const mountedRef = useRef(false);
9
+ useEffect(() => {
10
+ mountedRef.current = true;
11
+ return () => {
12
+ mountedRef.current = false;
13
+ };
14
+ });
15
+ const mountedSetState: typeof setState = useCallback((...args) => {
16
+ if (mountedRef.current) {
17
+ setState(...args);
18
+ } else {
19
+ console.warn("Ignoring `setState` call because component unmounted", ...args);
20
+ }
21
+ }, []);
22
+ return [state, mountedSetState];
23
+ }
@@ -1,3 +0,0 @@
1
- import { Component, ComponentValue, EntityIndex, Metadata, Schema } from "@latticexyz/recs";
2
- export declare function useComponentValue<S extends Schema>(component: Component<S, Metadata, undefined>, entityIndex: EntityIndex | undefined, defaultValue: ComponentValue<S>): ComponentValue<S>;
3
- export declare function useComponentValue<S extends Schema>(component: Component<S, Metadata, undefined>, entityIndex: EntityIndex | undefined): ComponentValue<S> | undefined;
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- import { IComputedValue } from "mobx";
2
- /** @deprecated See https://github.com/latticexyz/mud/issues/339 */
3
- export declare const useDeprecatedComputedValue: <T>(computedValue: IComputedValue<T> & {
4
- observe_: any;
5
- }) => T;
@@ -1,12 +0,0 @@
1
- import { QueryFragment } from "@latticexyz/recs";
2
- /**
3
- * Returns all matching `EntityIndex`es for a given entity query,
4
- * and triggers a re-render as new query results come in.
5
- *
6
- * @param fragments Query fragments to match against, executed from left to right.
7
- * @param options.updateOnValueChange False - re-renders only on entity array changes. True (default) - also on component value changes.
8
- * @returns Set of entities matching the query fragments.
9
- */
10
- export declare function useEntityQuery(fragments: QueryFragment[], options?: {
11
- updateOnValueChange?: boolean;
12
- }): import("@latticexyz/recs").EntityIndex[];
@@ -1 +0,0 @@
1
- export {};
@@ -1,3 +0,0 @@
1
- import { Observable } from "rxjs";
2
- export declare function useObservableValue<T>(observable: Observable<T>, defaultValue: T): T;
3
- export declare function useObservableValue<T>(observable: Observable<T>): T | undefined;
@@ -1 +0,0 @@
1
- export declare const useDeepMemo: <T>(currentValue: T) => T;