@dxos/react-hooks 0.8.4-main.67995b8 → 0.8.4-main.72ec0f3

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