Add StorageState class
This commit is contained in:
parent
287aa98955
commit
2e540dbc6f
1 changed files with 59 additions and 7 deletions
66
state.js
66
state.js
|
@ -9,13 +9,18 @@ export class State extends EventTarget {
|
||||||
#target
|
#target
|
||||||
#options
|
#options
|
||||||
#queue
|
#queue
|
||||||
|
|
||||||
constructor(target={}, options={}) {
|
constructor(target={}, options={}) {
|
||||||
super()
|
super()
|
||||||
this.#options = options
|
this.#options = options
|
||||||
this.#target = target
|
this.#target = target
|
||||||
this.proxy = new Proxy(target, {
|
this.proxy = new Proxy(target, {
|
||||||
set: (_target, prop, value) => { this.set(prop, value); return true },
|
set: (_target, prop, value) => {
|
||||||
get: (target, prop) => target[prop],
|
this.emit(prop, value)
|
||||||
|
this.set(prop, value)
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
get: (_target, prop) => this.get(prop),
|
||||||
})
|
})
|
||||||
|
|
||||||
this.addEventListener
|
this.addEventListener
|
||||||
|
@ -29,10 +34,10 @@ export class State extends EventTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set state(value) { this.proxy.state = value }
|
set value(value) { this.proxy.value = value }
|
||||||
get state() { return this.proxy.state }
|
get value() { return this.proxy.value }
|
||||||
|
|
||||||
set(prop, value) {
|
emit(prop, value) {
|
||||||
if (this.#options.defer ?? true) {
|
if (this.#options.defer ?? true) {
|
||||||
if (!this.#queue) {
|
if (!this.#queue) {
|
||||||
this.#queue = []
|
this.#queue = []
|
||||||
|
@ -42,12 +47,59 @@ export class State extends EventTarget {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.#queue.push([prop, value])
|
this.#queue.push([prop, value])
|
||||||
this.#target[prop] = value
|
|
||||||
} else {
|
} else {
|
||||||
this.#target[prop] = value
|
|
||||||
this.dispatchEvent(new ChangeEvent([prop, value]))
|
this.dispatchEvent(new ChangeEvent([prop, value]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set(prop, value) {
|
||||||
|
this.#target[prop] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
get(prop) {
|
||||||
|
return this.#target[prop]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class StoredState extends State {
|
||||||
|
#storage
|
||||||
|
#valueKey
|
||||||
|
|
||||||
|
constructor(init, options={}) {
|
||||||
|
super({}, options)
|
||||||
|
this.#storage = options.storage ?? localStorage
|
||||||
|
this.#valueKey = options.key ?? 'value'
|
||||||
|
|
||||||
|
// Initialise storage from defaults
|
||||||
|
for (const [key, value] of Object.entries(init)) {
|
||||||
|
if (this.#storage[key] == undefined)
|
||||||
|
this.set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit change events for any changed keys
|
||||||
|
for (let i=0; i<this.#storage.length; i++) {
|
||||||
|
const key = this.#storage.key(i)
|
||||||
|
const value = this.#storage[key]
|
||||||
|
if (value !== JSON.stringify(init[key]))
|
||||||
|
this.emit(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener("storage", event => {
|
||||||
|
let prop = event.key
|
||||||
|
if (prop === this.#valueKey) prop = 'value'
|
||||||
|
this.emit(prop, event.newValue)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
set(prop, value) {
|
||||||
|
if (prop == "value") prop = this.#valueKey
|
||||||
|
this.#storage[prop] = JSON.stringify(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(prop) {
|
||||||
|
if (prop == "value") prop = this.#valueKey
|
||||||
|
return JSON.parse(this.#storage[prop])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default State
|
export default State
|
||||||
|
|
Loading…
Reference in a new issue