{"payload":{"feedbackUrl":"https://github.com/orgs/community/discussions/53140","repo":{"id":9156525,"defaultBranch":"master","name":"sharedb","ownerLogin":"share","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2013-04-01T21:30:46.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/969675?v=4","public":true,"private":false,"isOrgOwned":true},"refInfo":{"name":"","listCacheKey":"v0:1716979935.0","currentOid":""},"activityList":{"items":[{"before":"308ba34c479c125d1d4c7edaa6d791ef5fcbcdc7","after":null,"ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T10:52:15.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"}},{"before":null,"after":"24dc1ef462531d0c83f600c36293708acf61491f","ref":"refs/heads/submit-id","pushedAt":"2024-05-29T10:49:17.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"โœ… Unique ID per test in `submit` tests\n\nWe've had some issues with state from one test bleeding into another.\n\nThis happens because all of our `submit.js` tests use the same\ncollection and ID.\n\nThis change makes them instead use random IDs for each test, which\nshould give each test better isolation from other tests.","shortMessageHtmlLink":"โœ… Unique ID per test in submit tests"}},{"before":null,"after":"75b2a14ba6214da774bea7e698e6f28862edda03","ref":"refs/heads/create-test-fix","pushedAt":"2024-05-29T10:45:59.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"โœ… Fix create resubmit test\n\nOne of our tests currently checks resubmitting a create op after\nreconnecting during submission.\n\nHowever, since reconnection happens so quickly, this test case can cause\ntwo commit attempts in parallel.\n\nWe currently only wait for the first request to resolve, which means\nthat the second request can continue into the next test, causing\nunexpected test failures.\n\nThis change waits for both acks to be sent before finishing the test.","shortMessageHtmlLink":"โœ… Fix create resubmit test"}},{"before":"9b18170a4eb6f314d5f9f11a18a65471f76c1111","after":"308ba34c479c125d1d4c7edaa6d791ef5fcbcdc7","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T10:17:54.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"2ac1858a536278b270e14b6e8989e8f3c5fe9656","after":"9b18170a4eb6f314d5f9f11a18a65471f76c1111","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T10:15:34.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"c013812c8833cbc2c9b3a41a415b25fa1effc5ab","after":"2ac1858a536278b270e14b6e8989e8f3c5fe9656","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T10:05:25.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"4d074b4e369ebff207909871fbd5d6fb0b4b4105","after":"c013812c8833cbc2c9b3a41a415b25fa1effc5ab","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T10:00:45.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"ff43a8d722182a79009047f93cf85eb0f6ba2fb8","after":"4d074b4e369ebff207909871fbd5d6fb0b4b4105","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T09:56:55.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"7b87fbc000b25ee6ac25c60510cf5da780f39ca4","after":"ff43a8d722182a79009047f93cf85eb0f6ba2fb8","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T09:49:45.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"5bde96707dd8987e1f2f64b2730916715bccfb85","after":"7b87fbc000b25ee6ac25c60510cf5da780f39ca4","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T09:45:34.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"a1aff36d1c111e5eaa22f72b07dccd66895e0fc0","after":"5bde96707dd8987e1f2f64b2730916715bccfb85","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T09:36:17.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"0ae585f3f07e91967c38b0410ad2db11c6aaebdf","after":"a1aff36d1c111e5eaa22f72b07dccd66895e0fc0","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T09:27:13.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"5aeaf89254b975c0d78b854f4843cbf4cbf70244","after":"0ae585f3f07e91967c38b0410ad2db11c6aaebdf","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T09:22:50.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"bc3c4e44ed85f09c39b9cfae1cdfbe25b057750f","after":"5aeaf89254b975c0d78b854f4843cbf4cbf70244","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T09:08:16.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"b05877b7134bcd7f5eb65950bfa36055b780409a","after":"bc3c4e44ed85f09c39b9cfae1cdfbe25b057750f","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T08:26:15.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":null,"after":"b05877b7134bcd7f5eb65950bfa36055b780409a","ref":"refs/heads/debug-mongo","pushedAt":"2024-05-29T08:22:37.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"wip","shortMessageHtmlLink":"wip"}},{"before":"7378ab71ea6c1bed80e4e1b6a450b46210bde2b6","after":"c8de10c6a341a727e0618c72e137685bcc92b35a","ref":"refs/heads/create-error-fix","pushedAt":"2024-05-29T07:44:37.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"๐Ÿ› Fix error handling in `_fetchCreateOpVersion()`\n\nWe're currently not returning errors from the database adapter if there\nare issues fetching the committed op, because of a code typo.\n\nThis change adds coverage for this case and fixes the bug.","shortMessageHtmlLink":"๐Ÿ› Fix error handling in _fetchCreateOpVersion()"}},{"before":"e0a069ea27cb64969fe13af399146fd01057f6ac","after":"7378ab71ea6c1bed80e4e1b6a450b46210bde2b6","ref":"refs/heads/create-error-fix","pushedAt":"2024-05-29T07:31:02.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"๐Ÿ› Fix error handling in `_fetchCreateOpVersion()`\n\nWe're currently not returning errors from the database adapter if there\nare issues fetching the committed op, because of a code typo.\n\nThis change adds coverage for this case and fixes the bug.","shortMessageHtmlLink":"๐Ÿ› Fix error handling in _fetchCreateOpVersion()"}},{"before":null,"after":"e0a069ea27cb64969fe13af399146fd01057f6ac","ref":"refs/heads/create-error-fix","pushedAt":"2024-05-29T07:28:30.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"๐Ÿ› Fix error handling in `_fetchCreateOpVersion()`\n\nWe're currently not returning errors from the database adapter if there\nare issues fetching the committed op, because of a code typo.\n\nThis change adds coverage for this case and fixes the bug.","shortMessageHtmlLink":"๐Ÿ› Fix error handling in _fetchCreateOpVersion()"}},{"before":"eff464d02ac10cfe5235b7a95f4836e23d032395","after":"7abe65049add9b58e1df638aa34e7ca2c0a1fcfa","ref":"refs/heads/master","pushedAt":"2024-05-28T16:37:10.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"5.0.1","shortMessageHtmlLink":"5.0.1"}},{"before":"d8ba01cd429498a1fd420540745ddf8fe225502e","after":null,"ref":"refs/heads/no-commited-op","pushedAt":"2024-05-28T16:36:54.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"}},{"before":"5e5f1b489c20f064c523c20306322b49e3486ab7","after":null,"ref":"refs/heads/src-seq-create-meta","pushedAt":"2024-05-28T16:23:04.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"}},{"before":"f4effa3a73c840cfeff8ed59371fda16516d7ad9","after":"eff464d02ac10cfe5235b7a95f4836e23d032395","ref":"refs/heads/master","pushedAt":"2024-05-28T16:23:03.000Z","pushType":"pr_merge","commitsCount":2,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"Merge pull request #659 from share/src-seq-create-meta\n\n๐Ÿ—ƒ Add `_create` metadata to snapshots to avoid `getCommittedOpVersion()`","shortMessageHtmlLink":"Merge pull request #659 from share/src-seq-create-meta"}},{"before":"efabb26b6a539d985f7653d90aab7abc4e7f1c45","after":"5e5f1b489c20f064c523c20306322b49e3486ab7","ref":"refs/heads/src-seq-create-meta","pushedAt":"2024-05-28T16:20:45.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"๐Ÿ—ƒ Add `_create` metadata to snapshots to avoid `getCommittedOpVersion()`\n\nSupersedes https://github.com/share/sharedb/pull/657\n\nThe `DB.getCommitedOpVersion()` function is only used [in one place][1]:\nin a corner case that differentiates between two \"blind\", versionless\n(created without first fetching) create op conflict cases:\n\n - a versionless create op that conflicts with another create op\n - a versionless create op that has been re-submitted because the\n connection was closed before the ack was received\n\nThe first of these cases should result in an error, and the second is\nnon-fatal and the error can be swallowed.\n\nAt the moment, this differentiation is made using the special\n`DB.getCommittedOpVersion()` function, which - given an op with a\n`src` and `seq` combination - will return `null` if the op hasn't been\ncommitted, or its version number if it has.\n\nIf the op has a committed version number, we know that the submit is a\nduplicate, and we can safely ignore it.\n\nThis approach is problematic, because:\n\n - it [needs a whole op index][2] just to handle this niche corner case\n - the default behaviour [fetches **all** ops][3] unless the driver\n overrides this behaviour\n\nThis change proposes that we actually don't need this function in most\ncases, and implements an alternative approach to differentiate between\nthe above cases.\n\nWhen creating an snapshot, we store the `src`, `seq` and `v` of the op\nthat was used to create it.\n\nIf a conflicting `create` is received, we can then compare directly with\nthis metadata, without needing to fetch anything extra from the\ndatabase.\n\nThis should work in the majority of cases, but won't work if the\nmetadata is missing, which could happen if:\n\n - the snapshot is \"old\": it was created before this change\n - the driver doesn't support metadata (eg [Postgres][4])\n\nIn the case where metadata is unavailable, we fall back to the existing\nmethod, using `getCommittedOpVersion()`. However, if drivers support\nmetadata, this should happen sufficiently infrequently that consumers\ncould potentially remove the `src`/`seq`/`v` index with no noticeable\nperformance penalty.\n\n[1]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/submit-request.js#L112\n[2]: https://github.com/share/sharedb-mongo/issues/94\n[3]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/db/index.js#L69\n[4]: https://github.com/share/sharedb-postgres/blob/499702acd478645bcc249fa50ba6fc066d257d04/index.js#L140","shortMessageHtmlLink":"๐Ÿ—ƒ Add _create metadata to snapshots to avoid getCommittedOpVersion()"}},{"before":"7ba7f0be75862a48234cdbb6d183ae20aec8312d","after":"efabb26b6a539d985f7653d90aab7abc4e7f1c45","ref":"refs/heads/src-seq-create-meta","pushedAt":"2024-05-23T07:20:20.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"๐Ÿ—ƒ Add `_create` metadata to snapshots to avoid `getCommittedOpVersion()`\n\nSupersedes https://github.com/share/sharedb/pull/657\n\nThe `DB.getCommitedOpVersion()` function is only used [in one place][1]:\nin a corner case that differentiates between two \"blind\", versionless\n(created without first fetching) create op conflict cases:\n\n - a versionless create op that conflicts with another create op\n - a versionless create op that has been re-submitted because the\n connection was closed before the ack was received\n\nThe first of these cases should result in an error, and the second is\nnon-fatal and the error can be swallowed.\n\nAt the moment, this differentiation is made using the special\n`DB.getCommittedOpVersion()` function, which - given an op with a\n`src` and `seq` combination - will return `null` if the op hasn't been\ncommitted, or its version number if it has.\n\nIf the op has a committed version number, we know that the submit is a\nduplicate, and we can safely ignore it.\n\nThis approach is problematic, because:\n\n - it [needs a whole op index][2] just to handle this niche corner case\n - the default behaviour [fetches **all** ops][3] unless the driver\n overrides this behaviour\n\nThis change proposes that we actually don't need this function in most\ncases, and implements an alternative approach to differentiate between\nthe above cases.\n\nWhen creating an snapshot, we store the `src`, `seq` and `v` of the op\nthat was used to create it.\n\nIf a conflicting `create` is received, we can then compare directly with\nthis metadata, without needing to fetch anything extra from the\ndatabase.\n\nThis should work in the majority of cases, but won't work if the\nmetadata is missing, which could happen if:\n\n - the snapshot is \"old\": it was created before this change\n - the driver doesn't support metadata (eg [Postgres][4])\n\nIn the case where metadata is unavailable, we fall back to the existing\nmethod, using `getCommittedOpVersion()`. However, if drivers support\nmetadata, this should happen sufficiently infrequently that consumers\ncould potentially remove the `src`/`seq`/`v` index with no noticeable\nperformance penalty.\n\n[1]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/submit-request.js#L112\n[2]: https://github.com/share/sharedb-mongo/issues/94\n[3]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/db/index.js#L69\n[4]: https://github.com/share/sharedb-postgres/blob/499702acd478645bcc249fa50ba6fc066d257d04/index.js#L140","shortMessageHtmlLink":"๐Ÿ—ƒ Add _create metadata to snapshots to avoid getCommittedOpVersion()"}},{"before":"9f089775ff172dd2898fe42d10254ddaa21737ed","after":"7ba7f0be75862a48234cdbb6d183ae20aec8312d","ref":"refs/heads/src-seq-create-meta","pushedAt":"2024-05-23T07:15:18.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"๐Ÿ—ƒ Add `_create` metadata to snapshots to avoid `getCommittedOpVersion()`\n\nSupersedes https://github.com/share/sharedb/pull/657\n\nThe `DB.getCommitedOpVersion()` function is only used [in one place][1]:\nin a corner case that differentiates between two \"blind\", versionless\n(created without first fetching) create op conflict cases:\n\n - a versionless create op that conflicts with another create op\n - a versionless create op that has been re-submitted because the\n connection was closed before the ack was received\n\nThe first of these cases should result in an error, and the second is\nnon-fatal and the error can be swallowed.\n\nAt the moment, this differentiation is made using the special\n`DB.getCommittedOpVersion()` function, which - given an op with a\n`src` and `seq` combination - will return `null` if the op hasn't been\ncommitted, or its version number if it has.\n\nIf the op has a committed version number, we know that the submit is a\nduplicate, and we can safely ignore it.\n\nThis approach is problematic, because:\n\n - it [needs a whole op index][2] just to handle this niche corner case\n - the default behaviour [fetches **all** ops][3] unless the driver\n overrides this behaviour\n\nThis change proposes that we actually don't need this function in most\ncases, and implements an alternative approach to differentiate between\nthe above cases.\n\nWhen creating an snapshot, we store the `src`, `seq` and `v` of the op\nthat was used to create it.\n\nIf a conflicting `create` is received, we can then compare directly with\nthis metadata, without needing to fetch anything extra from the\ndatabase.\n\nThis should work in the majority of cases, but won't work if the\nmetadata is missing, which could happen if:\n\n - the snapshot is \"old\": it was created before this change\n - the driver doesn't support metadata (eg [Postgres][4])\n\nIn the case where metadata is unavailable, we fall back to the existing\nmethod, using `getCommittedOpVersion()`. However, if drivers support\nmetadata, this should happen sufficiently infrequently that consumers\ncould potentially remove the `src`/`seq`/`v` index with no noticeable\nperformance penalty.\n\n[1]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/submit-request.js#L112\n[2]: https://github.com/share/sharedb-mongo/issues/94\n[3]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/db/index.js#L69\n[4]: https://github.com/share/sharedb-postgres/blob/499702acd478645bcc249fa50ba6fc066d257d04/index.js#L140","shortMessageHtmlLink":"๐Ÿ—ƒ Add _create metadata to snapshots to avoid getCommittedOpVersion()"}},{"before":"22e554d6eff3c46787d6ceac3b54e091774a8498","after":null,"ref":"refs/heads/create-collide-tests","pushedAt":"2024-05-23T07:14:28.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"}},{"before":"7b20313ded4c302b9416cc6c7821694a7fa491b8","after":"f4effa3a73c840cfeff8ed59371fda16516d7ad9","ref":"refs/heads/master","pushedAt":"2024-05-23T07:14:27.000Z","pushType":"pr_merge","commitsCount":2,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"Merge pull request #658 from share/create-collide-tests\n\nโœ… Add `OP_ALREADY_SUBMITTED` test for create ops","shortMessageHtmlLink":"Merge pull request #658 from share/create-collide-tests"}},{"before":null,"after":"9f089775ff172dd2898fe42d10254ddaa21737ed","ref":"refs/heads/src-seq-create-meta","pushedAt":"2024-05-22T14:01:16.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"๐Ÿ—ƒ Add `_create` metadata to snapshots to avoid `getCommittedOpVersion()`\n\nSupersedes https://github.com/share/sharedb/pull/657\n\nThe `DB.getCommitedOpVersion()` function is only used [in one place][1]:\nin a corner case that differentiates between two \"blind\", versionless\n(created without first fetching) create op conflict cases:\n\n - a versionless create op that conflicts with another create op\n - a versionless create op that has been re-submitted because the\n connection was closed before the ack was received\n\nThe first of these cases should result in an error, and the second is\nnon-fatal and the error can be swallowed.\n\nAt the moment, this differentiation is made using the special\n`DB.getCommittedOpVersion()` function, which - given an op with a\n`src` and `seq` combination - will return `null` if the op hasn't been\ncommitted, or its version number if it has.\n\nIf the op has a committed version number, we know that the submit is a\nduplicate, and we can safely ignore it.\n\nThis approach is problematic, because:\n\n - it [needs a whole op index][2] just to handle this niche corner case\n - the default behaviour [fetches **all** ops][3] unless the driver\n overrides this behaviour\n\nThis change proposes that we actually don't need this function in most\ncases, and implements an alternative approach to differentiate between\nthe above cases.\n\nWhen creating an snapshot, we store the `src`, `seq` and `v` of the op\nthat was used to create it.\n\nIf a conflicting `create` is received, we can then compare directly with\nthis metadata, without needing to fetch anything extra from the\ndatabase.\n\nThis should work in the majority of cases, but won't work if the\nmetadata is missing, which could happen if:\n\n - the snapshot is \"old\": it was created before this change\n - the driver doesn't support metadata (eg [Postgres][4])\n\nIn the case where metadata is unavailable, we fall back to the existing\nmethod, using `getCommittedOpVersion()`. However, if drivers support\nmetadata, this should happen sufficiently infrequently that consumers\ncould potentially remove the `src`/`seq`/`v` index with no noticeable\nperformance penalty.\n\n[1]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/submit-request.js#L112\n[2]: https://github.com/share/sharedb-mongo/issues/94\n[3]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/db/index.js#L69\n[4]: https://github.com/share/sharedb-postgres/blob/499702acd478645bcc249fa50ba6fc066d257d04/index.js#L140","shortMessageHtmlLink":"๐Ÿ—ƒ Add _create metadata to snapshots to avoid getCommittedOpVersion()"}},{"before":null,"after":"22e554d6eff3c46787d6ceac3b54e091774a8498","ref":"refs/heads/create-collide-tests","pushedAt":"2024-05-22T12:55:19.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"alecgibson","name":"Alec Gibson","path":"/alecgibson","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/12036746?s=80&v=4"},"commit":{"message":"โœ… Add `OP_ALREADY_SUBMITTED` test for create ops\n\nWe have [logic][1] that tries to differentiate between:\n\n - a create op that is incorrectly trying to create a `Doc` that already\n exists\n - a create op that has already been committed, and has been resubmitted\n (possibly because the connection closed before the ack was received)\n\nThe latter case is [not currently covered by tests][2].\n\nThis change adds a test to cover this branch, and a second similar test\nwhich explains why https://github.com/share/sharedb/pull/657 was not a\nviable change (and correctly fails for that case).\n\n[1]: https://github.com/share/sharedb/blob/7b20313ded4c302b9416cc6c7821694a7fa491b8/lib/submit-request.js#L105-L121\n[2]: https://coveralls.io/builds/67552613/source?filename=lib%2Fsubmit-request.js#L117","shortMessageHtmlLink":"โœ… Add OP_ALREADY_SUBMITTED test for create ops"}}],"hasNextPage":true,"hasPreviousPage":false,"activityType":"all","actor":null,"timePeriod":"all","sort":"DESC","perPage":30,"cursor":"djE6ks8AAAAEVtQysgA","startCursor":null,"endCursor":null}},"title":"Activity ยท share/sharedb"}