{"payload":{"feedbackUrl":"https://github.com/orgs/community/discussions/53140","repo":{"id":689102279,"defaultBranch":"main","name":"river","ownerLogin":"replit","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2023-09-08T20:04:13.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/983194?v=4","public":true,"private":false,"isOrgOwned":true},"refInfo":{"name":"","listCacheKey":"v0:1720560655.0","currentOid":""},"activityList":{"items":[{"before":"f165b81342d31e90cff62fbc75ae57fc24a690fb","after":null,"ref":"refs/heads/jackyzha0/uds-destroy","pushedAt":"2024-07-09T21:30:55.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"}},{"before":"72e4fc8d02263e551d66ee5f0995707e8fa6cd1b","after":"e5e74af5603f67fa15ab27fdec47fbf06b932443","ref":"refs/heads/main","pushedAt":"2024-07-09T21:30:53.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"uds: clear received buffer on _flush (#229)\n\n## Why\r\n\r\n- it is safe to lose data here\r\n\r\n\r\n\r\n## What changed\r\n\r\n- make it so `receivedBuffer` gets yoinked on flush and no longer errors\r\nif theres outstanding data\r\n\r\n\r\n\r\n## Versioning\r\n\r\n- [ ] Breaking protocol change\r\n- [ ] Breaking ts/js API change\r\n\r\n","shortMessageHtmlLink":"uds: clear received buffer on _flush (#229)"}},{"before":"7dca464207e35c8566074402557df41847e61676","after":"f165b81342d31e90cff62fbc75ae57fc24a690fb","ref":"refs/heads/jackyzha0/uds-destroy","pushedAt":"2024-07-09T21:28:40.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"fix tests","shortMessageHtmlLink":"fix tests"}},{"before":"695a505e6292564e062d5636ca0a1d6e7c27b5a7","after":"4ecea88e4a0d22500617547b5c5006da651f7349","ref":"refs/heads/jackyzha0/stabilize-0.24","pushedAt":"2024-07-09T21:15:38.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"fix test","shortMessageHtmlLink":"fix test"}},{"before":"f20b285b7934b1410e8d7e3173365d5c2023889d","after":"695a505e6292564e062d5636ca0a1d6e7c27b5a7","ref":"refs/heads/jackyzha0/stabilize-0.24","pushedAt":"2024-07-09T21:14:48.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"use 0.25.0 instead","shortMessageHtmlLink":"use 0.25.0 instead"}},{"before":null,"after":"7dca464207e35c8566074402557df41847e61676","ref":"refs/heads/jackyzha0/uds-destroy","pushedAt":"2024-07-09T21:09:16.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"ok to clear framing buffer on _flush","shortMessageHtmlLink":"ok to clear framing buffer on _flush"}},{"before":"7ac0c0d2f394033aaa960ec3e6f1a0cf695eeab4","after":"4e7679652e779cbd33daaea7c908abb5027fe5d5","ref":"refs/heads/protocolv2","pushedAt":"2024-07-09T20:27:38.000Z","pushType":"push","commitsCount":2,"pusher":{"login":"masad-frost","name":"Faris Masad","path":"/masad-frost","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1994028?s=80&v=4"},"commit":{"message":"0.200.0-rc.3","shortMessageHtmlLink":"0.200.0-rc.3"}},{"before":"4b9c39decd973c5417e31c750f898dd0a55e4d42","after":"7ac0c0d2f394033aaa960ec3e6f1a0cf695eeab4","ref":"refs/heads/protocolv2","pushedAt":"2024-07-09T20:22:50.000Z","pushType":"push","commitsCount":7,"pusher":{"login":"masad-frost","name":"Faris Masad","path":"/masad-frost","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1994028?s=80&v=4"},"commit":{"message":"Merge remote-tracking branch 'origin/main' into protocolv2","shortMessageHtmlLink":"Merge remote-tracking branch 'origin/main' into protocolv2"}},{"before":"029fe37517002d96c075cf790c6a7652e5dd5955","after":"4b9c39decd973c5417e31c750f898dd0a55e4d42","ref":"refs/heads/protocolv2","pushedAt":"2024-07-09T18:22:03.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"masad-frost","name":"Faris Masad","path":"/masad-frost","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1994028?s=80&v=4"},"commit":{"message":"0.200.0-rc.2","shortMessageHtmlLink":"0.200.0-rc.2"}},{"before":"46c4bd44ca422aec44cc4abc58339d3c2670c871","after":"f20b285b7934b1410e8d7e3173365d5c2023889d","ref":"refs/heads/jackyzha0/stabilize-0.24","pushedAt":"2024-07-09T00:33:19.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"bump pkg","shortMessageHtmlLink":"bump pkg"}},{"before":null,"after":"46c4bd44ca422aec44cc4abc58339d3c2670c871","ref":"refs/heads/jackyzha0/stabilize-0.24","pushedAt":"2024-07-09T00:32:44.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"change state options to be objects instead of long param lists, stabilize optionals","shortMessageHtmlLink":"change state options to be objects instead of long param lists, stabi…"}},{"before":"5f8d05aacc54ef08e3cfbdba39d1045f235cabbc","after":null,"ref":"refs/heads/jackyzha0/re-expose-sessionid-in-handler","pushedAt":"2024-07-08T23:05:27.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"}},{"before":"3d14daba41387ed55799a3d34ad6ce30b97af615","after":"72e4fc8d02263e551d66ee5f0995707e8fa6cd1b","ref":"refs/heads/main","pushedAt":"2024-07-08T23:05:26.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"allow session id again (#227)\n\n## Why\r\n\r\n\r\n\r\n- some handlers relied on session id before to identify session changes,\r\netc.\r\n\r\n## What changed\r\n\r\n\r\n\r\n- expose `sessionId` to handlers again via `context`\r\n\r\n## Versioning\r\n\r\n- [ ] Breaking protocol change\r\n- [ ] Breaking ts/js API change\r\n\r\n","shortMessageHtmlLink":"allow session id again (#227)"}},{"before":"e09202436cfe730c9630bb4a85d0ddea970af3b1","after":"5f8d05aacc54ef08e3cfbdba39d1045f235cabbc","ref":"refs/heads/jackyzha0/re-expose-sessionid-in-handler","pushedAt":"2024-07-08T23:01:48.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"bump pkg lock","shortMessageHtmlLink":"bump pkg lock"}},{"before":null,"after":"e09202436cfe730c9630bb4a85d0ddea970af3b1","ref":"refs/heads/jackyzha0/re-expose-sessionid-in-handler","pushedAt":"2024-07-08T22:59:03.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"allow session id again'","shortMessageHtmlLink":"allow session id again'"}},{"before":"11e34e8895f575c91568e87449d46c160d18623d","after":null,"ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-08T22:39:24.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"}},{"before":"dddc63c5492b6ded1dff94cce70119cc18080c0d","after":"3d14daba41387ed55799a3d34ad6ce30b97af615","ref":"refs/heads/main","pushedAt":"2024-07-08T22:39:22.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"Use a state machine to manage session state transitions (#220)\n\n## Why\r\n\r\nKeeping track of what handlers are registered when and knowing when to\r\ncleanup/register new callbacks and fields in a session's lifecycle is\r\nreally difficult. Let's encode valid states via a state machine and make\r\nillegal states unrepresentable.\r\n\r\nThis PR also addresses two other problems that are heavily tied to the\r\nsession lifecycle:\r\n- Message order synchronization during handshake: we used to synchronize\r\n`nextExpectedSeq` in the handshake which is useful to detect desyncs in\r\nserver to client direction (that is, if the server was about to send a\r\nmessage that would cause the client to receive an out-of-order message,\r\nwe should just close the session there instead of continuing). However,\r\nwe never did this check in the other direction.\r\n- Relying on browser timers: we used to rely on a client-side\r\n`setInterval` to send heartbeat messages to the server and the server\r\nwould kill the client if it didn't send heartbeats frequently enough.\r\nTurns out that Chromium _heavily_ throttles intervals when backgrounded\r\n(source:\r\nhttps://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h;l=54?q=kDefaultThrottledWakeUpInterval&ss=chromium%2Fchromium%2Fsrc)\r\nso a `setInterval` for, say 3s, could take up to 60s to actually fire.\r\nThis meant connections were getting killed far too frequently. However,\r\nif we make the timers server authoritative, the client can always\r\nrespond to server heartbeats as data-listener-based wakeups are not\r\nthrottled :)\r\n\r\n## What changed\r\n\r\n- Implement a state machine that supports async-transitions via a\r\ncallback-based system. We use a proxy to ensure that session states\r\nwe've transitioned from cannot be used again.\r\n- Each state registers what to do on state exit and on close (exiting\r\nfrom the state machine entirely, e.g. closing the session object) so we\r\nhave consistent cleanups that don't leak. This has been the source of\r\nquite a few bugs.\r\n- Made heartbeats server authoritative.\r\n- Clients no longer schedule their own heartbeats. Instead, it responds\r\ndirectly to any server-sent heartbeats.\r\n- Servers are responsible for closing a connection on too many heartbeat\r\nmisses.\r\n- This is ok even in the case of phantom disconnects as closing the\r\nunderlying TCP conn will still propagate in the case of a WebSocket\r\ntransport (and UDS cannot have phantom disconnects)\r\n- Update the handshake messages\r\n- No longer sends `reconnect`, this can be inferred a combination of\r\n`nextExpectedSeq` and `nextSentSeq`\r\n- Now relies on `sessionId` to generate the ID on the session on the\r\nserver side so the IDs of the client session and the server session\r\nmatch\r\n- Now sends `nextSentSeq`. We do some more comparison here to check for\r\nmismatched session state before calling the handshake ok. Specifically,\r\nthere are two cases where we cannot accept a session:\r\n\t - the client is in the future (`client.nextSentSeq > server.ack`)\r\n\t - server is in the future (`server.seq > client.nextExpectedSeq`)\r\n- Distinguish retriable handshake failures from fatal ones.\r\n- Only a session state mismatch is retriable (i.e. kill the session and\r\nstart over), everything else should be 'fatal' and stop retrying.\r\n- Testing infra changes\r\n- Made constructing a transport not automatically connect by default. We\r\nhad cases where we registered listeners _after_ connecting and would\r\nmiss some events.\r\n- No longer expose connections to the transport (it doesn't manage\r\nthese! it shouldn't be able to introspect connections). I pulled these\r\nout into test helpers `numberOfConnections(transport)` and\r\n`closeAllConnections(transport)` which covers our existing use cases.\r\n\r\n## Versioning\r\n\r\n- [ ] Breaking protocol change\r\n- [x] Breaking ts/js API change\r\n\r\n","shortMessageHtmlLink":"Use a state machine to manage session state transitions (#220)"}},{"before":"164bb578fc2c5a22b76c288af279bd1f0a7493f0","after":"11e34e8895f575c91568e87449d46c160d18623d","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-08T22:35:10.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"format lol","shortMessageHtmlLink":"format lol"}},{"before":"dfd4fdf15a965ad96d7bee01d63875f5c9de3448","after":"164bb578fc2c5a22b76c288af279bd1f0a7493f0","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-08T22:33:40.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"address review comments","shortMessageHtmlLink":"address review comments"}},{"before":"c613aadccf11cd85fbc3f748e59df9bd17009eb9","after":"dfd4fdf15a965ad96d7bee01d63875f5c9de3448","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-05T22:48:33.000Z","pushType":"push","commitsCount":2,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"rename PendingIdentification -> WaitingForHandshake","shortMessageHtmlLink":"rename PendingIdentification -> WaitingForHandshake"}},{"before":"9d9812caea9e49e72765c0cf88d2bfc2fdbdeb64","after":"c613aadccf11cd85fbc3f748e59df9bd17009eb9","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-05T21:47:39.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"fix circular import for chunk opt","shortMessageHtmlLink":"fix circular import for chunk opt"}},{"before":"7c2d7c55a6ffef4da5613ea90bd5a4c93e62bc5a","after":null,"ref":"refs/heads/fm-write-stream-onclose","pushedAt":"2024-07-05T21:39:57.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"masad-frost","name":"Faris Masad","path":"/masad-frost","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1994028?s=80&v=4"}},{"before":"1545321efb374809888cf4eeebf15214fed2b864","after":"029fe37517002d96c075cf790c6a7652e5dd5955","ref":"refs/heads/protocolv2","pushedAt":"2024-07-05T21:39:55.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"masad-frost","name":"Faris Masad","path":"/masad-frost","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1994028?s=80&v=4"},"commit":{"message":"[protocolv2] Allow listening for close on WriteStream (#226)\n\n## Why\r\n\r\nI ended up needing this in river-babel, it's probably a useful API to\r\nhave\r\n\r\n## What changed\r\n\r\n- Added `WriteStream.onClose`\r\n- Unrelated: Made `WriteStream.close` lose reference to `onCloseRequest`\r\nlisteners and unset `write` function","shortMessageHtmlLink":"[protocolv2] Allow listening for close on WriteStream (#226)"}},{"before":null,"after":"7c2d7c55a6ffef4da5613ea90bd5a4c93e62bc5a","ref":"refs/heads/fm-write-stream-onclose","pushedAt":"2024-07-05T21:38:26.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"masad-frost","name":"Faris Masad","path":"/masad-frost","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1994028?s=80&v=4"},"commit":{"message":"[protocolv2] Allow listening for close on WriteStream\nI ended up needing this in river-babel, it's probably a useful API to have","shortMessageHtmlLink":"[protocolv2] Allow listening for close on WriteStream"}},{"before":"ae2cd4744e9fc965013955bc113f8ff348e6073a","after":"9d9812caea9e49e72765c0cf88d2bfc2fdbdeb64","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-05T20:54:55.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"fmt skull emoji","shortMessageHtmlLink":"fmt skull emoji"}},{"before":"94631cf99d6170c5368067187de4f8220e5ed118","after":"ae2cd4744e9fc965013955bc113f8ff348e6073a","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-05T20:53:13.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"update protocol docs","shortMessageHtmlLink":"update protocol docs"}},{"before":"10488c90d1746c7bb0149950dcd48c64dc669c94","after":"94631cf99d6170c5368067187de4f8220e5ed118","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-05T20:18:16.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"add extra connect statements now that the transport setup doesnt connect automatically","shortMessageHtmlLink":"add extra connect statements now that the transport setup doesnt conn…"}},{"before":"22e1757bd70f4e844aa4f89482ea6b6261ecd589","after":"10488c90d1746c7bb0149950dcd48c64dc669c94","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-05T20:10:46.000Z","pushType":"push","commitsCount":7,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"rebase off main","shortMessageHtmlLink":"rebase off main"}},{"before":"34d27eb02fbf1aa92ad6ccd09c9ae58319b5b7b7","after":"22e1757bd70f4e844aa4f89482ea6b6261ecd589","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-05T19:51:53.000Z","pushType":"push","commitsCount":2,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"fix up the tests","shortMessageHtmlLink":"fix up the tests"}},{"before":"dda67dcb72e94c59a9f53d751087d9e975678054","after":"34d27eb02fbf1aa92ad6ccd09c9ae58319b5b7b7","ref":"refs/heads/jackyzha0/state-machine","pushedAt":"2024-07-03T23:56:42.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jackyzha0","name":"Jacky Zhao","path":"/jackyzha0","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/23178940?s=80&v=4"},"commit":{"message":"checkpoint tests","shortMessageHtmlLink":"checkpoint tests"}}],"hasNextPage":true,"hasPreviousPage":false,"activityType":"all","actor":null,"timePeriod":"all","sort":"DESC","perPage":30,"cursor":"djE6ks8AAAAEex03NgA","startCursor":null,"endCursor":null}},"title":"Activity · replit/river"}