Skip to content

Commit

Permalink
feat: starter useRefHistory
Browse files Browse the repository at this point in the history
  • Loading branch information
pei-pay committed May 18, 2024
1 parent d6b9862 commit e782340
Showing 1 changed file with 49 additions and 7 deletions.
56 changes: 49 additions & 7 deletions starter/useRefHistory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Ref, ref, watch } from 'vue'
import { type Ref, ref, watch, markRaw, computed } from 'vue'

interface UseRefHistoryRecord<T> {
snapshot: T
Expand All @@ -12,16 +12,58 @@ interface UseRefHistoryReturn<Raw> {
redo: () => void
}

export const timestamp = () => +Date.now()

export function useRefHistory<Raw>(source: Ref<Raw>): UseRefHistoryReturn<Raw> {
const history: Ref<UseRefHistoryRecord<Raw>[]> = ref([])
const canUndo = ref(false)
const canRedo = ref(false)
const undo = () => {}
const redo = () => {}

function _createHistoryRecord(): UseRefHistoryRecord<Raw> {
return markRaw({
snapshot: source.value,
timestamp: timestamp()
})
}

const _setSource = (record: UseRefHistoryRecord<Raw>) => {
ignore.value = true
source.value = record.snapshot
last.value = record
ignore.value = false
}

const ignore = ref(false)

const last: Ref<UseRefHistoryRecord<Raw>> = ref(_createHistoryRecord()) as Ref<UseRefHistoryRecord<Raw>>

const undoStack: Ref<UseRefHistoryRecord<Raw>[]> = ref([]);
const redoStack: Ref<UseRefHistoryRecord<Raw>[]> = ref([])

const undo = () => {
const state = undoStack.value.shift()
if(state) {
redoStack.value.unshift(last.value)
_setSource(state)
}
}
const redo = () => {
const state = redoStack.value.shift();

if (state) {
undoStack.value.unshift(last.value);
_setSource(state);
}
}

watch(source, () => {
if(ignore.value) return
undoStack.value.unshift(last.value)
last.value = _createHistoryRecord()
if(redoStack.value.length)
redoStack.value.splice(0, redoStack.value.length)
}, { flush: 'sync'} )

})
const history = computed(() => [last.value, ...undoStack.value])
const canUndo = computed(() => undoStack.value.length > 0)
const canRedo = computed(() => redoStack.value.length > 0)

return {
history,
Expand Down

0 comments on commit e782340

Please sign in to comment.