Commit 4f57718
committed
feat(session): add bi-directional cursor-based pagination for messages
Implements Issue #6548: Cursor-based pagination to support long session histories without performance degradation.
This supersedes PR #6656 by @ry2009, addressing the feedback from that review and adding additional features.
Backend:
- Add `before` and `after` cursor support to Session.messages and API
- Add Binary.lowerBound to util for efficient cursor lookup on ULIDs
- Use Promise.allSettled for graceful handling of deleted messages
- Return RFC 5005 compliant Link headers (rel="prev"/rel="next")
- Return 400 when both cursors specified (mutual exclusion)
- Validate cursors via Zod schema with graceful fallback
TUI:
- Track message_page state with hasOlder/hasNewer flags
- Implement loadOlder/loadNewer with scroll position restoration
- Memory-bound to 500 messages with 50-message eviction chunks
- Skip live SSE inserts when detached from head (hasNewer=true)
- Add error state handling for failed pagination requests
Improvements over PR #6656:
- Bi-directional pagination (before + after cursors)
- Proper parseLinkHeader utility with comprehensive tests
- Memory bounding to prevent unbounded growth
- Error state feedback instead of silent failures
- RFC 5005 compliant Link header semantics
Tests:
- messages-pagination.test.ts: cursor, boundary, deletion tests (5 tests)
- session-messages.test.ts: API validation, Link header tests (4 tests)
- parse-link-header.test.ts: RFC 8288 parser tests (9 tests)
Closes #65481 parent 6b6d6e9 commit 4f57718
File tree
12 files changed
+904
-17
lines changed- packages
- opencode
- src
- cli/cmd/tui
- context
- routes/session
- server
- session
- util
- test
- server
- session
- util
- sdk
- js/src/v2/gen
- util/src
12 files changed
+904
-17
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
31 | 37 | | |
32 | 38 | | |
33 | 39 | | |
| |||
48 | 54 | | |
49 | 55 | | |
50 | 56 | | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
51 | 66 | | |
52 | 67 | | |
53 | 68 | | |
| |||
89 | 104 | | |
90 | 105 | | |
91 | 106 | | |
| 107 | + | |
92 | 108 | | |
93 | 109 | | |
94 | 110 | | |
| |||
226 | 242 | | |
227 | 243 | | |
228 | 244 | | |
229 | | - | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
230 | 248 | | |
231 | | - | |
| 249 | + | |
232 | 250 | | |
233 | 251 | | |
234 | 252 | | |
235 | 253 | | |
236 | | - | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
237 | 258 | | |
238 | 259 | | |
239 | 260 | | |
240 | 261 | | |
241 | | - | |
| 262 | + | |
242 | 263 | | |
243 | 264 | | |
244 | | - | |
245 | 265 | | |
246 | 266 | | |
247 | 267 | | |
| |||
261 | 281 | | |
262 | 282 | | |
263 | 283 | | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
264 | 291 | | |
265 | 292 | | |
266 | 293 | | |
| |||
371 | 398 | | |
372 | 399 | | |
373 | 400 | | |
| 401 | + | |
374 | 402 | | |
375 | 403 | | |
376 | 404 | | |
| |||
404 | 432 | | |
405 | 433 | | |
406 | 434 | | |
| 435 | + | |
| 436 | + | |
407 | 437 | | |
408 | 438 | | |
409 | 439 | | |
| |||
415 | 445 | | |
416 | 446 | | |
417 | 447 | | |
| 448 | + | |
418 | 449 | | |
419 | 450 | | |
420 | 451 | | |
421 | 452 | | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
422 | 563 | | |
423 | 564 | | |
424 | 565 | | |
| |||
Lines changed: 68 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
| 122 | + | |
122 | 123 | | |
123 | 124 | | |
124 | 125 | | |
| |||
128 | 129 | | |
129 | 130 | | |
130 | 131 | | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
131 | 160 | | |
132 | 161 | | |
133 | 162 | | |
| |||
910 | 939 | | |
911 | 940 | | |
912 | 941 | | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
913 | 955 | | |
914 | 956 | | |
915 | 957 | | |
| |||
926 | 968 | | |
927 | 969 | | |
928 | 970 | | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
929 | 987 | | |
930 | 988 | | |
931 | 989 | | |
| |||
1021 | 1079 | | |
1022 | 1080 | | |
1023 | 1081 | | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
1024 | 1092 | | |
1025 | 1093 | | |
1026 | 1094 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| 58 | + | |
58 | 59 | | |
59 | 60 | | |
60 | 61 | | |
| |||
1250 | 1251 | | |
1251 | 1252 | | |
1252 | 1253 | | |
1253 | | - | |
| 1254 | + | |
| 1255 | + | |
| 1256 | + | |
1254 | 1257 | | |
1255 | 1258 | | |
1256 | 1259 | | |
1257 | 1260 | | |
1258 | | - | |
1259 | | - | |
1260 | | - | |
| 1261 | + | |
| 1262 | + | |
| 1263 | + | |
| 1264 | + | |
| 1265 | + | |
| 1266 | + | |
| 1267 | + | |
| 1268 | + | |
| 1269 | + | |
| 1270 | + | |
| 1271 | + | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + | |
| 1275 | + | |
| 1276 | + | |
| 1277 | + | |
| 1278 | + | |
| 1279 | + | |
| 1280 | + | |
| 1281 | + | |
| 1282 | + | |
| 1283 | + | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
1261 | 1293 | | |
1262 | | - | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
| 1298 | + | |
| 1299 | + | |
| 1300 | + | |
| 1301 | + | |
| 1302 | + | |
| 1303 | + | |
| 1304 | + | |
| 1305 | + | |
| 1306 | + | |
| 1307 | + | |
1263 | 1308 | | |
1264 | 1309 | | |
1265 | 1310 | | |
| |||
0 commit comments