@dxos/react-hooks 0.8.4-main.f9ba587 → 0.8.4-main.fffef41

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.
Files changed (58) hide show
  1. package/dist/lib/browser/index.mjs +195 -129
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +195 -129
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/index.d.ts +4 -3
  8. package/dist/types/src/index.d.ts.map +1 -1
  9. package/dist/types/src/useAsyncEffect.d.ts +5 -29
  10. package/dist/types/src/useAsyncEffect.d.ts.map +1 -1
  11. package/dist/types/src/useControlledState.d.ts +2 -1
  12. package/dist/types/src/useControlledState.d.ts.map +1 -1
  13. package/dist/types/src/useDebugDeps.d.ts +6 -0
  14. package/dist/types/src/useDebugDeps.d.ts.map +1 -0
  15. package/dist/types/src/useDynamicRef.d.ts +6 -1
  16. package/dist/types/src/useDynamicRef.d.ts.map +1 -1
  17. package/dist/types/src/useForwardedRef.d.ts +23 -3
  18. package/dist/types/src/useForwardedRef.d.ts.map +1 -1
  19. package/dist/types/src/useIsFocused.d.ts +1 -1
  20. package/dist/types/src/useIsFocused.d.ts.map +1 -1
  21. package/dist/types/src/useMediaQuery.d.ts +1 -1
  22. package/dist/types/src/useMediaQuery.d.ts.map +1 -1
  23. package/dist/types/src/useMulticastObservable.test.d.ts.map +1 -1
  24. package/dist/types/src/useSignals.d.ts +10 -0
  25. package/dist/types/src/useSignals.d.ts.map +1 -0
  26. package/dist/types/src/useTimeout.d.ts +2 -1
  27. package/dist/types/src/useTimeout.d.ts.map +1 -1
  28. package/dist/types/src/useTransitions.d.ts +2 -1
  29. package/dist/types/src/useTransitions.d.ts.map +1 -1
  30. package/dist/types/src/useViewportResize.d.ts +3 -0
  31. package/dist/types/src/useViewportResize.d.ts.map +1 -0
  32. package/dist/types/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +12 -9
  34. package/src/index.ts +5 -3
  35. package/src/useAsyncEffect.ts +19 -49
  36. package/src/useControlledState.ts +22 -11
  37. package/src/useDebugDeps.ts +26 -0
  38. package/src/useDefaultValue.ts +1 -1
  39. package/src/useDynamicRef.ts +27 -5
  40. package/src/useForwardedRef.ts +48 -13
  41. package/src/useIsFocused.ts +2 -2
  42. package/src/useMediaQuery.ts +8 -9
  43. package/src/{useMulticastObservable.test.tsx → useMulticastObservable.test.ts} +1 -3
  44. package/src/useSignals.ts +27 -0
  45. package/src/useTimeout.ts +28 -3
  46. package/src/useTransitions.ts +4 -2
  47. package/src/{useResize.ts → useViewportResize.ts} +1 -1
  48. package/dist/types/src/useAsyncEffect.test.d.ts +0 -2
  49. package/dist/types/src/useAsyncEffect.test.d.ts.map +0 -1
  50. package/dist/types/src/useDebugReactDeps.d.ts +0 -6
  51. package/dist/types/src/useDebugReactDeps.d.ts.map +0 -1
  52. package/dist/types/src/useResize.d.ts +0 -3
  53. package/dist/types/src/useResize.d.ts.map +0 -1
  54. package/dist/types/src/useTrackProps.d.ts +0 -5
  55. package/dist/types/src/useTrackProps.d.ts.map +0 -1
  56. package/src/useAsyncEffect.test.tsx +0 -51
  57. package/src/useDebugReactDeps.ts +0 -27
  58. package/src/useTrackProps.ts +0 -40
@@ -1,26 +1,20 @@
1
1
  // src/useAsyncEffect.ts
2
2
  import { useEffect } from "react";
3
- import { log } from "@dxos/log";
4
- var useAsyncEffect = (callback, destructor, deps) => {
5
- const [effectDestructor, effectDeps] = typeof destructor === "function" ? [
6
- destructor,
7
- deps
8
- ] : [
9
- void 0,
10
- destructor
11
- ];
3
+ var useAsyncEffect = (cb, deps) => {
12
4
  useEffect(() => {
13
- let mounted = true;
14
- let value;
15
- const asyncResult = callback(() => mounted);
16
- void Promise.resolve(asyncResult).then((result) => {
17
- value = result;
18
- }).catch(log.catch);
5
+ const controller = new AbortController();
6
+ let cleanup;
7
+ const t = setTimeout(async () => {
8
+ if (!controller.signal.aborted) {
9
+ cleanup = await cb(controller);
10
+ }
11
+ });
19
12
  return () => {
20
- mounted = false;
21
- effectDestructor?.(value);
13
+ clearTimeout(t);
14
+ controller.abort();
15
+ cleanup?.();
22
16
  };
23
- }, effectDeps);
17
+ }, deps ?? []);
24
18
  };
25
19
 
26
20
  // src/useAsyncState.ts
@@ -47,43 +41,85 @@ var useAsyncState = (cb, deps = []) => {
47
41
  };
48
42
 
49
43
  // src/useControlledState.ts
50
- import { useEffect as useEffect3, useState as useState2 } from "react";
51
- var useControlledState = (controlledValue, onChange, ...deps) => {
52
- const [value, setValue] = useState2(controlledValue);
53
- useEffect3(() => {
54
- if (controlledValue !== void 0) {
55
- setValue(controlledValue);
44
+ import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2, useState as useState3 } from "react";
45
+
46
+ // src/useDynamicRef.ts
47
+ import { useCallback } from "@preact-signals/safe-react/react";
48
+ import { useEffect as useEffect3, useRef, useState as useState2 } from "react";
49
+ var useStateWithRef = (valueParam) => {
50
+ const [value, setValue] = useState2(valueParam);
51
+ const valueRef = useRef(valueParam);
52
+ const setter = useCallback((value2) => {
53
+ if (typeof value2 === "function") {
54
+ setValue((current) => {
55
+ valueRef.current = value2(current);
56
+ return valueRef.current;
57
+ });
58
+ } else {
59
+ valueRef.current = value2;
60
+ setValue(value2);
56
61
  }
62
+ }, []);
63
+ return [
64
+ value,
65
+ setter,
66
+ valueRef
67
+ ];
68
+ };
69
+ var useDynamicRef = (value) => {
70
+ const valueRef = useRef(value);
71
+ useEffect3(() => {
72
+ valueRef.current = value;
57
73
  }, [
58
- controlledValue,
59
- ...deps
74
+ value
60
75
  ]);
61
- useEffect3(() => {
62
- onChange?.(value);
76
+ return valueRef;
77
+ };
78
+
79
+ // src/useControlledState.ts
80
+ var useControlledState = (valueParam, onChange) => {
81
+ const [value, setControlledValue] = useState3(valueParam);
82
+ useEffect4(() => {
83
+ setControlledValue(valueParam);
63
84
  }, [
64
- value,
65
- onChange
85
+ valueParam
86
+ ]);
87
+ const onChangeRef = useRef2(onChange);
88
+ const valueRef = useDynamicRef(valueParam);
89
+ const setValue = useCallback2((nextValue) => {
90
+ const value2 = isFunction(nextValue) ? nextValue(valueRef.current) : nextValue;
91
+ setControlledValue(value2);
92
+ onChangeRef.current?.(value2);
93
+ }, [
94
+ valueRef,
95
+ onChangeRef
66
96
  ]);
67
97
  return [
68
98
  value,
69
99
  setValue
70
100
  ];
71
101
  };
102
+ function isFunction(value) {
103
+ return typeof value === "function";
104
+ }
72
105
 
73
- // src/useDebugReactDeps.ts
74
- import { useEffect as useEffect4, useRef } from "react";
75
- var useDebugReactDeps = (deps = []) => {
76
- const lastDeps = useRef([]);
77
- useEffect4(() => {
106
+ // src/useDebugDeps.ts
107
+ import { useEffect as useEffect5, useRef as useRef3 } from "react";
108
+ var useDebugDeps = (deps = [], active = true) => {
109
+ const lastDeps = useRef3([]);
110
+ useEffect5(() => {
78
111
  console.group("deps changed", {
79
- old: lastDeps.current.length,
80
- new: deps.length
112
+ previous: lastDeps.current.length,
113
+ current: deps.length
81
114
  });
82
115
  for (let i = 0; i < Math.max(lastDeps.current.length ?? 0, deps.length ?? 0); i++) {
83
- console.log(i, lastDeps.current[i] === deps[i] ? "SAME" : "CHANGED", {
84
- previous: lastDeps.current[i],
85
- current: deps[i]
86
- });
116
+ if (lastDeps.current[i] !== deps[i] && active) {
117
+ console.log("changed", {
118
+ index: i,
119
+ previous: lastDeps.current[i],
120
+ current: deps[i]
121
+ });
122
+ }
87
123
  }
88
124
  console.groupEnd();
89
125
  lastDeps.current = deps;
@@ -91,11 +127,11 @@ var useDebugReactDeps = (deps = []) => {
91
127
  };
92
128
 
93
129
  // src/useDefaultValue.ts
94
- import { useEffect as useEffect5, useState as useState3, useMemo } from "react";
130
+ import { useEffect as useEffect6, useMemo, useState as useState4 } from "react";
95
131
  var useDefaultValue = (reactiveValue, getDefaultValue) => {
96
132
  const stableDefaultValue = useMemo(getDefaultValue, []);
97
- const [value, setValue] = useState3(reactiveValue ?? stableDefaultValue);
98
- useEffect5(() => {
133
+ const [value, setValue] = useState4(reactiveValue ?? stableDefaultValue);
134
+ useEffect6(() => {
99
135
  setValue(reactiveValue ?? stableDefaultValue);
100
136
  }, [
101
137
  reactiveValue,
@@ -114,18 +150,6 @@ var useDefaults = (value, defaults) => {
114
150
  ]);
115
151
  };
116
152
 
117
- // src/useDynamicRef.ts
118
- import { useEffect as useEffect6, useRef as useRef2 } from "react";
119
- var useDynamicRef = (value) => {
120
- const ref = useRef2(value);
121
- useEffect6(() => {
122
- ref.current = value;
123
- }, [
124
- value
125
- ]);
126
- return ref;
127
- };
128
-
129
153
  // src/useFileDownload.ts
130
154
  import { useMemo as useMemo3 } from "react";
131
155
  var useFileDownload = () => {
@@ -140,38 +164,55 @@ var useFileDownload = () => {
140
164
  };
141
165
 
142
166
  // src/useForwardedRef.ts
143
- import { useRef as useRef3, useEffect as useEffect7 } from "react";
144
- var useForwardedRef = (ref) => {
145
- const innerRef = useRef3(null);
167
+ import { useEffect as useEffect7, useMemo as useMemo4, useRef as useRef4 } from "react";
168
+ var useForwardedRef = (forwardedRef) => {
169
+ const localRef = useRef4(null);
146
170
  useEffect7(() => {
147
- if (!ref) {
148
- return;
149
- }
150
- if (typeof ref === "function") {
151
- ref(innerRef.current);
152
- } else {
153
- ref.current = innerRef.current;
171
+ setRef(forwardedRef, localRef.current);
172
+ }, [
173
+ forwardedRef
174
+ ]);
175
+ return localRef;
176
+ };
177
+ function setRef(ref, value) {
178
+ if (typeof ref === "function") {
179
+ return ref(value);
180
+ } else if (ref) {
181
+ ref.current = value;
182
+ }
183
+ }
184
+ var mergeRefs = (refs) => {
185
+ return (value) => {
186
+ const cleanups = [];
187
+ for (const ref of refs) {
188
+ const cleanup = setRef(ref, value);
189
+ cleanups.push(typeof cleanup === "function" ? cleanup : () => setRef(ref, null));
154
190
  }
155
- });
156
- return innerRef;
191
+ return () => {
192
+ for (const cleanup of cleanups) cleanup();
193
+ };
194
+ };
195
+ };
196
+ var useMergeRefs = (refs) => {
197
+ return useMemo4(() => mergeRefs(refs), refs);
157
198
  };
158
199
 
159
200
  // src/useId.ts
160
201
  import alea from "alea";
161
- import { useMemo as useMemo4 } from "react";
202
+ import { useMemo as useMemo5 } from "react";
162
203
  var Alea = alea;
163
204
  var prng = new Alea("@dxos/react-hooks");
164
205
  var randomString = (n = 4) => prng().toString(16).slice(2, n + 2);
165
- var useId = (namespace, propsId, opts) => useMemo4(() => makeId(namespace, propsId, opts), [
206
+ var useId = (namespace, propsId, opts) => useMemo5(() => makeId(namespace, propsId, opts), [
166
207
  propsId
167
208
  ]);
168
209
  var makeId = (namespace, propsId, opts) => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`;
169
210
 
170
211
  // src/useIsFocused.ts
171
- import { useEffect as useEffect8, useRef as useRef4, useState as useState4 } from "react";
212
+ import { useEffect as useEffect8, useRef as useRef5, useState as useState5 } from "react";
172
213
  var useIsFocused = (inputRef) => {
173
- const [isFocused, setIsFocused] = useState4(void 0);
174
- const isFocusedRef = useRef4(isFocused);
214
+ const [isFocused, setIsFocused] = useState5(void 0);
215
+ const isFocusedRef = useRef5(isFocused);
175
216
  isFocusedRef.current = isFocused;
176
217
  useEffect8(() => {
177
218
  const input = inputRef.current;
@@ -197,7 +238,7 @@ var useIsFocused = (inputRef) => {
197
238
  };
198
239
 
199
240
  // src/useMediaQuery.ts
200
- import { useEffect as useEffect9, useState as useState5 } from "react";
241
+ import { useEffect as useEffect9, useState as useState6 } from "react";
201
242
  var breakpointMediaQueries = {
202
243
  sm: "(min-width: 640px)",
203
244
  md: "(min-width: 768px)",
@@ -206,7 +247,7 @@ var breakpointMediaQueries = {
206
247
  "2xl": "(min-width: 1536px)"
207
248
  };
208
249
  var useMediaQuery = (query, options = {}) => {
209
- const { ssr = true, fallback } = options;
250
+ const { ssr = false, fallback } = options;
210
251
  const queries = (Array.isArray(query) ? query : [
211
252
  query
212
253
  ]).map((query2) => query2 in breakpointMediaQueries ? breakpointMediaQueries[query2] : query2);
@@ -214,7 +255,7 @@ var useMediaQuery = (query, options = {}) => {
214
255
  fallback
215
256
  ];
216
257
  fallbackValues = fallbackValues.filter((v) => v != null);
217
- const [value, setValue] = useState5(() => {
258
+ const [value, setValue] = useState6(() => {
218
259
  return queries.map((query2, index) => ({
219
260
  media: query2,
220
261
  matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query2).matches
@@ -262,9 +303,9 @@ var useMediaQuery = (query, options = {}) => {
262
303
  };
263
304
 
264
305
  // src/useMulticastObservable.ts
265
- import { useMemo as useMemo5, useSyncExternalStore } from "react";
306
+ import { useMemo as useMemo6, useSyncExternalStore } from "react";
266
307
  var useMulticastObservable = (observable) => {
267
- const subscribeFn = useMemo5(() => (listener) => {
308
+ const subscribeFn = useMemo6(() => (listener) => {
268
309
  const subscription = observable.subscribe(listener);
269
310
  return () => subscription.unsubscribe();
270
311
  }, [
@@ -274,19 +315,19 @@ var useMulticastObservable = (observable) => {
274
315
  };
275
316
 
276
317
  // src/useRefCallback.ts
277
- import { useState as useState6 } from "react";
318
+ import { useState as useState7 } from "react";
278
319
  var useRefCallback = () => {
279
- const [value, setValue] = useState6(null);
320
+ const [value, setValue] = useState7(null);
280
321
  return {
281
322
  refCallback: (value2) => setValue(value2),
282
323
  value
283
324
  };
284
325
  };
285
326
 
286
- // src/useResize.ts
287
- import { useLayoutEffect, useMemo as useMemo6 } from "react";
288
- var useResize = (handler, deps = [], delay = 800) => {
289
- const debouncedHandler = useMemo6(() => {
327
+ // src/useViewportResize.ts
328
+ import { useLayoutEffect, useMemo as useMemo7 } from "react";
329
+ var useViewportResize = (handler, deps = [], delay = 800) => {
330
+ const debouncedHandler = useMemo7(() => {
290
331
  let timeout;
291
332
  return (event) => {
292
333
  clearTimeout(timeout);
@@ -308,70 +349,84 @@ var useResize = (handler, deps = [], delay = 800) => {
308
349
  ]);
309
350
  };
310
351
 
352
+ // src/useSignals.ts
353
+ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
354
+ import { computed, effect } from "@preact-signals/safe-react";
355
+ import { useRef as useRef6 } from "@preact-signals/safe-react/react";
356
+ import { useEffect as useEffect10, useMemo as useMemo8 } from "react";
357
+ var useSignalsEffect = (cb, deps) => {
358
+ const callback = useRef6(cb);
359
+ callback.current = cb;
360
+ useEffect10(() => {
361
+ return effect(() => {
362
+ return callback.current();
363
+ });
364
+ }, deps ?? []);
365
+ };
366
+ var useSignalsMemo = (cb, deps) => {
367
+ var _effect = _useSignals();
368
+ try {
369
+ return useMemo8(() => computed(cb), deps ?? []).value;
370
+ } finally {
371
+ _effect.f();
372
+ }
373
+ };
374
+
311
375
  // src/useTimeout.ts
312
- import { useEffect as useEffect10, useRef as useRef5 } from "react";
376
+ import { useEffect as useEffect11, useRef as useRef7 } from "react";
313
377
  var useTimeout = (callback, delay = 0, deps = []) => {
314
- const callbackRef = useRef5(callback);
315
- useEffect10(() => {
378
+ const callbackRef = useRef7(callback);
379
+ useEffect11(() => {
316
380
  callbackRef.current = callback;
317
381
  }, [
318
382
  callback
319
383
  ]);
320
- useEffect10(() => {
384
+ useEffect11(() => {
321
385
  if (delay == null) {
322
386
  return;
323
387
  }
324
- const timeout = setTimeout(() => callbackRef.current?.(), delay);
325
- return () => clearTimeout(timeout);
388
+ const t = setTimeout(() => callbackRef.current?.(), delay);
389
+ return () => clearTimeout(t);
326
390
  }, [
327
391
  delay,
328
392
  ...deps
329
393
  ]);
330
394
  };
331
-
332
- // src/useTrackProps.ts
333
- import { useRef as useRef6, useEffect as useEffect11 } from "react";
334
- import { log as log2 } from "@dxos/log";
335
- var __dxlog_file = "/__w/dxos/dxos/packages/ui/primitives/react-hooks/src/useTrackProps.ts";
336
- var useTrackProps = (props, componentName = "Component", active = true) => {
337
- const prevProps = useRef6(props);
395
+ var useInterval = (callback, delay = 0, deps = []) => {
396
+ const callbackRef = useRef7(callback);
338
397
  useEffect11(() => {
339
- const changes = Object.entries(props).filter(([key]) => props[key] !== prevProps.current[key]);
340
- if (changes.length > 0) {
341
- if (active) {
342
- log2.info("props changed", {
343
- componentName,
344
- keys: changes.map(([key]) => key).join(","),
345
- props: Object.fromEntries(changes.map(([key]) => [
346
- key,
347
- {
348
- from: prevProps.current[key],
349
- to: props[key]
350
- }
351
- ]))
352
- }, {
353
- F: __dxlog_file,
354
- L: 22,
355
- S: void 0,
356
- C: (f, a) => f(...a)
357
- });
358
- }
398
+ callbackRef.current = callback;
399
+ }, [
400
+ callback
401
+ ]);
402
+ useEffect11(() => {
403
+ if (delay == null) {
404
+ return;
359
405
  }
360
- prevProps.current = props;
361
- });
406
+ const i = setInterval(async () => {
407
+ const result = await callbackRef.current?.();
408
+ if (result === false) {
409
+ clearInterval(i);
410
+ }
411
+ }, delay);
412
+ return () => clearInterval(i);
413
+ }, [
414
+ delay,
415
+ ...deps
416
+ ]);
362
417
  };
363
418
 
364
419
  // src/useTransitions.ts
365
- import { useRef as useRef7, useEffect as useEffect12, useState as useState7 } from "react";
366
- var isFunction = (functionToCheck) => {
420
+ import { useEffect as useEffect12, useRef as useRef8, useState as useState8 } from "react";
421
+ var isFunction2 = (functionToCheck) => {
367
422
  return functionToCheck instanceof Function;
368
423
  };
369
424
  var useDidTransition = (currentValue, fromValue, toValue) => {
370
- const [hasTransitioned, setHasTransitioned] = useState7(false);
371
- const previousValue = useRef7(currentValue);
425
+ const [hasTransitioned, setHasTransitioned] = useState8(false);
426
+ const previousValue = useRef8(currentValue);
372
427
  useEffect12(() => {
373
- const toValueValid = isFunction(toValue) ? toValue(currentValue) : toValue === currentValue;
374
- const fromValueValid = isFunction(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
428
+ const toValueValid = isFunction2(toValue) ? toValue(currentValue) : toValue === currentValue;
429
+ const fromValueValid = isFunction2(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
375
430
  if (fromValueValid && toValueValid && !hasTransitioned) {
376
431
  setHasTransitioned(true);
377
432
  } else if ((!fromValueValid || !toValueValid) && hasTransitioned) {
@@ -387,7 +442,7 @@ var useDidTransition = (currentValue, fromValue, toValue) => {
387
442
  return hasTransitioned;
388
443
  };
389
444
  var useOnTransition = (currentValue, fromValue, toValue, callback) => {
390
- const dirty = useRef7(false);
445
+ const dirty = useRef8(false);
391
446
  const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);
392
447
  useEffect12(() => {
393
448
  dirty.current = false;
@@ -406,13 +461,18 @@ var useOnTransition = (currentValue, fromValue, toValue, callback) => {
406
461
  callback
407
462
  ]);
408
463
  };
464
+
465
+ // src/index.ts
466
+ import { useSize, useScroller } from "mini-virtual-list";
409
467
  export {
410
468
  makeId,
469
+ mergeRefs,
411
470
  randomString,
471
+ setRef,
412
472
  useAsyncEffect,
413
473
  useAsyncState,
414
474
  useControlledState,
415
- useDebugReactDeps,
475
+ useDebugDeps,
416
476
  useDefaultValue,
417
477
  useDefaults,
418
478
  useDidTransition,
@@ -420,13 +480,19 @@ export {
420
480
  useFileDownload,
421
481
  useForwardedRef,
422
482
  useId,
483
+ useInterval,
423
484
  useIsFocused,
424
485
  useMediaQuery,
486
+ useMergeRefs,
425
487
  useMulticastObservable,
426
488
  useOnTransition,
427
489
  useRefCallback,
428
- useResize,
490
+ useScroller,
491
+ useSignalsEffect,
492
+ useSignalsMemo,
493
+ useSize,
494
+ useStateWithRef,
429
495
  useTimeout,
430
- useTrackProps
496
+ useViewportResize
431
497
  };
432
498
  //# sourceMappingURL=index.mjs.map