@trackunit/react-core-hooks 1.7.30 → 1.7.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.
package/index.cjs.js CHANGED
@@ -5,6 +5,7 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
  var fflate = require('fflate');
6
6
  var irisAppRuntimeCore = require('@trackunit/iris-app-runtime-core');
7
7
  var sharedUtils = require('@trackunit/shared-utils');
8
+ var esToolkit = require('es-toolkit');
8
9
 
9
10
  const AnalyticsContext = react.createContext(null);
10
11
  const AnalyticsContextProvider = AnalyticsContext.Provider; // easy import
@@ -1188,6 +1189,31 @@ function useTextSearch(items, props) {
1188
1189
  return react.useMemo(() => [result, searchText, setSearchText], [result, searchText, setSearchText]);
1189
1190
  }
1190
1191
 
1192
+ const UNINITIALIZED = Symbol("UNINITIALIZED");
1193
+ /**
1194
+ * Hook to watch for changes in a value and react to them.
1195
+ * Uses deep equality comparison via es-toolkit's isEqual.
1196
+ *
1197
+ * @param props - The hook properties
1198
+ * @param props.value - The value to watch for changes
1199
+ * @param props.onChange - Function to call when the value changes
1200
+ * @param props.immediate - Whether to run the callback immediately on mount (default: false)
1201
+ */
1202
+ const useWatch = ({ value, onChange, immediate = false }) => {
1203
+ const prevValue = react.useRef(UNINITIALIZED);
1204
+ react.useEffect(() => {
1205
+ const prev = prevValue.current;
1206
+ const hasChanged = prev === UNINITIALIZED ? false : !esToolkit.isEqual(value, prev);
1207
+ if (immediate && prev === UNINITIALIZED) {
1208
+ onChange(value, null);
1209
+ }
1210
+ else if (hasChanged && prev !== UNINITIALIZED) {
1211
+ onChange(value, prev);
1212
+ }
1213
+ prevValue.current = value;
1214
+ }, [value, onChange, immediate]);
1215
+ };
1216
+
1191
1217
  const WidgetConfigContext = react.createContext(null);
1192
1218
  /**
1193
1219
  * This is a hook to use the WidgetConfigProvider.
@@ -1344,5 +1370,6 @@ exports.useTimeRange = useTimeRange;
1344
1370
  exports.useToast = useToast;
1345
1371
  exports.useToken = useToken;
1346
1372
  exports.useUserSubscription = useUserSubscription;
1373
+ exports.useWatch = useWatch;
1347
1374
  exports.useWidgetConfig = useWidgetConfig;
1348
1375
  exports.useWidgetConfigAsync = useWidgetConfigAsync;
package/index.esm.js CHANGED
@@ -3,6 +3,7 @@ import { jsx } from 'react/jsx-runtime';
3
3
  import { gzipSync, gunzipSync } from 'fflate';
4
4
  import { AssetRuntime, CustomerRuntime, EventRuntime, ParamsRuntime, SiteRuntime, WidgetConfigRuntime } from '@trackunit/iris-app-runtime-core';
5
5
  import { filterByMultiple } from '@trackunit/shared-utils';
6
+ import { isEqual } from 'es-toolkit';
6
7
 
7
8
  const AnalyticsContext = createContext(null);
8
9
  const AnalyticsContextProvider = AnalyticsContext.Provider; // easy import
@@ -1186,6 +1187,31 @@ function useTextSearch(items, props) {
1186
1187
  return useMemo(() => [result, searchText, setSearchText], [result, searchText, setSearchText]);
1187
1188
  }
1188
1189
 
1190
+ const UNINITIALIZED = Symbol("UNINITIALIZED");
1191
+ /**
1192
+ * Hook to watch for changes in a value and react to them.
1193
+ * Uses deep equality comparison via es-toolkit's isEqual.
1194
+ *
1195
+ * @param props - The hook properties
1196
+ * @param props.value - The value to watch for changes
1197
+ * @param props.onChange - Function to call when the value changes
1198
+ * @param props.immediate - Whether to run the callback immediately on mount (default: false)
1199
+ */
1200
+ const useWatch = ({ value, onChange, immediate = false }) => {
1201
+ const prevValue = useRef(UNINITIALIZED);
1202
+ useEffect(() => {
1203
+ const prev = prevValue.current;
1204
+ const hasChanged = prev === UNINITIALIZED ? false : !isEqual(value, prev);
1205
+ if (immediate && prev === UNINITIALIZED) {
1206
+ onChange(value, null);
1207
+ }
1208
+ else if (hasChanged && prev !== UNINITIALIZED) {
1209
+ onChange(value, prev);
1210
+ }
1211
+ prevValue.current = value;
1212
+ }, [value, onChange, immediate]);
1213
+ };
1214
+
1189
1215
  const WidgetConfigContext = createContext(null);
1190
1216
  /**
1191
1217
  * This is a hook to use the WidgetConfigProvider.
@@ -1289,4 +1315,4 @@ const useWidgetConfig = () => {
1289
1315
  return result;
1290
1316
  };
1291
1317
 
1292
- export { AnalyticsContext, AnalyticsContextProvider, AssetSortingProvider, ConfirmationDialogProvider, CurrentUserPreferenceProvider, CurrentUserProvider, EnvironmentContextProvider, ErrorHandlingContext, ErrorHandlingContextProvider, FilterBarProvider, ModalDialogContextProvider, NavigationContextProvider, OemBrandingContextProvider, TimeRangeProvider, ToastProvider, TokenProvider, UserSubscriptionProvider, WidgetConfigContext, WidgetConfigProvider, fetchAssetBlobUrl, useAnalytics, useAssetRuntime, useAssetSorting, useConfirmationDialog, useCurrentUser, useCurrentUserLanguage, useCurrentUserSystemOfMeasurement, useCurrentUserTimeZonePreference, useCustomEncoding, useCustomerRuntime, useEnvironment, useErrorHandler, useErrorHandlerOrNull, useEventRuntime, useFeatureBranchQueryString, useFilterBarContext, useHasAccessTo, useImageUploader, useIrisAppId, useIrisAppImage, useIrisAppName, useLocalStorage, useLocalStorageReducer, useModalDialogContext, useNavigateInHost, useOemBrandingContext, usePrevious, useSiteRuntime, useTextSearch, useTimeRange, useToast, useToken, useUserSubscription, useWidgetConfig, useWidgetConfigAsync };
1318
+ export { AnalyticsContext, AnalyticsContextProvider, AssetSortingProvider, ConfirmationDialogProvider, CurrentUserPreferenceProvider, CurrentUserProvider, EnvironmentContextProvider, ErrorHandlingContext, ErrorHandlingContextProvider, FilterBarProvider, ModalDialogContextProvider, NavigationContextProvider, OemBrandingContextProvider, TimeRangeProvider, ToastProvider, TokenProvider, UserSubscriptionProvider, WidgetConfigContext, WidgetConfigProvider, fetchAssetBlobUrl, useAnalytics, useAssetRuntime, useAssetSorting, useConfirmationDialog, useCurrentUser, useCurrentUserLanguage, useCurrentUserSystemOfMeasurement, useCurrentUserTimeZonePreference, useCustomEncoding, useCustomerRuntime, useEnvironment, useErrorHandler, useErrorHandlerOrNull, useEventRuntime, useFeatureBranchQueryString, useFilterBarContext, useHasAccessTo, useImageUploader, useIrisAppId, useIrisAppImage, useIrisAppName, useLocalStorage, useLocalStorageReducer, useModalDialogContext, useNavigateInHost, useOemBrandingContext, usePrevious, useSiteRuntime, useTextSearch, useTimeRange, useToast, useToken, useUserSubscription, useWatch, useWidgetConfig, useWidgetConfigAsync };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-core-hooks",
3
- "version": "1.7.30",
3
+ "version": "1.7.31",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -14,7 +14,8 @@
14
14
  "@trackunit/iris-app-runtime-core": "1.8.28",
15
15
  "@trackunit/shared-utils": "1.9.26",
16
16
  "@trackunit/react-test-setup": "1.4.26",
17
- "fflate": "^0.8.2"
17
+ "fflate": "^0.8.2",
18
+ "es-toolkit": "^1.39.10"
18
19
  },
19
20
  "module": "./index.esm.js",
20
21
  "main": "./index.cjs.js",
package/src/index.d.ts CHANGED
@@ -27,4 +27,5 @@ export * from "./usePrevious";
27
27
  export * from "./user/CurrentUserPreferenceProvider";
28
28
  export * from "./user/CurrentUserProvider";
29
29
  export * from "./useTextSearch";
30
+ export * from "./useWatch";
30
31
  export * from "./widgetConfig/WidgetConfigProvider";
@@ -0,0 +1,18 @@
1
+ interface UseWatchOptions {
2
+ immediate?: boolean;
3
+ }
4
+ interface UseWatchProps<TValue> extends UseWatchOptions {
5
+ value: TValue;
6
+ onChange: (value: TValue, prevValue: TValue | null) => void;
7
+ }
8
+ /**
9
+ * Hook to watch for changes in a value and react to them.
10
+ * Uses deep equality comparison via es-toolkit's isEqual.
11
+ *
12
+ * @param props - The hook properties
13
+ * @param props.value - The value to watch for changes
14
+ * @param props.onChange - Function to call when the value changes
15
+ * @param props.immediate - Whether to run the callback immediately on mount (default: false)
16
+ */
17
+ export declare const useWatch: <TValue>({ value, onChange, immediate }: UseWatchProps<TValue>) => void;
18
+ export {};