@valentinkolb/cloud 0.5.5 → 0.5.6
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/package.json
CHANGED
|
@@ -40,22 +40,20 @@
|
|
|
40
40
|
* comment on focus-trap rationale.
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
|
-
import { createSignal, createEffect, createMemo, onMount, onCleanup, untrack, For, Show } from "solid-js";
|
|
44
43
|
import { timed } from "@valentinkolb/stdlib/solid";
|
|
44
|
+
import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show, untrack } from "solid-js";
|
|
45
45
|
import {
|
|
46
|
-
type Completion,
|
|
47
|
-
type QueryContext,
|
|
48
|
-
type Suggestion,
|
|
49
46
|
applySuggestion,
|
|
50
47
|
buildSuggestContext,
|
|
51
|
-
|
|
48
|
+
type Completion,
|
|
52
49
|
detectQuery,
|
|
53
50
|
displayLabel,
|
|
54
51
|
plainTextHighlight,
|
|
52
|
+
type QueryContext,
|
|
55
53
|
renderWithOverlay,
|
|
56
54
|
resetCompletionState,
|
|
57
55
|
resolveSuggestions,
|
|
58
|
-
|
|
56
|
+
type Suggestion,
|
|
59
57
|
tryExpand,
|
|
60
58
|
tryRestore,
|
|
61
59
|
} from "../completion";
|
|
@@ -162,7 +160,6 @@ const AutocompleteEditor = (props: AutocompleteEditorProps) => {
|
|
|
162
160
|
/* ── Memoised inputs ──────────────────────────────────── */
|
|
163
161
|
|
|
164
162
|
const completions = createMemo(() => props.completions);
|
|
165
|
-
const knownLabels = createMemo(() => collectKnownLabels(completions()));
|
|
166
163
|
const useOverlay = createMemo(() => Boolean(props.highlight));
|
|
167
164
|
|
|
168
165
|
/* ── External value sync ──────────────────────────────── */
|
|
@@ -214,6 +211,11 @@ const AutocompleteEditor = (props: AutocompleteEditorProps) => {
|
|
|
214
211
|
currentAbort = null;
|
|
215
212
|
};
|
|
216
213
|
|
|
214
|
+
const isAbortError = (e: unknown): boolean =>
|
|
215
|
+
e instanceof DOMException
|
|
216
|
+
? e.name === "AbortError"
|
|
217
|
+
: Boolean(e && typeof e === "object" && "name" in e && (e as { name: string }).name === "AbortError");
|
|
218
|
+
|
|
217
219
|
const recomputeCompletion = (): void => {
|
|
218
220
|
if (!textareaEl) return;
|
|
219
221
|
const ctx = detectQuery(textareaEl, completions());
|
|
@@ -230,7 +232,15 @@ const AutocompleteEditor = (props: AutocompleteEditorProps) => {
|
|
|
230
232
|
currentAbort = new AbortController();
|
|
231
233
|
const signal = currentAbort.signal;
|
|
232
234
|
|
|
233
|
-
|
|
235
|
+
let result: ReturnType<typeof resolveSuggestions>;
|
|
236
|
+
try {
|
|
237
|
+
result = resolveSuggestions(ctx.completion, ctx.query, suggestCtx, signal);
|
|
238
|
+
} catch (e: unknown) {
|
|
239
|
+
if (isAbortError(e)) return;
|
|
240
|
+
setLoading(false);
|
|
241
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
234
244
|
|
|
235
245
|
if (result.kind === "sync") {
|
|
236
246
|
setError(null);
|
|
@@ -239,14 +249,25 @@ const AutocompleteEditor = (props: AutocompleteEditorProps) => {
|
|
|
239
249
|
return;
|
|
240
250
|
}
|
|
241
251
|
|
|
242
|
-
// Async path: keep previous suggestions visible
|
|
243
|
-
//
|
|
252
|
+
// Async path: keep previous suggestions visible only while the
|
|
253
|
+
// same completion token is being refined. A new token/context can
|
|
254
|
+
// mean a different language slot (e.g. GQL source → predicate), so
|
|
255
|
+
// stale rows would be actively misleading.
|
|
256
|
+
const prev = completionState();
|
|
257
|
+
if (prev && (prev.ctx.start !== ctx.start || prev.ctx.completion !== ctx.completion)) {
|
|
258
|
+
setCompletionState(null);
|
|
259
|
+
closeDropdown();
|
|
260
|
+
}
|
|
244
261
|
setError(null);
|
|
245
262
|
setLoading(true);
|
|
246
263
|
lastAsyncCompletion = ctx.completion;
|
|
247
264
|
lastAsyncQuery = ctx.query;
|
|
248
265
|
lastAsyncCtx = suggestCtx;
|
|
249
|
-
|
|
266
|
+
const promise = result.promise.catch((e: unknown) => {
|
|
267
|
+
if (signal.aborted || isAbortError(e)) return [];
|
|
268
|
+
throw e;
|
|
269
|
+
});
|
|
270
|
+
debouncedFetch.debouncedFn(ctx, suggestCtx, promise, signal);
|
|
250
271
|
};
|
|
251
272
|
|
|
252
273
|
/** Take a fresh suggestion list, filter to usable ones, and merge
|
|
@@ -308,7 +329,7 @@ const AutocompleteEditor = (props: AutocompleteEditorProps) => {
|
|
|
308
329
|
applySuggestionList(ctx, list);
|
|
309
330
|
} catch (e: unknown) {
|
|
310
331
|
if (signal.aborted) return;
|
|
311
|
-
if (
|
|
332
|
+
if (isAbortError(e)) return;
|
|
312
333
|
setLoading(false);
|
|
313
334
|
setError(e instanceof Error ? e.message : String(e));
|
|
314
335
|
}
|
|
@@ -652,5 +673,5 @@ const AutocompleteEditor = (props: AutocompleteEditorProps) => {
|
|
|
652
673
|
};
|
|
653
674
|
|
|
654
675
|
export default AutocompleteEditor;
|
|
655
|
-
export type { Completion,
|
|
676
|
+
export type { Completion, SuggestContext, Suggestion } from "../completion";
|
|
656
677
|
export { abbreviations } from "../completion";
|