@kelet-ai/feedback-ui 0.7.0 → 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 +2 -2
- package/dist/contexts/kelet.d.ts +1 -0
- package/dist/feedback-ui.es.js +41 -22
- package/dist/feedback-ui.es.js.map +1 -1
- package/dist/feedback-ui.es.min.js +511 -506
- package/dist/feedback-ui.es.min.js.map +1 -1
- package/dist/feedback-ui.umd.js +41 -22
- package/dist/feedback-ui.umd.js.map +1 -1
- package/dist/feedback-ui.umd.min.js +9 -9
- package/dist/feedback-ui.umd.min.js.map +1 -1
- package/dist/hooks/feedback-state/types.d.ts +1 -1
- package/package.json +1 -1
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:
|
|
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` | `
|
|
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 |
|
package/dist/contexts/kelet.d.ts
CHANGED
package/dist/feedback-ui.es.js
CHANGED
|
@@ -353,7 +353,7 @@ function requireJsxRuntime() {
|
|
|
353
353
|
}
|
|
354
354
|
var jsxRuntimeExports = requireJsxRuntime();
|
|
355
355
|
const KeletContext = createContext(null);
|
|
356
|
-
const
|
|
356
|
+
const DefaultKeletBaseUrl = "https://api.kelet.ai/api";
|
|
357
357
|
const useKelet = () => {
|
|
358
358
|
const context = useContext(KeletContext);
|
|
359
359
|
if (!context) {
|
|
@@ -373,7 +373,7 @@ const useDefaultFeedbackHandler = () => {
|
|
|
373
373
|
return context.feedback;
|
|
374
374
|
}
|
|
375
375
|
};
|
|
376
|
-
const KeletProvider = ({ apiKey, project, children }) => {
|
|
376
|
+
const KeletProvider = ({ apiKey, project, baseUrl, children }) => {
|
|
377
377
|
const parentContext = useContext(KeletContext);
|
|
378
378
|
const resolvedApiKey = apiKey || parentContext?.api_key;
|
|
379
379
|
if (!resolvedApiKey) {
|
|
@@ -382,7 +382,8 @@ const KeletProvider = ({ apiKey, project, children }) => {
|
|
|
382
382
|
);
|
|
383
383
|
}
|
|
384
384
|
const feedback = async (data) => {
|
|
385
|
-
const
|
|
385
|
+
const resolvedBaseUrl = baseUrl || DefaultKeletBaseUrl;
|
|
386
|
+
const url = `${resolvedBaseUrl}/projects/${project}/feedback`;
|
|
386
387
|
const req = {
|
|
387
388
|
tx_id: data.tx_id,
|
|
388
389
|
source: data.source || "EXPLICIT",
|
|
@@ -1864,7 +1865,7 @@ function splitLines(text) {
|
|
|
1864
1865
|
}
|
|
1865
1866
|
return result;
|
|
1866
1867
|
}
|
|
1867
|
-
function formatDiff(oldValue, newValue, diffType = "git", context =
|
|
1868
|
+
function formatDiff(oldValue, newValue, diffType = "git", context = 1) {
|
|
1868
1869
|
switch (diffType) {
|
|
1869
1870
|
case "git":
|
|
1870
1871
|
return formatGitDiff(oldValue, newValue, context);
|
|
@@ -1876,7 +1877,7 @@ function formatDiff(oldValue, newValue, diffType = "git", context = 3) {
|
|
|
1876
1877
|
return formatGitDiff(oldValue, newValue, context);
|
|
1877
1878
|
}
|
|
1878
1879
|
}
|
|
1879
|
-
function formatGitDiff(oldValue, newValue, context =
|
|
1880
|
+
function formatGitDiff(oldValue, newValue, context = 1) {
|
|
1880
1881
|
const oldStr = stringify(oldValue);
|
|
1881
1882
|
const newStr = stringify(newValue);
|
|
1882
1883
|
const patch = createTwoFilesPatch(
|
|
@@ -1892,7 +1893,20 @@ function formatGitDiff(oldValue, newValue, context = 3) {
|
|
|
1892
1893
|
"",
|
|
1893
1894
|
{ context }
|
|
1894
1895
|
);
|
|
1895
|
-
|
|
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");
|
|
1896
1910
|
}
|
|
1897
1911
|
function formatObjectDiff(oldValue, newValue) {
|
|
1898
1912
|
const differences = deepDiffExports.diff(oldValue, newValue) || [];
|
|
@@ -2005,19 +2019,22 @@ function stringify(value) {
|
|
|
2005
2019
|
function useStateChangeTracking(currentState, tx_id, options) {
|
|
2006
2020
|
const defaultFeedbackHandler = useDefaultFeedbackHandler();
|
|
2007
2021
|
const feedbackHandler = options?.onFeedback || defaultFeedbackHandler;
|
|
2008
|
-
const debounceMs = options?.debounceMs ??
|
|
2022
|
+
const debounceMs = options?.debounceMs ?? 3e3;
|
|
2009
2023
|
const diffType = options?.diffType ?? "git";
|
|
2010
2024
|
const compareWith = options?.compareWith;
|
|
2011
2025
|
const defaultTriggerName = options?.default_trigger_name ?? "auto_state_change";
|
|
2012
2026
|
const ignoreInitialNullish = options?.ignoreInitialNullish ?? true;
|
|
2013
2027
|
const prevStateRef = useRef(currentState);
|
|
2014
|
-
const changeStartStateRef = useRef(currentState);
|
|
2015
2028
|
const isFirstRenderRef = useRef(true);
|
|
2016
2029
|
const initialStateRef = useRef(currentState);
|
|
2030
|
+
const initialWasNullishRef = useRef(currentState == null);
|
|
2017
2031
|
const hasHadNonNullishStateRef = useRef(
|
|
2018
2032
|
currentState != null
|
|
2019
2033
|
// != null catches both null and undefined
|
|
2020
2034
|
);
|
|
2035
|
+
const hasEligibleBaselineRef = useRef(
|
|
2036
|
+
!(ignoreInitialNullish && currentState == null)
|
|
2037
|
+
);
|
|
2021
2038
|
const timeoutRef = useRef(null);
|
|
2022
2039
|
const currentTriggerNameRef = useRef(void 0);
|
|
2023
2040
|
const sendFeedback = useCallback(
|
|
@@ -2052,7 +2069,7 @@ function useStateChangeTracking(currentState, tx_id, options) {
|
|
|
2052
2069
|
const newTriggerName = trigger_name || defaultTriggerName;
|
|
2053
2070
|
if (timeoutRef.current && currentTriggerNameRef.current && currentTriggerNameRef.current !== newTriggerName) {
|
|
2054
2071
|
clearTimeout(timeoutRef.current);
|
|
2055
|
-
const startState =
|
|
2072
|
+
const startState = initialStateRef.current;
|
|
2056
2073
|
const currentStateBeforeChange = currentState;
|
|
2057
2074
|
sendFeedback(
|
|
2058
2075
|
startState,
|
|
@@ -2069,39 +2086,41 @@ function useStateChangeTracking(currentState, tx_id, options) {
|
|
|
2069
2086
|
if (isFirstRenderRef.current) {
|
|
2070
2087
|
isFirstRenderRef.current = false;
|
|
2071
2088
|
prevStateRef.current = currentState;
|
|
2072
|
-
|
|
2089
|
+
if (!ignoreInitialNullish || currentState != null) {
|
|
2090
|
+
initialStateRef.current = currentState;
|
|
2091
|
+
hasEligibleBaselineRef.current = true;
|
|
2092
|
+
}
|
|
2073
2093
|
return;
|
|
2074
2094
|
}
|
|
2075
2095
|
const prevState = prevStateRef.current;
|
|
2076
2096
|
const isEqual = compareWith ? compareWith(prevState, currentState) : JSON.stringify(prevState) === JSON.stringify(currentState);
|
|
2077
2097
|
if (!isEqual) {
|
|
2078
|
-
const shouldIgnoreChange = ignoreInitialNullish &&
|
|
2098
|
+
const shouldIgnoreChange = ignoreInitialNullish && initialWasNullishRef.current && // True initial state was nullish
|
|
2079
2099
|
!hasHadNonNullishStateRef.current && // We haven't had non-nullish state before
|
|
2080
2100
|
currentState != null;
|
|
2081
2101
|
if (currentState != null) {
|
|
2082
2102
|
hasHadNonNullishStateRef.current = true;
|
|
2083
2103
|
}
|
|
2084
2104
|
if (shouldIgnoreChange) {
|
|
2105
|
+
initialStateRef.current = currentState;
|
|
2106
|
+
hasEligibleBaselineRef.current = true;
|
|
2085
2107
|
prevStateRef.current = currentState;
|
|
2086
|
-
changeStartStateRef.current = currentState;
|
|
2087
2108
|
return;
|
|
2088
2109
|
}
|
|
2089
|
-
if (!timeoutRef.current) {
|
|
2090
|
-
changeStartStateRef.current = prevState;
|
|
2091
|
-
}
|
|
2092
2110
|
if (timeoutRef.current) {
|
|
2093
2111
|
clearTimeout(timeoutRef.current);
|
|
2094
2112
|
}
|
|
2095
2113
|
prevStateRef.current = currentState;
|
|
2096
2114
|
timeoutRef.current = setTimeout(() => {
|
|
2097
|
-
const startState =
|
|
2115
|
+
const startState = initialStateRef.current;
|
|
2098
2116
|
const finalState = currentState;
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2117
|
+
if (hasEligibleBaselineRef.current) {
|
|
2118
|
+
sendFeedback(
|
|
2119
|
+
startState,
|
|
2120
|
+
finalState,
|
|
2121
|
+
currentTriggerNameRef.current || defaultTriggerName
|
|
2122
|
+
);
|
|
2123
|
+
}
|
|
2105
2124
|
timeoutRef.current = null;
|
|
2106
2125
|
}, debounceMs);
|
|
2107
2126
|
}
|