-
-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
297 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
--- | ||
"@evolu/common": minor | ||
--- | ||
|
||
Time Travel | ||
|
||
Evolu does not delete data; it only marks them as deleted. This is because local-first is a distributed system. There is no central authority (if there is, it's not local-first). Imagine you delete data on some disconnected device and update it on another. Should we throw away changes? Such a deletion would require additional logic to enforce data deletion on all devices forever, even in the future, when some outdated device syncs. It's possible (and planned for Evolu), but it's not trivial because every device has to track data to be rejected without knowing the data itself (for security reasons). | ||
|
||
Not deleting data allows Evolu to provide a time-traveling feature. All data, even "deleted" or overridden, are stored in the evolu_message table. Here is how we can read such data. | ||
|
||
```ts | ||
const todoTitleHistory = (id: TodoId) => | ||
evolu.createQuery((db) => | ||
db | ||
.selectFrom("evolu_message") | ||
.select("value") | ||
.where("table", "==", "todo") | ||
.where("row", "==", id) | ||
.where("column", "==", "title") | ||
.$narrowType<{ value: TodoTable["title"] }>() | ||
.orderBy("timestamp", "desc"), | ||
); | ||
``` | ||
|
||
Note that this API is not 100% typed, but it's not an issue because Evolu Schema shall be append-only. Once an app is released, we shall not change Schema names and types. We can only add new tables and columns because there is a chance current Schema is already used. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Time Travel | ||
|
||
Evolu does not delete data; it only marks them as deleted. This is because local-first is a distributed system. There is no central authority (if there is, it's not local-first). Imagine you delete data on some disconnected device and update it on another. Should we throw away changes? Such a deletion would require additional logic to enforce data deletion on all devices forever, even in the future, when some outdated device syncs. It's possible (and planned for Evolu), but it's not trivial because every device has to track data to be rejected without knowing the data itself (for security reasons). | ||
|
||
Not deleting data allows Evolu to provide a time-traveling feature. All data, even "deleted" or overridden, are stored in the evolu_message table. Here is how we can read such data. | ||
|
||
```ts | ||
const todoTitleHistory = (id: TodoId) => | ||
evolu.createQuery((db) => | ||
db | ||
.selectFrom("evolu_message") | ||
.select("value") | ||
.where("table", "==", "todo") | ||
.where("row", "==", id) | ||
.where("column", "==", "title") | ||
.$narrowType<{ value: TodoTable["title"] }>() | ||
.orderBy("timestamp", "desc"), | ||
); | ||
``` | ||
|
||
Note that this API is not 100% typed, but it's not an issue because Evolu Schema shall be append-only. Once an app is released, we shall not change Schema names and types. We can only add new tables and columns because there is a chance current Schema is already used. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,9 @@ | |
}, | ||
"packageManager": "[email protected]", | ||
"pnpm": { | ||
"patchedDependencies": { | ||
"@changesets/[email protected]": "patches/@[email protected]" | ||
}, | ||
"peerDependencyRules": { | ||
"ignoreMissing": [ | ||
"@babel/*", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
diff --git a/dist/changesets-assemble-release-plan.cjs.js b/dist/changesets-assemble-release-plan.cjs.js | ||
index ee5c0f67fabadeb112e9f238d8b144a4d125830f..42afcbce044a2949d6242af0a6c5abffcd2a51ad 100644 | ||
--- a/dist/changesets-assemble-release-plan.cjs.js | ||
+++ b/dist/changesets-assemble-release-plan.cjs.js | ||
@@ -90,16 +90,6 @@ function determineDependents({ | ||
} of dependencyVersionRanges) { | ||
if (nextRelease.type === "none") { | ||
continue; | ||
- } else if (shouldBumpMajor({ | ||
- dependent, | ||
- depType, | ||
- versionRange, | ||
- releases, | ||
- nextRelease, | ||
- preInfo, | ||
- onlyUpdatePeerDependentsWhenOutOfRange: config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH.onlyUpdatePeerDependentsWhenOutOfRange | ||
- })) { | ||
- type = "major"; | ||
} else if ((!releases.has(dependent) || releases.get(dependent).type === "none") && (config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH.updateInternalDependents === "always" || !semverSatisfies__default["default"](incrementVersion(nextRelease, preInfo), versionRange))) { | ||
switch (depType) { | ||
case "dependencies": | ||
diff --git a/dist/changesets-assemble-release-plan.esm.js b/dist/changesets-assemble-release-plan.esm.js | ||
index bf5202626a164a7780650d333983c3479b078689..27eea4d1d31c0e7ce8d56363c5a3437bbeb819a0 100644 | ||
--- a/dist/changesets-assemble-release-plan.esm.js | ||
+++ b/dist/changesets-assemble-release-plan.esm.js | ||
@@ -79,16 +79,6 @@ function determineDependents({ | ||
} of dependencyVersionRanges) { | ||
if (nextRelease.type === "none") { | ||
continue; | ||
- } else if (shouldBumpMajor({ | ||
- dependent, | ||
- depType, | ||
- versionRange, | ||
- releases, | ||
- nextRelease, | ||
- preInfo, | ||
- onlyUpdatePeerDependentsWhenOutOfRange: config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH.onlyUpdatePeerDependentsWhenOutOfRange | ||
- })) { | ||
- type = "major"; | ||
} else if ((!releases.has(dependent) || releases.get(dependent).type === "none") && (config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH.updateInternalDependents === "always" || !semverSatisfies(incrementVersion(nextRelease, preInfo), versionRange))) { | ||
switch (depType) { | ||
case "dependencies": |
Oops, something went wrong.