@dynamic-labs/react-hooks 4.0.0-alpha.3 → 4.0.0-alpha.31

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 (3) hide show
  1. package/index.cjs +94 -0
  2. package/index.js +4 -1543
  3. package/package.json +6 -5
package/index.cjs ADDED
@@ -0,0 +1,94 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var assertPackageVersion = require('@dynamic-labs/assert-package-version');
6
+ var react = require('react');
7
+ var reactivity = require('@vue/reactivity');
8
+
9
+ var version = "4.0.0-alpha.31";
10
+
11
+ const isObject = value => typeof value === 'object' && value !== null && value !== undefined && typeof value !== 'function' && typeof value !== 'symbol' && typeof value !== 'bigint' && !Array.isArray(value) && !(value instanceof Date);
12
+ /**
13
+ * Watches for changes in the source and calls the callback when the source changes
14
+ * @param source - The source to watch for changes
15
+ * @param callback - The callback to call when the source changes
16
+ * @returns The unsubscribe function
17
+ */
18
+ const watch = (source, callback) => {
19
+ let isWatching = false;
20
+ const runner = reactivity.effect(source, {
21
+ onTrack: () => isWatching = true,
22
+ scheduler: callback
23
+ });
24
+ if (!isWatching) return undefined;
25
+ return () => {
26
+ reactivity.stop(runner);
27
+ };
28
+ };
29
+ const useReactivityProxy = target => {
30
+ /**
31
+ * Stores all unsubscribe functions in a particular render
32
+ */
33
+ const unsubscribeFunctionsRef = react.useRef(new Set());
34
+ /**
35
+ * Store all new proxy objects references created when accessed to present unnecessary reactivity.
36
+ * When an attribute is accessed by the customer and we create a proxy for it, we store it here
37
+ * so in the next render, we can reuse the same proxy object and that way not cause a new render
38
+ * by creating a new proxy object reference
39
+ */
40
+ const proxyObjectCacheRef = react.useRef(new Map());
41
+ // Rerender count to force rerender when the target changes
42
+ const [, setRerenderCount] = react.useState(0);
43
+ const unsubscribeAll = react.useCallback(() => {
44
+ unsubscribeFunctionsRef.current.forEach(unsubscribeFunction => unsubscribeFunction());
45
+ unsubscribeFunctionsRef.current.clear();
46
+ }, []);
47
+ const rerender = react.useCallback(() => {
48
+ unsubscribeAll();
49
+ setRerenderCount(rerenderCount => rerenderCount + 1);
50
+ }, [setRerenderCount, unsubscribeAll]);
51
+ /**
52
+ * On every render it cleans the previous subscriptions.
53
+ * This is necessary because different renders can have different subscriptions.
54
+ */
55
+ unsubscribeAll();
56
+ const addSubscriptionProxy = (target, proxyCacheKey) => {
57
+ // Check if object path is already cached
58
+ if (proxyObjectCacheRef.current.has(proxyCacheKey)) {
59
+ return proxyObjectCacheRef.current.get(proxyCacheKey);
60
+ }
61
+ // Create a proxy object to subscribe to the accessed attribute
62
+ const proxyObject = new Proxy(target, {
63
+ get: (target, prop, receiver) => {
64
+ const value = Reflect.get(target, prop, receiver);
65
+ // Subscribe to the accessed attribute
66
+ const unsubscribeFunction = watch(() => Reflect.get(target, prop, receiver), rerender);
67
+ if (unsubscribeFunction) {
68
+ unsubscribeFunctionsRef.current.add(unsubscribeFunction);
69
+ }
70
+ const isReactiveValue = Boolean(unsubscribeFunction);
71
+ // If the value is an object, we need to create a proxy for it too
72
+ // but not when the value is reactive, if it is reactive we wanna stop creating proxies
73
+ if (isObject(value) && !isReactiveValue) {
74
+ const propCachePath = `${proxyCacheKey}.${String(prop)}`;
75
+ return addSubscriptionProxy(value, propCachePath);
76
+ }
77
+ return value;
78
+ }
79
+ });
80
+ // Cache the proxy object
81
+ proxyObjectCacheRef.current.set(proxyCacheKey, proxyObject);
82
+ return proxyObject;
83
+ };
84
+ return react.useMemo(() => {
85
+ // target changed, clear all proxy cache to allow for the new object to be proxied
86
+ proxyObjectCacheRef.current.clear();
87
+ return addSubscriptionProxy(target, '');
88
+ // eslint-disable-next-line react-hooks/exhaustive-deps
89
+ }, [target]);
90
+ };
91
+
92
+ assertPackageVersion.assertPackageVersion('@dynamic-labs/react-hooks', version);
93
+
94
+ exports.useReactiveClient = useReactivityProxy;