biome format --write

This commit is contained in:
Henry Jameson 2026-01-06 16:22:52 +02:00
commit 9262e803ec
415 changed files with 54076 additions and 17419 deletions

View file

@ -12,7 +12,7 @@ import {
findLastIndex,
takeRight,
uniqWith,
merge as _merge
merge as _merge,
} from 'lodash'
import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js'
@ -29,7 +29,7 @@ export const defaultState = {
flagStorage: {
updateCounter: 0, // Counter for most recent update notification seen
configMigration: 0, // Counter for config -> server-side migrations
reset: 0 // special flag that can be used to force-reset all flags, debug purposes only
reset: 0, // special flag that can be used to force-reset all flags, debug purposes only
// special reset codes:
// 1000: trim keys to those known by currently running FE
// 1001: same as above + reset everything to 0
@ -39,22 +39,22 @@ export const defaultState = {
simple: {
dontShowUpdateNotifs: false,
collapseNav: false,
muteFilters: {}
muteFilters: {},
},
collections: {
pinnedStatusActions: ['reply', 'retweet', 'favorite', 'emoji'],
pinnedNavItems: ['home', 'dms', 'chats']
}
pinnedNavItems: ['home', 'dms', 'chats'],
},
},
// raw data
raw: null,
// local cache
cache: null
cache: null,
}
export const newUserFlags = {
...defaultState.flagStorage,
updateCounter: CURRENT_UPDATE_COUNTER // new users don't need to see update notification
updateCounter: CURRENT_UPDATE_COUNTER, // new users don't need to see update notification
}
export const _moveItemInArray = (array, value, movement) => {
@ -72,7 +72,7 @@ const _wrapData = (data, userName) => ({
...data,
_user: userName,
_timestamp: Date.now(),
_version: VERSION
_version: VERSION,
})
const _checkValidity = (data) => data._timestamp > 0 && data._version > 0
@ -80,7 +80,7 @@ const _checkValidity = (data) => data._timestamp > 0 && data._version > 0
const _verifyPrefs = (state) => {
state.prefsStorage = state.prefsStorage || {
simple: {},
collections: {}
collections: {},
}
// Simple
@ -95,7 +95,11 @@ const _verifyPrefs = (state) => {
Object.entries(defaultState.prefsStorage.collections).forEach(([k, v]) => {
if (Array.isArray(v)) return
console.warn(`Preference collections.${k} as invalid type, reinitializing`)
set(state.prefsStorage.collections, k, defaultState.prefsStorage.collections[k])
set(
state.prefsStorage.collections,
k,
defaultState.prefsStorage.collections[k],
)
})
}
@ -105,21 +109,32 @@ export const _getRecentData = (cache, live, isTest) => {
const liveValid = _checkValidity(live || {})
if (!liveValid && cacheValid) {
result.needUpload = true
console.debug('Nothing valid stored on server, assuming cache to be source of truth')
console.debug(
'Nothing valid stored on server, assuming cache to be source of truth',
)
result.recent = cache
result.stale = live
} else if (!cacheValid && liveValid) {
console.debug('Valid storage on server found, no local cache found, using live as source of truth')
console.debug(
'Valid storage on server found, no local cache found, using live as source of truth',
)
result.recent = live
result.stale = cache
} else if (cacheValid && liveValid) {
console.debug('Both sources have valid data, figuring things out...')
if (live._timestamp === cache._timestamp && live._version === cache._version) {
console.debug('Same version/timestamp on both source, source of truth irrelevant')
if (
live._timestamp === cache._timestamp &&
live._version === cache._version
) {
console.debug(
'Same version/timestamp on both source, source of truth irrelevant',
)
result.recent = cache
result.stale = live
} else {
console.debug('Different timestamp, figuring out which one is more recent')
console.debug(
'Different timestamp, figuring out which one is more recent',
)
if (live._timestamp < cache._timestamp) {
result.recent = cache
result.stale = live
@ -139,49 +154,64 @@ export const _getRecentData = (cache, live, isTest) => {
_timestamp: a._timestamp ?? b._timestamp,
needUpload: b.needUpload ?? a.needUpload,
prefsStorage: _merge(a.prefsStorage, b.prefsStorage),
flagStorage: _merge(a.flagStorage, b.flagStorage)
flagStorage: _merge(a.flagStorage, b.flagStorage),
})
result.recent = isTest ? result.recent : (result.recent && merge(defaultState, result.recent))
result.stale = isTest ? result.stale : (result.stale && merge(defaultState, result.stale))
result.recent = isTest
? result.recent
: result.recent && merge(defaultState, result.recent)
result.stale = isTest
? result.stale
: result.stale && merge(defaultState, result.stale)
return result
}
export const _getAllFlags = (recent, stale) => {
return Array.from(new Set([
...Object.keys(toRaw((recent || {}).flagStorage || {})),
...Object.keys(toRaw((stale || {}).flagStorage || {}))
]))
return Array.from(
new Set([
...Object.keys(toRaw((recent || {}).flagStorage || {})),
...Object.keys(toRaw((stale || {}).flagStorage || {})),
]),
)
}
export const _mergeFlags = (recent, stale, allFlagKeys) => {
if (!stale.flagStorage) return recent.flagStorage
if (!recent.flagStorage) return stale.flagStorage
return Object.fromEntries(allFlagKeys.map(flag => {
const recentFlag = recent.flagStorage[flag]
const staleFlag = stale.flagStorage[flag]
// use flag that is of higher value
return [flag, Number((recentFlag > staleFlag ? recentFlag : staleFlag) || 0)]
}))
return Object.fromEntries(
allFlagKeys.map((flag) => {
const recentFlag = recent.flagStorage[flag]
const staleFlag = stale.flagStorage[flag]
// use flag that is of higher value
return [
flag,
Number((recentFlag > staleFlag ? recentFlag : staleFlag) || 0),
]
}),
)
}
const _mergeJournal = (...journals) => {
// Ignore invalid journal entries
const allJournals = flatten(
journals.map(j => Array.isArray(j) ? j : [])
).filter(entry =>
Object.hasOwn(entry, 'path') &&
Object.hasOwn(entry, 'operation') &&
Object.hasOwn(entry, 'args') &&
Object.hasOwn(entry, 'timestamp')
journals.map((j) => (Array.isArray(j) ? j : [])),
).filter(
(entry) =>
Object.hasOwn(entry, 'path') &&
Object.hasOwn(entry, 'operation') &&
Object.hasOwn(entry, 'args') &&
Object.hasOwn(entry, 'timestamp'),
)
const grouped = groupBy(allJournals, 'path')
const trimmedGrouped = Object.entries(grouped).map(([path, journal]) => {
// side effect
journal.sort((a, b) => a.timestamp > b.timestamp ? 1 : -1)
journal.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1))
if (path.startsWith('collections')) {
const lastRemoveIndex = findLastIndex(journal, ({ operation }) => operation === 'removeFromCollection')
const lastRemoveIndex = findLastIndex(
journal,
({ operation }) => operation === 'removeFromCollection',
)
// everything before last remove is unimportant
let remainder
if (lastRemoveIndex > 0) {
@ -191,8 +221,12 @@ const _mergeJournal = (...journals) => {
remainder = journal
}
return uniqWith(remainder, (a, b) => {
if (a.path !== b.path) { return false }
if (a.operation !== b.operation) { return false }
if (a.path !== b.path) {
return false
}
if (a.operation !== b.operation) {
return false
}
if (a.operation === 'addToCollection') {
return a.args[0] === b.args[0]
}
@ -205,8 +239,9 @@ const _mergeJournal = (...journals) => {
return journal
}
})
return flatten(trimmedGrouped)
.sort((a, b) => a.timestamp > b.timestamp ? 1 : -1)
return flatten(trimmedGrouped).sort((a, b) =>
a.timestamp > b.timestamp ? 1 : -1,
)
}
export const _mergePrefs = (recent, stale) => {
@ -228,29 +263,45 @@ export const _mergePrefs = (recent, stale) => {
const totalJournal = _mergeJournal(staleJournal, recentJournal)
totalJournal.forEach(({ path, operation, args }) => {
if (path.startsWith('_')) {
throw new Error(`journal contains entry to edit internal (starts with _) field '${path}', something is incorrect here, ignoring.`)
throw new Error(
`journal contains entry to edit internal (starts with _) field '${path}', something is incorrect here, ignoring.`,
)
}
switch (operation) {
case 'set':
if (path.startsWith('collections') || path.startsWith('objectCollections')) {
if (
path.startsWith('collections') ||
path.startsWith('objectCollections')
) {
throw new Error('Illegal operation "set" on a collection')
}
if (path.split(/\./g).length <= 1) {
throw new Error(`Calling set on depth <= 1 (path: ${path}) is not allowed`)
throw new Error(
`Calling set on depth <= 1 (path: ${path}) is not allowed`,
)
}
set(resultOutput, path, args[0])
break
case 'unset':
if (path.startsWith('collections') || path.startsWith('objectCollections')) {
if (
path.startsWith('collections') ||
path.startsWith('objectCollections')
) {
throw new Error('Illegal operation "unset" on a collection')
}
if (path.split(/\./g).length <= 2) {
throw new Error(`Calling unset on depth <= 2 (path: ${path}) is not allowed`)
throw new Error(
`Calling unset on depth <= 2 (path: ${path}) is not allowed`,
)
}
unset(resultOutput, path)
break
case 'addToCollection':
set(resultOutput, path, Array.from(new Set(get(resultOutput, path)).add(args[0])))
set(
resultOutput,
path,
Array.from(new Set(get(resultOutput, path)).add(args[0])),
)
break
case 'removeFromCollection': {
const newSet = new Set(get(resultOutput, path))
@ -260,27 +311,39 @@ export const _mergePrefs = (recent, stale) => {
}
case 'reorderCollection': {
const [value, movement] = args
set(resultOutput, path, _moveItemInArray(get(resultOutput, path), value, movement))
set(
resultOutput,
path,
_moveItemInArray(get(resultOutput, path), value, movement),
)
break
}
default:
throw new Error(`Unknown journal operation: '${operation}', did we forget to run reverse migrations beforehand?`)
throw new Error(
`Unknown journal operation: '${operation}', did we forget to run reverse migrations beforehand?`,
)
}
})
return { ...resultOutput, _journal: totalJournal }
}
export const _resetFlags = (totalFlags, knownKeys = defaultState.flagStorage) => {
export const _resetFlags = (
totalFlags,
knownKeys = defaultState.flagStorage,
) => {
let result = { ...totalFlags }
const allFlagKeys = Object.keys(totalFlags)
// flag reset functionality
if (totalFlags.reset >= COMMAND_TRIM_FLAGS && totalFlags.reset <= COMMAND_TRIM_FLAGS_AND_RESET) {
if (
totalFlags.reset >= COMMAND_TRIM_FLAGS &&
totalFlags.reset <= COMMAND_TRIM_FLAGS_AND_RESET
) {
console.debug('Received command to trim the flags')
const knownKeysSet = new Set(Object.keys(knownKeys))
// Trim
result = {}
allFlagKeys.forEach(flag => {
allFlagKeys.forEach((flag) => {
if (knownKeysSet.has(flag)) {
result[flag] = totalFlags[flag]
}
@ -290,11 +353,15 @@ export const _resetFlags = (totalFlags, knownKeys = defaultState.flagStorage) =>
if (totalFlags.reset === COMMAND_TRIM_FLAGS_AND_RESET) {
// 1001 - and reset everything to 0
console.debug('Received command to reset the flags')
Object.keys(knownKeys).forEach(flag => { result[flag] = 0 })
Object.keys(knownKeys).forEach((flag) => {
result[flag] = 0
})
}
} else if (totalFlags.reset > 0 && totalFlags.reset < 9000) {
console.debug('Received command to reset the flags')
allFlagKeys.forEach(flag => { result[flag] = 0 })
allFlagKeys.forEach((flag) => {
result[flag] = 0
})
}
result.reset = 0
return result
@ -304,20 +371,29 @@ export const _doMigrations = (cache) => {
if (!cache) return cache
if (cache._version < VERSION) {
console.debug('Local cached data has older version, seeing if there any migrations that can be applied')
console.debug(
'Local cached data has older version, seeing if there any migrations that can be applied',
)
// no migrations right now since we only have one version
console.debug('No migrations found')
}
if (cache._version > VERSION) {
console.debug('Local cached data has newer version, seeing if there any reverse migrations that can be applied')
console.debug(
'Local cached data has newer version, seeing if there any reverse migrations that can be applied',
)
// no reverse migrations right now but we leave a possibility of loading a hotpatch if need be
if (window._PLEROMA_HOTPATCH) {
if (window._PLEROMA_HOTPATCH.reverseMigrations) {
console.debug('Found hotpatch migration, applying')
return window._PLEROMA_HOTPATCH.reverseMigrations.call({}, 'serverSideStorage', { from: cache._version, to: VERSION }, cache)
return window._PLEROMA_HOTPATCH.reverseMigrations.call(
{},
'serverSideStorage',
{ from: cache._version, to: VERSION },
cache,
)
}
}
}
@ -330,53 +406,77 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
return cloneDeep(defaultState)
},
actions: {
setFlag ({ flag, value }) {
setFlag({ flag, value }) {
this.flagStorage[flag] = value
this.dirty = true
},
setPreference ({ path, value }) {
setPreference({ path, value }) {
if (path.startsWith('_')) {
throw new Error(`Tried to edit internal (starts with _) field '${path}', ignoring.`)
throw new Error(
`Tried to edit internal (starts with _) field '${path}', ignoring.`,
)
}
if (path.startsWith('collections') || path.startsWith('objectCollections')) {
throw new Error(`Invalid operation 'set' for collection field '${path}', ignoring.`)
if (
path.startsWith('collections') ||
path.startsWith('objectCollections')
) {
throw new Error(
`Invalid operation 'set' for collection field '${path}', ignoring.`,
)
}
if (path.split(/\./g).length <= 1) {
throw new Error(`Calling set on depth <= 1 (path: ${path}) is not allowed`)
throw new Error(
`Calling set on depth <= 1 (path: ${path}) is not allowed`,
)
}
if (path.split(/\./g).length > 3) {
throw new Error(`Calling set on depth > 3 (path: ${path}) is not allowed`)
throw new Error(
`Calling set on depth > 3 (path: ${path}) is not allowed`,
)
}
set(this.prefsStorage, path, value)
this.prefsStorage._journal = [
...this.prefsStorage._journal,
{ operation: 'set', path, args: [value], timestamp: Date.now() }
{ operation: 'set', path, args: [value], timestamp: Date.now() },
]
this.dirty = true
},
unsetPreference ({ path, value }) {
unsetPreference({ path, value }) {
if (path.startsWith('_')) {
throw new Error(`Tried to edit internal (starts with _) field '${path}', ignoring.`)
throw new Error(
`Tried to edit internal (starts with _) field '${path}', ignoring.`,
)
}
if (path.startsWith('collections') || path.startsWith('objectCollections')) {
throw new Error(`Invalid operation 'unset' for collection field '${path}', ignoring.`)
if (
path.startsWith('collections') ||
path.startsWith('objectCollections')
) {
throw new Error(
`Invalid operation 'unset' for collection field '${path}', ignoring.`,
)
}
if (path.split(/\./g).length <= 2) {
throw new Error(`Calling unset on depth <= 2 (path: ${path}) is not allowed`)
throw new Error(
`Calling unset on depth <= 2 (path: ${path}) is not allowed`,
)
}
if (path.split(/\./g).length > 3) {
throw new Error(`Calling unset on depth > 3 (path: ${path}) is not allowed`)
throw new Error(
`Calling unset on depth > 3 (path: ${path}) is not allowed`,
)
}
unset(this.prefsStorage, path, value)
this.prefsStorage._journal = [
...this.prefsStorage._journal,
{ operation: 'unset', path, args: [], timestamp: Date.now() }
{ operation: 'unset', path, args: [], timestamp: Date.now() },
]
this.dirty = true
},
addCollectionPreference ({ path, value }) {
addCollectionPreference({ path, value }) {
if (path.startsWith('_')) {
throw new Error(`tried to edit internal (starts with _) field '${path}'`)
throw new Error(
`tried to edit internal (starts with _) field '${path}'`,
)
}
if (path.startsWith('collections')) {
const collection = new Set(get(this.prefsStorage, path))
@ -394,55 +494,79 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
}
this.prefsStorage._journal = [
...this.prefsStorage._journal,
{ operation: 'addToCollection', path, args: [value], timestamp: Date.now() }
{
operation: 'addToCollection',
path,
args: [value],
timestamp: Date.now(),
},
]
this.dirty = true
},
removeCollectionPreference ({ path, value }) {
removeCollectionPreference({ path, value }) {
if (path.startsWith('_')) {
throw new Error(`tried to edit internal (starts with _) field '${path}', ignoring.`)
throw new Error(
`tried to edit internal (starts with _) field '${path}', ignoring.`,
)
}
const collection = new Set(get(this.prefsStorage, path))
collection.delete(value)
set(this.prefsStorage, path, [...collection])
this.prefsStorage._journal = [
...this.prefsStorage._journal,
{ operation: 'removeFromCollection', path, args: [value], timestamp: Date.now() }
{
operation: 'removeFromCollection',
path,
args: [value],
timestamp: Date.now(),
},
]
this.dirty = true
},
reorderCollectionPreference ({ path, value, movement }) {
reorderCollectionPreference({ path, value, movement }) {
if (path.startsWith('_')) {
throw new Error(`tried to edit internal (starts with _) field '${path}', ignoring.`)
throw new Error(
`tried to edit internal (starts with _) field '${path}', ignoring.`,
)
}
const collection = get(this.prefsStorage, path)
const newCollection = _moveItemInArray(collection, value, movement)
set(this.prefsStorage, path, newCollection)
this.prefsStorage._journal = [
...this.prefsStorage._journal,
{ operation: 'arrangeCollection', path, args: [value], timestamp: Date.now() }
{
operation: 'arrangeCollection',
path,
args: [value],
timestamp: Date.now(),
},
]
this.dirty = true
},
updateCache ({ username }) {
updateCache({ username }) {
this.prefsStorage._journal = _mergeJournal(this.prefsStorage._journal)
this.cache = _wrapData({
flagStorage: toRaw(this.flagStorage),
prefsStorage: toRaw(this.prefsStorage)
}, username)
this.cache = _wrapData(
{
flagStorage: toRaw(this.flagStorage),
prefsStorage: toRaw(this.prefsStorage),
},
username,
)
},
clearServerSideStorage () {
clearServerSideStorage() {
const blankState = { ...cloneDeep(defaultState) }
Object.keys(this).forEach(k => {
Object.keys(this).forEach((k) => {
this[k] = blankState[k]
})
},
setServerSideStorage (userData) {
setServerSideStorage(userData) {
const live = userData.storage
this.raw = live
let cache = this.cache
if (cache && cache._user !== userData.fqn) {
console.warn('Cache belongs to another user! reinitializing local cache!')
console.warn(
'Cache belongs to another user! reinitializing local cache!',
)
cache = null
}
@ -455,10 +579,12 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
let dirty = false
if (recent === null) {
console.debug(`Data is empty, initializing for ${userNew ? 'new' : 'existing'} user`)
console.debug(
`Data is empty, initializing for ${userNew ? 'new' : 'existing'} user`,
)
recent = _wrapData({
flagStorage: { ...flagsTemplate },
prefsStorage: { ...defaultState.prefsStorage }
prefsStorage: { ...defaultState.prefsStorage },
})
}
@ -470,7 +596,7 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
const { _timestamp: _2, _version: _3, ...staleData } = stale
/* eslint-enable no-unused-vars */
dirty = !isEqual(recentData, staleData)
console.debug(`Data ${dirty ? 'needs' : 'doesn\'t need'} merging`)
console.debug(`Data ${dirty ? 'needs' : "doesn't need"} merging`)
}
const allFlagKeys = _getAllFlags(recent, stale)
@ -502,7 +628,7 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
this.flagStorage = this.cache.flagStorage
this.prefsStorage = this.cache.prefsStorage
},
pushServerSideStorage ({ force = false } = {}) {
pushServerSideStorage({ force = false } = {}) {
const needPush = this.dirty || force
if (!needPush) return
this.updateCache({ username: window.vuex.state.users.currentUser.fqn })
@ -513,6 +639,6 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
this.setServerSideStorage(user)
this.dirty = false
})
}
}
},
},
})