Update jq-repeat to 2.1.0; fix editProfile update->slideDown race

jq-repeat 2.1.0 (release notes: https://github.com/wmantly/jq-repeat/releases/tag/v2.1.0)
brings real fixes (throttled-update race conditions, sorted-list
reverse() leaking elements, nested-scope isolation) and a few
behavior changes. Audited every usage in this repo against the
changelog before upgrading:

- push()/unshift() now return the new array length -- every call
  site in this repo is a bare statement, none consume the return
  value. No risk.
- __setPut/__setTake, jr-order-reverse, nested jq-repeat templates:
  not used anywhere in this repo (unlike proxy's companion PR, which
  needed the __setPut/__setTake fix).

Real risk found and fixed: update() is now trailing-edge throttled
(~50ms) even on the first call, not just rapid subsequent ones.
profile.ejs's editUser()/editUserSeccess() call $.scope.editProfile
.update()/renderProfile() (which itself calls update()) and
immediately slideDown() the same element -- with the old synchronous
behavior the form was already populated by then; with throttling it
could briefly show stale/empty data. Deferred both slideUp/slideDown
pairs by 60ms (past the throttle window), per the library's own
migration guidance. Verified live (real bundled image + Playwright,
logged in as admin): the edit form's fields show real data, not
empty/stale, when checked right as the slide-open completes.
This commit is contained in:
2026-07-16 18:27:58 -04:00
parent e2b4ffabb7
commit 88387f3117
3 changed files with 18 additions and 9 deletions
+4 -4
View File
@@ -19,7 +19,7 @@
"express": "^5.2.1",
"express-rate-limit": "^8.5.2",
"extend": "^3.0.2",
"jq-repeat": "^2.0.1",
"jq-repeat": "^2.1.0",
"jquery": "^3.7.1",
"jsonwebtoken": "^9.0.3",
"ldapts": "^8.1.2",
@@ -4357,9 +4357,9 @@
}
},
"node_modules/jq-repeat": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/jq-repeat/-/jq-repeat-2.0.1.tgz",
"integrity": "sha512-ATI25tKQG3uHW8f8XPqBe85JsH4PNGHA/YLy1KgMVeYDoUSf9cqGNBum+4A+Pg1WKh9PA6bYyWfYNsgktwIbSg==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/jq-repeat/-/jq-repeat-2.1.0.tgz",
"integrity": "sha512-e1OmSWeBEHEtyOhNVysx0bnT5wd6HlZ37JZgPcGPmACJ0K9bXDPq0xOwrM1slQMSTw7FOSNDX+MD6VwvPeeZyQ==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
+1 -1
View File
@@ -31,7 +31,7 @@
"express": "^5.2.1",
"express-rate-limit": "^8.5.2",
"extend": "^3.0.2",
"jq-repeat": "^2.0.1",
"jq-repeat": "^2.1.0",
"jquery": "^3.7.1",
"jsonwebtoken": "^9.0.3",
"ldapts": "^8.1.2",
+13 -4
View File
@@ -40,15 +40,24 @@
var $editCard = $('#editProfile');
$.scope.editProfile.update(user);
$profileCard.slideUp();
$editCard.slideDown();
// jq-repeat's update() is trailing-edge throttled (~50ms) as of 2.1.0 --
// wait for the throttle tick to land before sliding the updated card
// into view, or it can briefly show stale/empty data.
setTimeout(function(){
$profileCard.slideUp();
$editCard.slideDown();
}, 60);
}
function editUserSeccess(data){
currentUser = data.results;
renderProfile(currentUser);
$('#editProfile').slideUp();
$('#userProfile').slideDown()
// Same throttle-tick wait as editUser() above -- renderProfile() calls
// $.scope.user.update()/passwordReset.update() internally.
setTimeout(function(){
$('#editProfile').slideUp();
$('#userProfile').slideDown()
}, 60);
}
async function toggleActive(uid, active){