@kelet-ai/feedback-ui 0.7.1 → 1.0.0

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/README.md CHANGED
@@ -261,7 +261,7 @@ For implicit feedback, understanding how state changes are processed:
261
261
  // User types: "Hello" → "Hello World" → "Hello World!"
262
262
  // Only sends ONE feedback after user stops typing
263
263
  const [text, setText] = useFeedbackState('', 'editor', {
264
- debounceMs: 1500, // Wait 1.5s after last change
264
+ debounceMs: 3000, // Wait 3s after last change
265
265
  });
266
266
  ```
267
267
 
@@ -535,7 +535,7 @@ interface FeedbackData {
535
535
 
536
536
  | Option | Type | Default | Description |
537
537
  | ---------------------- | ------------------------------------ | --------------------- | -------------------------------------- |
538
- | `debounceMs` | `number` | `1500` | Debounce time in milliseconds |
538
+ | `debounceMs` | `number` | `3000` | Debounce time in milliseconds |
539
539
  | `diffType` | `'git' \| 'object' \| 'json'` | `'git'` | Diff output format |
540
540
  | `compareWith` | `(a: T, b: T) => boolean` | `undefined` | Custom equality function |
541
541
  | `metadata` | `Record<string, any>` | `{}` | Additional metadata |
@@ -1865,7 +1865,7 @@ function splitLines(text) {
1865
1865
  }
1866
1866
  return result;
1867
1867
  }
1868
- function formatDiff(oldValue, newValue, diffType = "git", context = 3) {
1868
+ function formatDiff(oldValue, newValue, diffType = "git", context = 1) {
1869
1869
  switch (diffType) {
1870
1870
  case "git":
1871
1871
  return formatGitDiff(oldValue, newValue, context);
@@ -1877,7 +1877,7 @@ function formatDiff(oldValue, newValue, diffType = "git", context = 3) {
1877
1877
  return formatGitDiff(oldValue, newValue, context);
1878
1878
  }
1879
1879
  }
1880
- function formatGitDiff(oldValue, newValue, context = 3) {
1880
+ function formatGitDiff(oldValue, newValue, context = 1) {
1881
1881
  const oldStr = stringify(oldValue);
1882
1882
  const newStr = stringify(newValue);
1883
1883
  const patch = createTwoFilesPatch(
@@ -1893,7 +1893,20 @@ function formatGitDiff(oldValue, newValue, context = 3) {
1893
1893
  "",
1894
1894
  { context }
1895
1895
  );
1896
- return patch.split("\n").slice(2).join("\n");
1896
+ const lines = patch.split("\n");
1897
+ const filtered = lines.filter((line) => {
1898
+ if (!line) return false;
1899
+ if (line === "\") return false;
1900
+ if (line.startsWith("@@")) return false;
1901
+ if (line.startsWith("---") || line.startsWith("+++")) return false;
1902
+ if (line.startsWith(" ")) return false;
1903
+ if (line.startsWith("+") || line.startsWith("-")) return true;
1904
+ return false;
1905
+ });
1906
+ while (filtered.length && filtered[0].trim() === "") filtered.shift();
1907
+ while (filtered.length && filtered[filtered.length - 1].trim() === "")
1908
+ filtered.pop();
1909
+ return filtered.join("\n");
1897
1910
  }
1898
1911
  function formatObjectDiff(oldValue, newValue) {
1899
1912
  const differences = deepDiffExports.diff(oldValue, newValue) || [];
@@ -2006,19 +2019,22 @@ function stringify(value) {
2006
2019
  function useStateChangeTracking(currentState, tx_id, options) {
2007
2020
  const defaultFeedbackHandler = useDefaultFeedbackHandler();
2008
2021
  const feedbackHandler = options?.onFeedback || defaultFeedbackHandler;
2009
- const debounceMs = options?.debounceMs ?? 1500;
2022
+ const debounceMs = options?.debounceMs ?? 3e3;
2010
2023
  const diffType = options?.diffType ?? "git";
2011
2024
  const compareWith = options?.compareWith;
2012
2025
  const defaultTriggerName = options?.default_trigger_name ?? "auto_state_change";
2013
2026
  const ignoreInitialNullish = options?.ignoreInitialNullish ?? true;
2014
2027
  const prevStateRef = useRef(currentState);
2015
- const changeStartStateRef = useRef(currentState);
2016
2028
  const isFirstRenderRef = useRef(true);
2017
2029
  const initialStateRef = useRef(currentState);
2030
+ const initialWasNullishRef = useRef(currentState == null);
2018
2031
  const hasHadNonNullishStateRef = useRef(
2019
2032
  currentState != null
2020
2033
  // != null catches both null and undefined
2021
2034
  );
2035
+ const hasEligibleBaselineRef = useRef(
2036
+ !(ignoreInitialNullish && currentState == null)
2037
+ );
2022
2038
  const timeoutRef = useRef(null);
2023
2039
  const currentTriggerNameRef = useRef(void 0);
2024
2040
  const sendFeedback = useCallback(
@@ -2053,7 +2069,7 @@ function useStateChangeTracking(currentState, tx_id, options) {
2053
2069
  const newTriggerName = trigger_name || defaultTriggerName;
2054
2070
  if (timeoutRef.current && currentTriggerNameRef.current && currentTriggerNameRef.current !== newTriggerName) {
2055
2071
  clearTimeout(timeoutRef.current);
2056
- const startState = changeStartStateRef.current;
2072
+ const startState = initialStateRef.current;
2057
2073
  const currentStateBeforeChange = currentState;
2058
2074
  sendFeedback(
2059
2075
  startState,
@@ -2070,39 +2086,41 @@ function useStateChangeTracking(currentState, tx_id, options) {
2070
2086
  if (isFirstRenderRef.current) {
2071
2087
  isFirstRenderRef.current = false;
2072
2088
  prevStateRef.current = currentState;
2073
- changeStartStateRef.current = currentState;
2089
+ if (!ignoreInitialNullish || currentState != null) {
2090
+ initialStateRef.current = currentState;
2091
+ hasEligibleBaselineRef.current = true;
2092
+ }
2074
2093
  return;
2075
2094
  }
2076
2095
  const prevState = prevStateRef.current;
2077
2096
  const isEqual = compareWith ? compareWith(prevState, currentState) : JSON.stringify(prevState) === JSON.stringify(currentState);
2078
2097
  if (!isEqual) {
2079
- const shouldIgnoreChange = ignoreInitialNullish && initialStateRef.current == null && // Initial state was nullish
2098
+ const shouldIgnoreChange = ignoreInitialNullish && initialWasNullishRef.current && // True initial state was nullish
2080
2099
  !hasHadNonNullishStateRef.current && // We haven't had non-nullish state before
2081
2100
  currentState != null;
2082
2101
  if (currentState != null) {
2083
2102
  hasHadNonNullishStateRef.current = true;
2084
2103
  }
2085
2104
  if (shouldIgnoreChange) {
2105
+ initialStateRef.current = currentState;
2106
+ hasEligibleBaselineRef.current = true;
2086
2107
  prevStateRef.current = currentState;
2087
- changeStartStateRef.current = currentState;
2088
2108
  return;
2089
2109
  }
2090
- if (!timeoutRef.current) {
2091
- changeStartStateRef.current = prevState;
2092
- }
2093
2110
  if (timeoutRef.current) {
2094
2111
  clearTimeout(timeoutRef.current);
2095
2112
  }
2096
2113
  prevStateRef.current = currentState;
2097
2114
  timeoutRef.current = setTimeout(() => {
2098
- const startState = changeStartStateRef.current;
2115
+ const startState = initialStateRef.current;
2099
2116
  const finalState = currentState;
2100
- sendFeedback(
2101
- startState,
2102
- finalState,
2103
- currentTriggerNameRef.current || defaultTriggerName
2104
- );
2105
- changeStartStateRef.current = finalState;
2117
+ if (hasEligibleBaselineRef.current) {
2118
+ sendFeedback(
2119
+ startState,
2120
+ finalState,
2121
+ currentTriggerNameRef.current || defaultTriggerName
2122
+ );
2123
+ }
2106
2124
  timeoutRef.current = null;
2107
2125
  }, debounceMs);
2108
2126
  }