Merge branch 'setttingssync' into shigusegubu-themes3
This commit is contained in:
commit
8bffe9f0aa
7 changed files with 198 additions and 68 deletions
|
|
@ -42,6 +42,7 @@ import VBodyScrollLock from 'src/directives/body_scroll_lock'
|
||||||
import {
|
import {
|
||||||
INSTANCE_DEFAULT_CONFIG_DEFINITIONS,
|
INSTANCE_DEFAULT_CONFIG_DEFINITIONS,
|
||||||
INSTANCE_IDENTITY_DEFAULT_DEFINITIONS,
|
INSTANCE_IDENTITY_DEFAULT_DEFINITIONS,
|
||||||
|
INSTANCE_IDENTIY_EXTERNAL,
|
||||||
} from 'src/modules/default_config_state.js'
|
} from 'src/modules/default_config_state.js'
|
||||||
|
|
||||||
let staticInitialResults = null
|
let staticInitialResults = null
|
||||||
|
|
@ -170,12 +171,14 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
|
||||||
config = Object.assign({}, staticConfig, apiConfig)
|
config = Object.assign({}, staticConfig, apiConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(INSTANCE_IDENTITY_DEFAULT_DEFINITIONS).forEach((source) =>
|
Object.keys(INSTANCE_IDENTITY_DEFAULT_DEFINITIONS).forEach((source) => {
|
||||||
|
if (source === 'name') return
|
||||||
|
if (INSTANCE_IDENTIY_EXTERNAL.has(source)) return
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
value: config[source],
|
value: config[source],
|
||||||
path: `instanceIdentity.${source}`,
|
path: `instanceIdentity.${source}`,
|
||||||
}),
|
})
|
||||||
)
|
})
|
||||||
|
|
||||||
Object.keys(INSTANCE_DEFAULT_CONFIG_DEFINITIONS).forEach((source) =>
|
Object.keys(INSTANCE_DEFAULT_CONFIG_DEFINITIONS).forEach((source) =>
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
|
|
@ -277,7 +280,7 @@ const getNodeInfo = async ({ store }) => {
|
||||||
const metadata = data.metadata
|
const metadata = data.metadata
|
||||||
const features = metadata.features
|
const features = metadata.features
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'name',
|
path: 'instanceIdentity.name',
|
||||||
value: metadata.nodeName,
|
value: metadata.nodeName,
|
||||||
})
|
})
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
|
|
@ -527,6 +530,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
||||||
|
|
||||||
useInterfaceStore().setLayoutWidth(windowWidth())
|
useInterfaceStore().setLayoutWidth(windowWidth())
|
||||||
useInterfaceStore().setLayoutHeight(windowHeight())
|
useInterfaceStore().setLayoutHeight(windowHeight())
|
||||||
|
|
||||||
window.syncConfig = useSyncConfigStore()
|
window.syncConfig = useSyncConfigStore()
|
||||||
window.mergedConfig = useMergedConfigStore()
|
window.mergedConfig = useMergedConfigStore()
|
||||||
window.localConfig = useLocalConfigStore()
|
window.localConfig = useLocalConfigStore()
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,12 @@ import { useLocalConfigStore } from 'src/stores/local_config.js'
|
||||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
||||||
|
|
||||||
import { LOCAL_ONLY_KEYS } from 'src/modules/default_config_state.js'
|
import {
|
||||||
|
LOCAL_ONLY_KEYS,
|
||||||
|
ROOT_CONFIG,
|
||||||
|
ROOT_CONFIG_DEFINITIONS,
|
||||||
|
validateSetting,
|
||||||
|
} from 'src/modules/default_config_state.js'
|
||||||
import {
|
import {
|
||||||
newExporter,
|
newExporter,
|
||||||
newImporter,
|
newImporter,
|
||||||
|
|
@ -138,37 +143,52 @@ const SettingsModal = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onImport(data) {
|
onImport(input) {
|
||||||
if (data) {
|
if (!input) return
|
||||||
Object.entries(data).forEach(([path, value]) => {
|
const { _pleroma_settings_version, ...data } = input
|
||||||
if (LOCAL_ONLY_KEYS.has(path)) {
|
|
||||||
useLocalConfigStore().set({ path, value })
|
|
||||||
} else {
|
|
||||||
if (path.startsWith('muteFilters')) {
|
|
||||||
Object.keys(
|
|
||||||
useMergedConfigStore().mergedConfig.muteFilters,
|
|
||||||
).forEach((key) => {
|
|
||||||
useSyncConfigStore().unsetPreference({
|
|
||||||
path: `simple.${path}.${key}`,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Object.entries(value).forEach(([key, filter]) => {
|
Object.entries(data).forEach(([path, value]) => {
|
||||||
useSyncConfigStore().setPreference({
|
const definition = ROOT_CONFIG_DEFINITIONS[path]
|
||||||
path: `simple.${path}.${key}`,
|
|
||||||
value: filter,
|
const finalValue = validateSetting({
|
||||||
})
|
path,
|
||||||
|
value,
|
||||||
|
definition,
|
||||||
|
throwError: false,
|
||||||
|
defaultState: ROOT_CONFIG,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (finalValue === undefined) return
|
||||||
|
|
||||||
|
if (LOCAL_ONLY_KEYS.has(path)) {
|
||||||
|
useLocalConfigStore().set({ path, value: finalValue })
|
||||||
|
} else {
|
||||||
|
if (path.startsWith('muteFilters')) {
|
||||||
|
Object.keys(
|
||||||
|
useMergedConfigStore().mergedConfig.muteFilters,
|
||||||
|
).forEach((key) => {
|
||||||
|
useSyncConfigStore().unsetPreference({
|
||||||
|
path: `simple.${path}.${key}`,
|
||||||
})
|
})
|
||||||
} else {
|
})
|
||||||
|
|
||||||
|
Object.entries(value).forEach(([key, filter]) => {
|
||||||
|
useSyncConfigStore().setPreference({
|
||||||
|
path: `simple.${path}.${key}`,
|
||||||
|
value: filter,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (finalValue !== undefined) {
|
||||||
useSyncConfigStore().setPreference({
|
useSyncConfigStore().setPreference({
|
||||||
path: `simple.${path}`,
|
path: `simple.${path}`,
|
||||||
value,
|
value: finalValue,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
useSyncConfigStore().pushSyncConfig()
|
})
|
||||||
}
|
useSyncConfigStore().pushSyncConfig()
|
||||||
},
|
},
|
||||||
restore() {
|
restore() {
|
||||||
this.dataImporter.importData()
|
this.dataImporter.importData()
|
||||||
|
|
@ -184,10 +204,17 @@ const SettingsModal = {
|
||||||
let sample = config
|
let sample = config
|
||||||
if (!theme) {
|
if (!theme) {
|
||||||
const ignoreList = new Set([
|
const ignoreList = new Set([
|
||||||
|
'theme',
|
||||||
'customTheme',
|
'customTheme',
|
||||||
'customThemeSource',
|
'customThemeSource',
|
||||||
'colors',
|
'colors',
|
||||||
|
'style',
|
||||||
|
'styleCustomData',
|
||||||
|
'palette',
|
||||||
|
'paletteCustomData',
|
||||||
|
'themeChecksum',
|
||||||
])
|
])
|
||||||
|
|
||||||
sample = Object.fromEntries(
|
sample = Object.fromEntries(
|
||||||
Object.entries(sample).filter(
|
Object.entries(sample).filter(
|
||||||
([key, value]) => !ignoreList.has(key) && value !== undefined,
|
([key, value]) => !ignoreList.has(key) && value !== undefined,
|
||||||
|
|
|
||||||
|
|
@ -112,10 +112,19 @@ export const INSTANCE_IDENTITY_DEFAULT_DEFINITIONS = {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
name: {
|
||||||
|
description: 'Instance Name',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
export const INSTANCE_IDENTITY_DEFAULT = convertDefinitions(
|
export const INSTANCE_IDENTITY_DEFAULT = convertDefinitions(
|
||||||
INSTANCE_IDENTITY_DEFAULT_DEFINITIONS,
|
INSTANCE_IDENTITY_DEFAULT_DEFINITIONS,
|
||||||
)
|
)
|
||||||
|
export const INSTANCE_IDENTIY_EXTERNAL = new Set([
|
||||||
|
'tos',
|
||||||
|
'instanceSpecificPanelContent',
|
||||||
|
])
|
||||||
|
|
||||||
/// This object contains setting entries that makes sense
|
/// This object contains setting entries that makes sense
|
||||||
/// at the user level. The defaults can also be overriden by
|
/// at the user level. The defaults can also be overriden by
|
||||||
|
|
@ -522,6 +531,18 @@ export const INSTANCE_DEFAULT_CONFIG_DEFINITIONS = {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
theme3hacks: {
|
||||||
|
description: 'Theme 3 hacks (need separation)',
|
||||||
|
type: 'object',
|
||||||
|
required: false,
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
highlights: {
|
||||||
|
description: 'User highlights',
|
||||||
|
type: 'object',
|
||||||
|
required: false,
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
export const INSTANCE_DEFAULT_CONFIG = convertDefinitions(
|
export const INSTANCE_DEFAULT_CONFIG = convertDefinitions(
|
||||||
INSTANCE_DEFAULT_CONFIG_DEFINITIONS,
|
INSTANCE_DEFAULT_CONFIG_DEFINITIONS,
|
||||||
|
|
@ -663,6 +684,11 @@ export const SYNC_DEFAULT_CONFIG_DEFINITIONS = {
|
||||||
description: 'Collapse navigation panel to header only',
|
description: 'Collapse navigation panel to header only',
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
muteFilters: {
|
||||||
|
description: 'Object containing mute filters',
|
||||||
|
type: 'object',
|
||||||
|
default: {},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export const SYNC_DEFAULT_CONFIG = convertDefinitions(
|
export const SYNC_DEFAULT_CONFIG = convertDefinitions(
|
||||||
SYNC_DEFAULT_CONFIG_DEFINITIONS,
|
SYNC_DEFAULT_CONFIG_DEFINITIONS,
|
||||||
|
|
@ -731,14 +757,27 @@ export const ROOT_CONFIG_DEFINITIONS = {
|
||||||
|
|
||||||
export const validateSetting = ({
|
export const validateSetting = ({
|
||||||
value,
|
value,
|
||||||
path,
|
path: fullPath,
|
||||||
definition,
|
definition,
|
||||||
throwError,
|
throwError,
|
||||||
defaultState,
|
defaultState,
|
||||||
|
validateObjects = true,
|
||||||
}) => {
|
}) => {
|
||||||
if (value === undefined) return // only null is allowed as missing value
|
const path = fullPath.replace(/^simple./, '')
|
||||||
if (get(defaultState, path) === undefined) {
|
if (validateObjects && definition.type === 'object' && path.split('.').length <= 1) {
|
||||||
const string = `Unknown instance option ${path}, value: ${value}`
|
console.error(`attempt to set object ${fullPath} instead of its children. ignoring.`)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.includes('muteFilters')) {
|
||||||
|
console.log('##', path, value, definition)
|
||||||
|
console.log(value)
|
||||||
|
console.log(path)
|
||||||
|
console.log('====')
|
||||||
|
}
|
||||||
|
if (value === undefined) return undefined // only null is allowed as missing value
|
||||||
|
if (get(defaultState, path.split('.')[0]) === undefined) {
|
||||||
|
const string = `Unknown option ${fullPath}, value: ${value}`
|
||||||
|
|
||||||
if (throwError) {
|
if (throwError) {
|
||||||
throw new Error(string)
|
throw new Error(string)
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ export const useInstanceStore = defineStore('instance', {
|
||||||
definition,
|
definition,
|
||||||
throwError: true,
|
throwError: true,
|
||||||
defaultState: DEFAULT_STATE,
|
defaultState: DEFAULT_STATE,
|
||||||
|
validateObjects: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
set(this, path, finalValue)
|
set(this, path, finalValue)
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,10 @@ import { useLocalConfigStore } from 'src/stores/local_config.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
INSTANCE_DEFAULT_CONFIG,
|
|
||||||
LOCAL_DEFAULT_CONFIG,
|
|
||||||
LOCAL_ONLY_KEYS,
|
LOCAL_ONLY_KEYS,
|
||||||
THEME_CONFIG,
|
ROOT_CONFIG,
|
||||||
} from 'src/modules/default_config_state.js'
|
} from 'src/modules/default_config_state.js'
|
||||||
|
|
||||||
const ROOT_CONFIG = {
|
|
||||||
...INSTANCE_DEFAULT_CONFIG,
|
|
||||||
...LOCAL_DEFAULT_CONFIG,
|
|
||||||
...THEME_CONFIG,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useMergedConfigStore = defineStore('merged_config', {
|
export const useMergedConfigStore = defineStore('merged_config', {
|
||||||
getters: {
|
getters: {
|
||||||
mergedConfig: () => {
|
mergedConfig: () => {
|
||||||
|
|
@ -50,16 +42,15 @@ export const useMergedConfigStore = defineStore('merged_config', {
|
||||||
return result
|
return result
|
||||||
},
|
},
|
||||||
mergedConfigWithoutDefaults: () => {
|
mergedConfigWithoutDefaults: () => {
|
||||||
const instancePrefs = useInstanceStore().prefsStorage
|
|
||||||
const tempPrefs = useLocalConfigStore().tempStorage
|
const tempPrefs = useLocalConfigStore().tempStorage
|
||||||
const localPrefs = useLocalConfigStore().prefsStorage
|
const localPrefs = useLocalConfigStore().prefsStorage
|
||||||
const syncPrefs = useSyncConfigStore().prefsStorage
|
const syncPrefs = useSyncConfigStore().prefsStorage
|
||||||
|
|
||||||
const getValue = (k) =>
|
const getValue = (k) =>
|
||||||
tempPrefs[k] ?? localPrefs[k] ?? syncPrefs.simple[k] ?? instancePrefs[k]
|
tempPrefs[k] ?? localPrefs[k] ?? syncPrefs.simple[k]
|
||||||
|
|
||||||
const result = Object.fromEntries(
|
const result = Object.fromEntries(
|
||||||
Object.keys(ROOT_CONFIG).map(([k, value]) => [k, getValue(k)]),
|
Object.keys(ROOT_CONFIG).map((k) => [k, getValue(k)]),
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -295,12 +295,14 @@ export const _mergePrefs = (recent, stale) => {
|
||||||
const entry = path.split('.')[1]
|
const entry = path.split('.')[1]
|
||||||
if (operation === 'unset') return ROOT_CONFIG[entry] !== undefined
|
if (operation === 'unset') return ROOT_CONFIG[entry] !== undefined
|
||||||
|
|
||||||
|
if (operation !== 'set') return true
|
||||||
|
|
||||||
const definition = path.startsWith('simple.muteFilters')
|
const definition = path.startsWith('simple.muteFilters')
|
||||||
? { default: {} }
|
? { default: {} }
|
||||||
: ROOT_CONFIG_DEFINITIONS[entry]
|
: ROOT_CONFIG_DEFINITIONS[entry]
|
||||||
|
|
||||||
const finalValue = validateSetting({
|
const finalValue = validateSetting({
|
||||||
path: entry,
|
path,
|
||||||
value: args[0],
|
value: args[0],
|
||||||
definition,
|
definition,
|
||||||
throwError: false,
|
throwError: false,
|
||||||
|
|
@ -507,12 +509,14 @@ export const useSyncConfigStore = defineStore('sync_config', {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (path.startsWith('collections.')) return value
|
||||||
|
|
||||||
const definition = path.startsWith('simple.muteFilters')
|
const definition = path.startsWith('simple.muteFilters')
|
||||||
? { default: {} }
|
? { default: {} }
|
||||||
: ROOT_CONFIG_DEFINITIONS[path.split('.')[1]]
|
: ROOT_CONFIG_DEFINITIONS[path.split('.')[1]]
|
||||||
|
|
||||||
const finalValue = validateSetting({
|
const finalValue = validateSetting({
|
||||||
path: path.split('.')[1],
|
path,
|
||||||
value,
|
value,
|
||||||
definition,
|
definition,
|
||||||
throwError: false,
|
throwError: false,
|
||||||
|
|
@ -773,21 +777,19 @@ export const useSyncConfigStore = defineStore('sync_config', {
|
||||||
afterLoad(state) {
|
afterLoad(state) {
|
||||||
console.debug('Validating persisted state of SyncConfig')
|
console.debug('Validating persisted state of SyncConfig')
|
||||||
const newState = { ...state }
|
const newState = { ...state }
|
||||||
const newEntries = Object.entries(newState.prefsStorage.simple).map(
|
const newEntries = Object.entries(ROOT_CONFIG).map(
|
||||||
([path, value]) => {
|
([path, value]) => {
|
||||||
if (path === 'muteFilters') {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
const definition = ROOT_CONFIG_DEFINITIONS[path]
|
const definition = ROOT_CONFIG_DEFINITIONS[path]
|
||||||
const finalValue = validateSetting({
|
const finalValue = validateSetting({
|
||||||
path,
|
path,
|
||||||
value,
|
value: newState.prefsStorage.simple[path],
|
||||||
definition,
|
definition,
|
||||||
throwError: false,
|
throwError: false,
|
||||||
|
validateObjects: false,
|
||||||
defaultState: ROOT_CONFIG,
|
defaultState: ROOT_CONFIG,
|
||||||
})
|
})
|
||||||
|
|
||||||
return finalValue === undefined ? undefined : [path, finalValue]
|
return finalValue === undefined ? definition.default : [path, finalValue]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
newState.prefsStorage.simple = Object.fromEntries(
|
newState.prefsStorage.simple = Object.fromEntries(
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,9 @@ describe('The SyncConfig store', () => {
|
||||||
store.setPreference({ path: 'simple.fontInput.family', value: 'test' })
|
store.setPreference({ path: 'simple.fontInput.family', value: 'test' })
|
||||||
store.unsetPreference({ path: 'simple.fontInput.family' })
|
store.unsetPreference({ path: 'simple.fontInput.family' })
|
||||||
store.updateCache(store, { username: 'test' })
|
store.updateCache(store, { username: 'test' })
|
||||||
expect(store.prefsStorage.simple.fontInput).to.not.have.property('family')
|
expect(store.prefsStorage.simple.fontInput).to.not.have.property(
|
||||||
|
'family',
|
||||||
|
)
|
||||||
expect(store.prefsStorage._journal.length).to.eql(1)
|
expect(store.prefsStorage._journal.length).to.eql(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -395,7 +397,12 @@ describe('The SyncConfig store', () => {
|
||||||
{
|
{
|
||||||
simple: { theme: '1', style: '0', hideISP: true },
|
simple: { theme: '1', style: '0', hideISP: true },
|
||||||
_journal: [
|
_journal: [
|
||||||
{ path: 'simple.style', operation: 'set', args: ['0'], timestamp: 2 },
|
{
|
||||||
|
path: 'simple.style',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['0'],
|
||||||
|
timestamp: 2,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'simple.hideISP',
|
path: 'simple.hideISP',
|
||||||
operation: 'set',
|
operation: 'set',
|
||||||
|
|
@ -408,17 +415,42 @@ describe('The SyncConfig store', () => {
|
||||||
{
|
{
|
||||||
simple: { theme: '1', style: '1', hideISP: false },
|
simple: { theme: '1', style: '1', hideISP: false },
|
||||||
_journal: [
|
_journal: [
|
||||||
{ path: 'simple.theme', operation: 'set', args: ['1'], timestamp: 1 },
|
{
|
||||||
{ path: 'simple.style', operation: 'set', args: ['1'], timestamp: 3 },
|
path: 'simple.theme',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['1'],
|
||||||
|
timestamp: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'simple.style',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['1'],
|
||||||
|
timestamp: 3,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
).to.eql({
|
).to.eql({
|
||||||
simple: { theme: '1', style: '1', hideISP: true },
|
simple: { theme: '1', style: '1', hideISP: true },
|
||||||
_journal: [
|
_journal: [
|
||||||
{ path: 'simple.theme', operation: 'set', args: ['1'], timestamp: 1 },
|
{
|
||||||
{ path: 'simple.style', operation: 'set', args: ['1'], timestamp: 3 },
|
path: 'simple.theme',
|
||||||
{ path: 'simple.hideISP', operation: 'set', args: [true], timestamp: 4 },
|
operation: 'set',
|
||||||
|
args: ['1'],
|
||||||
|
timestamp: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'simple.style',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['1'],
|
||||||
|
timestamp: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'simple.hideISP',
|
||||||
|
operation: 'set',
|
||||||
|
args: [true],
|
||||||
|
timestamp: 4,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -430,7 +462,12 @@ describe('The SyncConfig store', () => {
|
||||||
{
|
{
|
||||||
simple: { theme: '1', style: '0', hideISP: false },
|
simple: { theme: '1', style: '0', hideISP: false },
|
||||||
_journal: [
|
_journal: [
|
||||||
{ path: 'simple.style', operation: 'set', args: ['0'], timestamp: 2 },
|
{
|
||||||
|
path: 'simple.style',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['0'],
|
||||||
|
timestamp: 2,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'simple.hideISP',
|
path: 'simple.hideISP',
|
||||||
operation: 'set',
|
operation: 'set',
|
||||||
|
|
@ -443,18 +480,42 @@ describe('The SyncConfig store', () => {
|
||||||
{
|
{
|
||||||
simple: { theme: '0', style: '0', hideISP: true },
|
simple: { theme: '0', style: '0', hideISP: true },
|
||||||
_journal: [
|
_journal: [
|
||||||
{ path: 'simple.theme', operation: 'set', args: ['0'], timestamp: 1 },
|
{
|
||||||
{ path: 'simple.style', operation: 'set', args: ['0'], timestamp: 3 },
|
path: 'simple.theme',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['0'],
|
||||||
|
timestamp: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'simple.style',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['0'],
|
||||||
|
timestamp: 3,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
).to.eql({
|
).to.eql({
|
||||||
simple: { a: 0, b: 0, c: false },
|
|
||||||
simple: { theme: '0', style: '0', hideISP: false },
|
simple: { theme: '0', style: '0', hideISP: false },
|
||||||
_journal: [
|
_journal: [
|
||||||
{ path: 'simple.theme', operation: 'set', args: ['0'], timestamp: 1 },
|
{
|
||||||
{ path: 'simple.style', operation: 'set', args: ['0'], timestamp: 3 },
|
path: 'simple.theme',
|
||||||
{ path: 'simple.hideISP', operation: 'set', args: [false], timestamp: 4 },
|
operation: 'set',
|
||||||
|
args: ['0'],
|
||||||
|
timestamp: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'simple.style',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['0'],
|
||||||
|
timestamp: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'simple.hideISP',
|
||||||
|
operation: 'set',
|
||||||
|
args: [false],
|
||||||
|
timestamp: 4,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -490,7 +551,12 @@ describe('The SyncConfig store', () => {
|
||||||
).to.eql({
|
).to.eql({
|
||||||
simple: { theme: 'bar' },
|
simple: { theme: 'bar' },
|
||||||
_journal: [
|
_journal: [
|
||||||
{ path: 'simple.theme', operation: 'set', args: ['bar'], timestamp: 4 },
|
{
|
||||||
|
path: 'simple.theme',
|
||||||
|
operation: 'set',
|
||||||
|
args: ['bar'],
|
||||||
|
timestamp: 4,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue