Skip to content

Commit 84ef8a1

Browse files
committed
Merge remote-tracking branch 'upstream/main' into exp-memo
2 parents 4e434f0 + b1a1c78 commit 84ef8a1

File tree

20 files changed

+2438
-416
lines changed

20 files changed

+2438
-416
lines changed

pyi_hashes.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"reflex/__init__.pyi": "224964f24351c79614ab9a4ae47560a0",
2+
"reflex/__init__.pyi": "9823934f0e3fca36228004a6fbb1d8df",
33
"reflex/components/__init__.pyi": "ac05995852baa81062ba3d18fbc489fb",
44
"reflex/components/base/__init__.pyi": "16e47bf19e0d62835a605baa3d039c5a",
55
"reflex/components/base/app_wrap.pyi": "22e94feaa9fe675bcae51c412f5b67f1",
@@ -19,7 +19,7 @@
1919
"reflex/components/core/helmet.pyi": "cb5ac1be02c6f82fcc78ba74651be593",
2020
"reflex/components/core/html.pyi": "4ebe946f3fc097fc2e31dddf7040ec1c",
2121
"reflex/components/core/sticky.pyi": "cb763b986a9b0654d1a3f33440dfcf60",
22-
"reflex/components/core/upload.pyi": "c90782be1b63276b428bce3fd4ce0af2",
22+
"reflex/components/core/upload.pyi": "ca9f7424f3b74b1b56f5c819e8654eeb",
2323
"reflex/components/core/window_events.pyi": "e7af4bf5341c4afaf60c4a534660f68f",
2424
"reflex/components/datadisplay/__init__.pyi": "52755871369acbfd3a96b46b9a11d32e",
2525
"reflex/components/datadisplay/code.pyi": "1d123d19ef08f085422f3023540e7bb1",

reflex/.templates/web/utils/helpers/upload.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ export const uploadFiles = async (
2727
getBackendURL,
2828
getToken,
2929
) => {
30-
// return if there's no file to upload
31-
if (files === undefined || files.length === 0) {
32-
return false;
33-
}
30+
files = files ?? [];
3431

3532
const upload_ref_name = `__upload_controllers_${upload_id}`;
3633

reflex/.templates/web/utils/state.js

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -419,16 +419,6 @@ export const applyEvent = async (event, socket, navigate, params) => {
419419
export const applyRestEvent = async (event, socket, navigate, params) => {
420420
let eventSent = false;
421421
if (event.handler === "uploadFiles") {
422-
if (event.payload.files === undefined || event.payload.files.length === 0) {
423-
// Submit the event over the websocket to trigger the event handler.
424-
return await applyEvent(
425-
ReflexEvent(event.name, { files: [] }),
426-
socket,
427-
navigate,
428-
params,
429-
);
430-
}
431-
432422
// Start upload, but do not wait for it, which would block other events.
433423
uploadFiles(
434424
event.name,
@@ -726,6 +716,53 @@ export const ReflexEvent = (
726716
return { name, payload, handler, event_actions };
727717
};
728718

719+
/**
720+
* Apply event actions before invoking a target function.
721+
* @param {Function} target The function to invoke after applying event actions.
722+
* @param {Object.<string, (number|boolean)>} event_actions The actions to apply.
723+
* @param {Array<any>|any} args The event args.
724+
* @param {string|null} action_key A stable key for debounce/throttle tracking.
725+
* @param {Function|null} temporal_handler Returns whether temporal actions may run.
726+
* @returns The target result, if it runs immediately.
727+
*/
728+
export const applyEventActions = (
729+
target,
730+
event_actions = {},
731+
args = [],
732+
action_key = null,
733+
temporal_handler = null,
734+
) => {
735+
if (!(args instanceof Array)) {
736+
args = [args];
737+
}
738+
739+
const _e = args.find((o) => o?.preventDefault !== undefined);
740+
741+
if (event_actions?.preventDefault && _e?.preventDefault) {
742+
_e.preventDefault();
743+
}
744+
if (event_actions?.stopPropagation && _e?.stopPropagation) {
745+
_e.stopPropagation();
746+
}
747+
if (event_actions?.temporal && temporal_handler && !temporal_handler()) {
748+
return;
749+
}
750+
751+
const invokeTarget = () => target(...args);
752+
const resolved_action_key = action_key ?? target.toString();
753+
754+
if (event_actions?.throttle) {
755+
if (!throttle(resolved_action_key, event_actions.throttle)) {
756+
return;
757+
}
758+
}
759+
if (event_actions?.debounce) {
760+
debounce(resolved_action_key, invokeTarget, event_actions.debounce);
761+
return;
762+
}
763+
return invokeTarget();
764+
};
765+
729766
/**
730767
* Package client-side storage values as payload to send to the
731768
* backend with the hydrate event
@@ -898,51 +935,24 @@ export const useEventLoop = (
898935
// Function to add new events to the event queue.
899936
const addEvents = useCallback((events, args, event_actions) => {
900937
const _events = events.filter((e) => e !== undefined && e !== null);
901-
if (!event_actions?.temporal) {
902-
// Reconnect socket if needed for non-temporal events.
903-
ensureSocketConnected();
904-
}
905-
906-
if (!(args instanceof Array)) {
907-
args = [args];
908-
}
909938

910939
event_actions = _events.reduce(
911940
(acc, e) => ({ ...acc, ...e.event_actions }),
912941
event_actions ?? {},
913942
);
914943

915-
const _e = args.filter((o) => o?.preventDefault !== undefined)[0];
916-
917-
if (event_actions?.preventDefault && _e?.preventDefault) {
918-
_e.preventDefault();
919-
}
920-
if (event_actions?.stopPropagation && _e?.stopPropagation) {
921-
_e.stopPropagation();
922-
}
923-
const combined_name = _events.map((e) => e.name).join("+++");
924-
if (event_actions?.temporal) {
925-
if (!socket.current || !socket.current.connected) {
926-
return; // don't queue when the backend is not connected
927-
}
928-
}
929-
if (event_actions?.throttle) {
930-
// If throttle returns false, the events are not added to the queue.
931-
if (!throttle(combined_name, event_actions.throttle)) {
932-
return;
933-
}
934-
}
935-
if (event_actions?.debounce) {
936-
// If debounce is used, queue the events after some delay
937-
debounce(
938-
combined_name,
939-
() =>
940-
queueEvents(_events, socket, false, navigate, () => params.current),
941-
event_actions.debounce,
942-
);
943-
} else {
944-
queueEvents(_events, socket, false, navigate, () => params.current);
944+
if (!event_actions?.temporal) {
945+
// Reconnect socket if needed for non-temporal events.
946+
ensureSocketConnected();
945947
}
948+
949+
return applyEventActions(
950+
() => queueEvents(_events, socket, false, navigate, () => params.current),
951+
event_actions,
952+
args,
953+
_events.map((e) => e.name).join("+++"),
954+
() => !!socket.current?.connected,
955+
);
946956
}, []);
947957

948958
const sentHydrate = useRef(false); // Avoid double-hydrate due to React strict-mode

reflex/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@
297297
"config": ["Config", "DBConfig"],
298298
"constants": ["Env"],
299299
"constants.colors": ["Color"],
300+
"_upload": [
301+
"UploadChunk",
302+
"UploadChunkIterator",
303+
],
300304
"event": [
301305
"event",
302306
"EventChain",
@@ -320,6 +324,7 @@
320324
"set_value",
321325
"stop_propagation",
322326
"upload_files",
327+
"upload_files_chunk",
323328
"window_alert",
324329
],
325330
"istate.storage": [

0 commit comments

Comments
 (0)