querysub 0.471.0 → 0.472.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/package.json
CHANGED
|
@@ -1664,7 +1664,7 @@ export class PathValueProxyWatcher {
|
|
|
1664
1664
|
|
|
1665
1665
|
let maxLocks = watcher.options.maxLocksOverride || DEFAULT_MAX_LOCKS;
|
|
1666
1666
|
if (locks.length > maxLocks) {
|
|
1667
|
-
throw new Error(`Too many locks for ${watcher.debugName} (${locks.length} > ${maxLocks}). Use Querysub.noLocks(() => ...) around code that is accessing too many values, assuming you don't want to lock them. You can override max locks with maxLocksOverride (in options / functionMetadata). Some locks are ${JSON.stringify(locks.slice(
|
|
1667
|
+
throw new Error(`Too many locks for ${watcher.debugName} (${locks.length} > ${maxLocks}). Use Querysub.noLocks(() => ...) around code that is accessing too many values, assuming you don't want to lock them. You can override max locks with maxLocksOverride (in options / functionMetadata). Some locks are ${JSON.stringify(locks.slice(-10).map(x => ({ path: x.path, startTime: x.startTime, endTime: x.endTime })))}.`);
|
|
1668
1668
|
}
|
|
1669
1669
|
|
|
1670
1670
|
|
|
@@ -144,6 +144,10 @@ export function writeFunctionCall(config: {
|
|
|
144
144
|
}) {
|
|
145
145
|
let { domainName, moduleId, functionId, args, metadata } = config;
|
|
146
146
|
|
|
147
|
+
if (isNode() && !curInterceptor) {
|
|
148
|
+
throw new Error(`Naked function writes are not allowed serverside. Wrap your code in a Querysub.commitAsync!`);
|
|
149
|
+
}
|
|
150
|
+
|
|
147
151
|
// NOTE: Having this be an always-increasing time means that at least if it's the same client making the call ID, the numbers will always be increasing. So we can go from the call ID to determine the order of the calls, which is extremely useful.
|
|
148
152
|
let now = getTimeUnique();
|
|
149
153
|
// IMPORTANT! CallId MUST be secure, otherwise other users can guess it, and read our calls
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { css } from "typesafecss";
|
|
2
|
+
import { InputProps } from "./Input";
|
|
3
|
+
import { qreact } from "../4-dom/qreact";
|
|
4
|
+
|
|
5
|
+
export class InputAutocomplete extends qreact.Component<InputProps & {
|
|
6
|
+
value: string | { value: string };
|
|
7
|
+
label?: string;
|
|
8
|
+
options: string[];
|
|
9
|
+
onChangeValue: (value: string) => void;
|
|
10
|
+
focusOnMount?: boolean;
|
|
11
|
+
}> {
|
|
12
|
+
handleInput = (e: Event) => {
|
|
13
|
+
const input = e.currentTarget as HTMLInputElement;
|
|
14
|
+
const inputEvent = e as InputEvent;
|
|
15
|
+
|
|
16
|
+
// Only autocomplete on text insertion, not deletion
|
|
17
|
+
if (!inputEvent.inputType || !inputEvent.inputType.startsWith("insert")) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const selectionStart = input.selectionStart || 0;
|
|
22
|
+
const userTyped = input.value.slice(0, selectionStart);
|
|
23
|
+
|
|
24
|
+
if (!userTyped) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Find matching character names
|
|
29
|
+
const options = this.props.options;
|
|
30
|
+
const lowerUserTyped = userTyped.toLowerCase();
|
|
31
|
+
const match = options.find(name =>
|
|
32
|
+
name.toLowerCase().startsWith(lowerUserTyped)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (match) {
|
|
36
|
+
// Replace with the matched name's casing
|
|
37
|
+
input.value = match;
|
|
38
|
+
input.setSelectionRange(userTyped.length, match.length);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
handleKeyDown = (e: KeyboardEvent) => {
|
|
43
|
+
const input = e.currentTarget as HTMLInputElement;
|
|
44
|
+
|
|
45
|
+
if (e.key === "Tab" || e.key === "Enter") {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
this.props.onChangeValue(input.value);
|
|
48
|
+
input.blur();
|
|
49
|
+
} else if (e.key === "Escape") {
|
|
50
|
+
input.value = this.getValue();
|
|
51
|
+
input.blur();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
handleBlur = (e: FocusEvent) => {
|
|
56
|
+
const input = e.currentTarget as HTMLInputElement;
|
|
57
|
+
this.props.onChangeValue(input.value);
|
|
58
|
+
};
|
|
59
|
+
getValue() {
|
|
60
|
+
if (typeof this.props.value === "string") {
|
|
61
|
+
return this.props.value;
|
|
62
|
+
}
|
|
63
|
+
return this.props.value.value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
render() {
|
|
67
|
+
let { value, options, onChangeValue, focusOnMount, ...nativeProps } = this.props;
|
|
68
|
+
const styleClass = (
|
|
69
|
+
css.border("1px solid hsl(0, 0%, 50%)", "soft")
|
|
70
|
+
.background("hsl(0, 0%, 7%)", "soft")
|
|
71
|
+
.color("hsl(0, 0%, 95%)", "soft")
|
|
72
|
+
.display("flex", "soft")
|
|
73
|
+
.outline("3px solid hsl(204, 100%, 50%)", "focus", "soft")
|
|
74
|
+
+ " " + css.width("100%", "soft")
|
|
75
|
+
+ " " + (nativeProps.className || "")
|
|
76
|
+
);
|
|
77
|
+
return (
|
|
78
|
+
<input
|
|
79
|
+
{...nativeProps as any}
|
|
80
|
+
ref={elem => {
|
|
81
|
+
if (elem) {
|
|
82
|
+
elem.value = this.getValue();
|
|
83
|
+
if (focusOnMount) {
|
|
84
|
+
setTimeout(() => {
|
|
85
|
+
elem.focus();
|
|
86
|
+
elem.select();
|
|
87
|
+
}, 0);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}}
|
|
91
|
+
type="text"
|
|
92
|
+
onFocus={e => (e.currentTarget as HTMLInputElement).select()}
|
|
93
|
+
onInput={this.handleInput}
|
|
94
|
+
onKeyDown={this.handleKeyDown}
|
|
95
|
+
onBlur={this.handleBlur}
|
|
96
|
+
className={styleClass}
|
|
97
|
+
/>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -12,9 +12,9 @@ function onUncaught(...args: unknown[]) {
|
|
|
12
12
|
}
|
|
13
13
|
// Ignore ResizeObserver errors, they are spurious
|
|
14
14
|
// - https://github.com/vercel/next.js/discussions/51551
|
|
15
|
-
if (error.message
|
|
15
|
+
if (error.message?.startsWith("ResizeObserver loop")) return;
|
|
16
16
|
// We should really do this better. Basically, if we're disposing or canceling, it's not actually an error, just ignore it.
|
|
17
|
-
if (error.message
|
|
17
|
+
if (error.message?.startsWith("Dispose")) return;
|
|
18
18
|
|
|
19
19
|
onMessage({
|
|
20
20
|
type: "error",
|