Improve speed of freshness and storage
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import {readable, derived, type Readable} from 'svelte/store'
|
import {readable, derived, type Readable} from 'svelte/store'
|
||||||
import {indexBy, type Maybe, now} from '@welshman/lib'
|
import {indexBy, type Maybe, now} from '@welshman/lib'
|
||||||
import {withGetter} from '@welshman/store'
|
import {withGetter} from '@welshman/store'
|
||||||
import {getFreshness, setFreshness} from './freshness'
|
import {getFreshness, setFreshnessThrottled} from './freshness'
|
||||||
|
|
||||||
export const collection = <T, LoadArgs extends any[]>({
|
export const collection = <T, LoadArgs extends any[]>({
|
||||||
name,
|
name,
|
||||||
@@ -42,7 +42,7 @@ export const collection = <T, LoadArgs extends any[]>({
|
|||||||
|
|
||||||
loadAttempts.set(key, attempt + 1)
|
loadAttempts.set(key, attempt + 1)
|
||||||
|
|
||||||
setFreshness(name, key, now())
|
setFreshnessThrottled({ns: name, key, ts: now()})
|
||||||
|
|
||||||
const promise = load(key, ...args)
|
const promise = load(key, ...args)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
import {writable} from 'svelte/store'
|
import {writable} from 'svelte/store'
|
||||||
import {assoc} from '@welshman/lib'
|
import {assoc, batch} from '@welshman/lib'
|
||||||
import {withGetter} from '@welshman/store'
|
import {withGetter} from '@welshman/store'
|
||||||
|
|
||||||
|
export type FreshnessUpdate = {
|
||||||
|
ns: string
|
||||||
|
key: string
|
||||||
|
ts: number
|
||||||
|
}
|
||||||
|
|
||||||
export const freshness = withGetter(writable<Record<string, number>>({}))
|
export const freshness = withGetter(writable<Record<string, number>>({}))
|
||||||
|
|
||||||
export const getFreshnessKey = (ns: string, key: string) => `${ns}:${key}`
|
export const getFreshnessKey = (ns: string, key: string) => `${ns}:${key}`
|
||||||
@@ -9,14 +15,15 @@ export const getFreshnessKey = (ns: string, key: string) => `${ns}:${key}`
|
|||||||
export const getFreshness = (ns: string, key: string) =>
|
export const getFreshness = (ns: string, key: string) =>
|
||||||
freshness.get()[getFreshnessKey(ns, key)] || 0
|
freshness.get()[getFreshnessKey(ns, key)] || 0
|
||||||
|
|
||||||
export const setFreshness = (ns: string, key: string, ts: number) =>
|
export const setFreshnessImmediate = ({ns, key, ts}: FreshnessUpdate) =>
|
||||||
freshness.update(assoc(getFreshnessKey(ns, key), ts))
|
freshness.update(assoc(getFreshnessKey(ns, key), ts))
|
||||||
|
|
||||||
export const setFreshnessBulk = (ns: string, updates: Record<string, number>) =>
|
export const setFreshnessThrottled = batch(100, (updates: FreshnessUpdate[]) =>
|
||||||
freshness.update($freshness => {
|
freshness.update($freshness => {
|
||||||
for (const [key, ts] of Object.entries(updates)) {
|
for (const {ns, key, ts} of updates) {
|
||||||
$freshness[key] = ts
|
$freshness[getFreshnessKey(ns, key)] = ts
|
||||||
}
|
}
|
||||||
|
|
||||||
return $freshness
|
return $freshness
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type {IDBPDatabase} from "idb"
|
|||||||
import {throttle} from "throttle-debounce"
|
import {throttle} from "throttle-debounce"
|
||||||
import {writable} from "svelte/store"
|
import {writable} from "svelte/store"
|
||||||
import type {Unsubscriber, Writable} from "svelte/store"
|
import type {Unsubscriber, Writable} from "svelte/store"
|
||||||
import {indexBy, fromPairs} from "@welshman/lib"
|
import {indexBy, equals, fromPairs} from "@welshman/lib"
|
||||||
import type {TrustedEvent, Repository} from "@welshman/util"
|
import type {TrustedEvent, Repository} from "@welshman/util"
|
||||||
import type {Tracker} from "@welshman/net"
|
import type {Tracker} from "@welshman/net"
|
||||||
import {withGetter, adapter, throttled, custom} from "@welshman/store"
|
import {withGetter, adapter, throttled, custom} from "@welshman/store"
|
||||||
@@ -69,12 +69,11 @@ export const initIndexedDbAdapter = async (name: string, adapter: IndexedDbAdapt
|
|||||||
const removedRecords = prevRecords.filter(r => !currentIds.has(r[adapter.keyPath]))
|
const removedRecords = prevRecords.filter(r => !currentIds.has(r[adapter.keyPath]))
|
||||||
|
|
||||||
const prevRecordsById = indexBy(item => item[adapter.keyPath], prevRecords)
|
const prevRecordsById = indexBy(item => item[adapter.keyPath], prevRecords)
|
||||||
const updatedRecords = currentRecords.filter(r => r !== prevRecordsById.get(r[adapter.keyPath]))
|
const updatedRecords = currentRecords.filter(r => !equals(r, prevRecordsById.get(r[adapter.keyPath])))
|
||||||
|
|
||||||
prevRecords = currentRecords
|
prevRecords = currentRecords
|
||||||
|
|
||||||
if (updatedRecords.length > 0) {
|
if (updatedRecords.length > 0) {
|
||||||
|
|
||||||
await bulkPut(name, updatedRecords)
|
await bulkPut(name, updatedRecords)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,24 +140,24 @@ export const storageAdapters = {
|
|||||||
fromObjectStore: <T>(store: Writable<Record<string, T>>, options: StorageAdapterOptions = {}) => ({
|
fromObjectStore: <T>(store: Writable<Record<string, T>>, options: StorageAdapterOptions = {}) => ({
|
||||||
options,
|
options,
|
||||||
keyPath: "key",
|
keyPath: "key",
|
||||||
store: throttled(options.throttle || 0, adapter({
|
store: adapter({
|
||||||
store: store,
|
store: throttled(options.throttle || 0, store),
|
||||||
forward: ($data: Record<string, T>) =>
|
forward: ($data: Record<string, T>) =>
|
||||||
Object.entries($data).map(([key, value]) => ({key, value})),
|
Object.entries($data).map(([key, value]) => ({key, value})),
|
||||||
backward: (data: {key: string, value: T}[]) =>
|
backward: (data: {key: string, value: T}[]) =>
|
||||||
fromPairs(data.map(({key, value}) => [key, value])),
|
fromPairs(data.map(({key, value}) => [key, value])),
|
||||||
})),
|
}),
|
||||||
}),
|
}),
|
||||||
fromMapStore: <T>(store: Writable<Map<string, T>>, options: StorageAdapterOptions = {}) => ({
|
fromMapStore: <T>(store: Writable<Map<string, T>>, options: StorageAdapterOptions = {}) => ({
|
||||||
options,
|
options,
|
||||||
keyPath: "key",
|
keyPath: "key",
|
||||||
store: throttled(options.throttle || 0, adapter({
|
store: adapter({
|
||||||
store: store,
|
store: throttled(options.throttle || 0, store),
|
||||||
forward: ($data: Map<string, T>) =>
|
forward: ($data: Map<string, T>) =>
|
||||||
Array.from($data.entries()).map(([key, value]) => ({key, value})),
|
Array.from($data.entries()).map(([key, value]) => ({key, value})),
|
||||||
backward: (data: {key: string, value: T}[]) =>
|
backward: (data: {key: string, value: T}[]) =>
|
||||||
new Map(data.map(({key, value}) => [key, value])),
|
new Map(data.map(({key, value}) => [key, value])),
|
||||||
})),
|
}),
|
||||||
}),
|
}),
|
||||||
fromTracker: (tracker: Tracker, options: StorageAdapterOptions = {}) => ({
|
fromTracker: (tracker: Tracker, options: StorageAdapterOptions = {}) => ({
|
||||||
options,
|
options,
|
||||||
|
|||||||
Reference in New Issue
Block a user