in src/global_append_only_array.js [15:90]
export async function AppendOnlyArray(startValue, arrayName) {
let arrayWrapper = {}
let localArray = startValue
let localChangesQueue = []
let receivedAllValues = Reactive.boolSignalSource(`${arrayName}_receivedAllValues`)
receivedAllValues.set(false)
receivedAllValues.signal.onOn().subscribe(
event => {
if (event.newValue) {
if (localChangesQueue.length > 0) {
receivedAllValues.set(false)
arrayWrapper.updateState({
newValues: localChangesQueue.slice()
})
localArray.push(...localChangesQueue)
localChangesQueue = []
Time.setTimeout(() => {
receivedAllValues.set(true)
}, 50)
}
}
})
arrayWrapper.setReceivedAllValues = function (newValue) {
receivedAllValues.set(newValue)
}
arrayWrapper.receivedAllValuesSignal = receivedAllValues.signal
arrayWrapper.compareAndUpdateLocal = function (newArray) {
const currentLength = localArray.length
const newLength = newArray.length
let i
for (i = 0; i < currentLength && i < newLength; i++) {
localArray[i] = newArray[i]
}
if (newLength > currentLength) {
for (let j = i; j < newArray.length; j++) {
localArray.push(newArray[j])
}
} else if (newLength < currentLength && newLength != 0) {
localArray.splice(i, currentLength - newLength)
}
}
// Pushes the new value when the global array is synchronised with at least one peer
arrayWrapper.push = function (newValue) {
if (receivedAllValues.signal.pinLastValue()) {
receivedAllValues.set(false)
localArray.push(newValue)
arrayWrapper.updateState({newValues: [newValue]})
Time.setTimeout(() => {
receivedAllValues.set(true)
}, 50)
} else {
localChangesQueue.push(newValue)
}
}
// Returns a copy with the current elements of the array
arrayWrapper.getSnapshot = function (index) {
return localArray.slice()
}
arrayWrapper.length = function () {
return localArray.length
}
arrayWrapper.get = function (index) {
return localArray[index]
}
return arrayWrapper
}