From 509828ab784f0e78b9a1a81f8ef033e6e46f2953 Mon Sep 17 00:00:00 2001 From: Laszlo Korte Date: Mon, 22 Jul 2024 21:02:52 +0200 Subject: [PATCH 1/3] add presentMut lens for always replacing the current history item instead of appending --- src/core.js | 24 ++++++++++++++++++++++++ src/partial.lenses.history.js | 1 + test/tests.js | 13 +++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/core.js b/src/core.js index 326ad68..550e1ff 100644 --- a/src/core.js +++ b/src/core.js @@ -33,6 +33,26 @@ function setPresentU(value, history) { ) } +function setPresentUMut(value, history) { + const v = history.v + const i = history.i + const c = history.c + if (c.e) { + if (I.acyclicEqualsU(S.nth(i, v), value)) { + return history + } + } + const t = history.t + const now = Date.now() + const j0 = Math.max(0, i - c.m) + return construct( + i - j0, + S.append(now, S.slice(j0, i, t)), + S.append(value, S.slice(j0, i, v)), + c + ) +} + const setIndexU = (index, history) => construct( Math.max(0, Math.min(index, indexMax(history))), @@ -69,6 +89,10 @@ export const present = L.lens(function present(history) { return S.nth(history.i, history.v) }, setPresentU) +export const presentMut = L.lens(function present(history) { + return S.nth(history.i, history.v) +}, setPresentUMut) + // Undo export {index as undoIndex} diff --git a/src/partial.lenses.history.js b/src/partial.lenses.history.js index 4c0ca79..72209da 100644 --- a/src/partial.lenses.history.js +++ b/src/partial.lenses.history.js @@ -45,6 +45,7 @@ export const init = C( // Present export const present = C(H.present, lens(history, V.any)) +export const presentMut = C(H.presentMut, lens(history, V.any)) // Undo diff --git a/test/tests.js b/test/tests.js index 2ca5d6f..8dc11a1 100644 --- a/test/tests.js +++ b/test/tests.js @@ -113,6 +113,19 @@ describe('History', () => { ) }) + testEq([1, 2, 5, 6], async () => { + let h = H.init({pushEquals: true}, 1) + h = L.set(H.present, 2, h) + h = L.set(H.present, 3, h) + h = L.set(H.presentMut, 4, h) + h = L.set(H.presentMut, 5, h) + h = L.set(H.present, 6, h) + return R.map( + i => L.get(H.present, L.set(H.index, i, h)), + R.range(0, H.count(h)) + ) + }) + testEq(16000, () => { let h = H.init({maxCount: 5000}, 1) for (let i = 2; i < 20000; ++i) h = L.set(H.present, i, h) From b882b9e5049642701e93b516c55c17729dc052aa Mon Sep 17 00:00:00 2001 From: Laszlo Korte Date: Tue, 23 Jul 2024 12:49:24 +0200 Subject: [PATCH 2/3] apply PR suggestions: rename presentMut to presentReplace, add README entry --- README.md | 20 ++++++++++++++++++++ package.json | 2 +- src/core.js | 6 +++--- src/partial.lenses.history.js | 2 +- test/tests.js | 4 ++-- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e4412c5..e8b20a3 100644 --- a/README.md +++ b/README.md @@ -285,6 +285,26 @@ thru( Note that modifications through `H.present` are not referentially transparent operations, because setting through `H.present` takes a timestamp underneath. +#### [≡](#contents) [▶](https://calmm-js.github.io/partial.lenses.history/index.html#H-presentReplace) [`H.presentReplace ~> valueLens`](#H-presentReplace) v1.3.0 + +`H.presentReplace` is a +[lens](https://github.com/calmm-js/partial.lenses/#partial-lenses) that focuses +on the present value of history. When read it behaves exactly as [`H.present`](#H-present). When written it does *not* create a new history entry but instead replaces the current one. This might be useful for applying multiple changes in squence without polluting the history. + +For example: + +```js +thru( + H.init({}, 42), + L.modify(H.presentReplace, x => -x), + L.get(H.undoIndex) +) +// 0 +``` + +Note that modifications through `H.present` are not referentially transparent +operations, because setting through `H.present` takes a timestamp underneath. + ### [≡](#contents) [▶](https://calmm-js.github.io/partial.lenses.history/index.html#undo) [Undo](#undo) #### [≡](#contents) [▶](https://calmm-js.github.io/partial.lenses.history/index.html#H-undoForget) [`H.undoForget(history) ~> history`](#H-undoForget) v0.1.0 diff --git a/package.json b/package.json index 14b234a..6b5e8f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "partial.lenses.history", - "version": "1.2.0", + "version": "1.3.0", "description": "Partial Lenses History is a JavaScript library for Undo-Redo", "module": "dist/partial.lenses.history.es.js", "main": "dist/partial.lenses.history.cjs.js", diff --git a/src/core.js b/src/core.js index 550e1ff..dc5638d 100644 --- a/src/core.js +++ b/src/core.js @@ -33,7 +33,7 @@ function setPresentU(value, history) { ) } -function setPresentUMut(value, history) { +function setPresentReplaceU(value, history) { const v = history.v const i = history.i const c = history.c @@ -89,9 +89,9 @@ export const present = L.lens(function present(history) { return S.nth(history.i, history.v) }, setPresentU) -export const presentMut = L.lens(function present(history) { +export const presentReplace = L.lens(function presentReplace(history) { return S.nth(history.i, history.v) -}, setPresentUMut) +}, setPresentReplaceU) // Undo diff --git a/src/partial.lenses.history.js b/src/partial.lenses.history.js index 72209da..d1ad9b7 100644 --- a/src/partial.lenses.history.js +++ b/src/partial.lenses.history.js @@ -45,7 +45,7 @@ export const init = C( // Present export const present = C(H.present, lens(history, V.any)) -export const presentMut = C(H.presentMut, lens(history, V.any)) +export const presentReplace = C(H.presentReplace, lens(history, V.any)) // Undo diff --git a/test/tests.js b/test/tests.js index 8dc11a1..23997fa 100644 --- a/test/tests.js +++ b/test/tests.js @@ -117,8 +117,8 @@ describe('History', () => { let h = H.init({pushEquals: true}, 1) h = L.set(H.present, 2, h) h = L.set(H.present, 3, h) - h = L.set(H.presentMut, 4, h) - h = L.set(H.presentMut, 5, h) + h = L.set(H.presentReplace, 4, h) + h = L.set(H.presentReplace, 5, h) h = L.set(H.present, 6, h) return R.map( i => L.get(H.present, L.set(H.index, i, h)), From 4fd6e909fbd09afbb8bee379b9c3e7613870a36a Mon Sep 17 00:00:00 2001 From: Laszlo Korte Date: Tue, 23 Jul 2024 12:51:10 +0200 Subject: [PATCH 3/3] update readme TOC --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8b20a3..3a61d0f 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ Undo-Redo history. Basic features: * [`H.init({[maxCount, pushEquals, replacePeriod]}, value) ~> history`](#H-init) v0.1.0 * [Present](#present) * [`H.present ~> valueLens`](#H-present) v0.2.0 + * [`H.presentReplace ~> valueLens`](#H-presentReplace) v1.3.0 * [Undo](#undo) * [`H.undoForget(history) ~> history`](#H-undoForget) v0.1.0 * [`H.undoIndex ~> numberLens`](#H-undoIndex) v0.2.0 @@ -302,8 +303,8 @@ thru( // 0 ``` -Note that modifications through `H.present` are not referentially transparent -operations, because setting through `H.present` takes a timestamp underneath. +Note that modifications through `H.presentReplace` are not referentially transparent +operations, because setting through `H.presentReplace` takes a timestamp underneath. ### [≡](#contents) [▶](https://calmm-js.github.io/partial.lenses.history/index.html#undo) [Undo](#undo)