mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-29 08:21:20 +00:00
Add repository to indexeddb
This commit is contained in:
parent
7896c9e5a0
commit
c6b3d74163
@ -28,7 +28,8 @@
|
|||||||
let element
|
let element
|
||||||
let filters: Filter[] = [{ids: []}]
|
let filters: Filter[] = [{ids: []}]
|
||||||
let limit = 0
|
let limit = 0
|
||||||
let opts = {
|
|
||||||
|
const {notes, start, load, feedLoader, opts} = new FeedLoader({
|
||||||
feed,
|
feed,
|
||||||
anchor,
|
anchor,
|
||||||
onEvent,
|
onEvent,
|
||||||
@ -40,9 +41,7 @@
|
|||||||
shouldDefer: !eager,
|
shouldDefer: !eager,
|
||||||
shouldLoadParents: true,
|
shouldLoadParents: true,
|
||||||
shouldHideReplies: Storage.getJson("hideReplies"),
|
shouldHideReplies: Storage.getJson("hideReplies"),
|
||||||
}
|
})
|
||||||
|
|
||||||
const {notes, start, load, feedLoader} = new FeedLoader(opts)
|
|
||||||
|
|
||||||
const loadMore = async () => {
|
const loadMore = async () => {
|
||||||
limit += 5
|
limit += 5
|
||||||
@ -52,14 +51,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onChange = async opts => {
|
const onChange = async newOpts => {
|
||||||
limit = 0
|
limit = 0
|
||||||
feed = opts.feed
|
feed = newOpts.feed
|
||||||
Storage.setJson("hideReplies", opts.shouldHideReplies)
|
Storage.setJson("hideReplies", newOpts.shouldHideReplies)
|
||||||
start(opts)
|
start(newOpts)
|
||||||
|
|
||||||
if (feedLoader.compiler.canCompile(opts.feed)) {
|
if (feedLoader.compiler.canCompile(newOpts.feed)) {
|
||||||
const requests = await feedLoader.compiler.compile(opts.feed)
|
const requests = await feedLoader.compiler.compile(newOpts.feed)
|
||||||
|
|
||||||
filters = requests.flatMap(r => r.filters || [])
|
filters = requests.flatMap(r => r.filters || [])
|
||||||
} else {
|
} else {
|
||||||
@ -67,7 +66,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(opts)
|
start({})
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const scroller = createScroller(loadMore, {element})
|
const scroller = createScroller(loadMore, {element})
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import Bugsnag from "@bugsnag/js"
|
import Bugsnag from "@bugsnag/js"
|
||||||
import {uniq} from "ramda"
|
import {uniq} from "ramda"
|
||||||
import {hash} from "hurdak"
|
|
||||||
import {writable} from "@welshman/lib"
|
import {writable} from "@welshman/lib"
|
||||||
import {ConnectionStatus, NetworkContext} from "@welshman/net"
|
import {ConnectionStatus, NetworkContext} from "@welshman/net"
|
||||||
import type {Feed} from "@welshman/feeds"
|
import type {Feed} from "@welshman/feeds"
|
||||||
import {warn} from "src/util/logger"
|
|
||||||
import {userKinds} from "src/util/nostr"
|
import {userKinds} from "src/util/nostr"
|
||||||
import {router} from "src/app/util/router"
|
import {router} from "src/app/util/router"
|
||||||
import {
|
import {
|
||||||
@ -21,7 +19,6 @@ import {
|
|||||||
getUserRelayUrls,
|
getUserRelayUrls,
|
||||||
listenForNotifications,
|
listenForNotifications,
|
||||||
getSetting,
|
getSetting,
|
||||||
dufflepud,
|
|
||||||
} from "src/engine"
|
} from "src/engine"
|
||||||
|
|
||||||
// Global state
|
// Global state
|
||||||
@ -64,7 +61,7 @@ setTimeout(() => {
|
|||||||
|
|
||||||
export const logUsage = async (path: string) => {
|
export const logUsage = async (path: string) => {
|
||||||
if (getSetting("report_analytics")) {
|
if (getSetting("report_analytics")) {
|
||||||
const {location, plausible} = window
|
const {location, plausible} = window as any
|
||||||
const pathname = path.replace(/(npub|nprofile|note|nevent|naddr)1[^\/]+/g, (_, m) => `<${m}>`)
|
const pathname = path.replace(/(npub|nprofile|note|nevent|naddr)1[^\/]+/g, (_, m) => `<${m}>`)
|
||||||
|
|
||||||
plausible("pageview", {u: location.origin + pathname})
|
plausible("pageview", {u: location.origin + pathname})
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
<strong>Max relays per request</strong>
|
<strong>Max relays per request</strong>
|
||||||
<div>{settings.relay_limit} relays</div>
|
<div>{settings.relay_limit} relays</div>
|
||||||
</div>
|
</div>
|
||||||
<Input type="range" class="!bg-transparent" bind:value={settings.relay_limit} min={1} max={30} parse={parseInt} />
|
<Input type="range" bind:value={settings.relay_limit} min={1} max={30} parse={parseInt} />
|
||||||
<p slot="info">
|
<p slot="info">
|
||||||
This controls how many relays to max out at when loading feeds and event context. More is
|
This controls how many relays to max out at when loading feeds and event context. More is
|
||||||
faster, but will require more bandwidth and processing power.
|
faster, but will require more bandwidth and processing power.
|
||||||
|
@ -2,7 +2,7 @@ import {prop, identity, pluck, splitAt, nth, sortBy} from "ramda"
|
|||||||
import {sleep, defer, chunk, randomInt, throttle} from "hurdak"
|
import {sleep, defer, chunk, randomInt, throttle} from "hurdak"
|
||||||
import {Storage as LocalStorage} from "hurdak"
|
import {Storage as LocalStorage} from "hurdak"
|
||||||
import {writable} from "@welshman/lib"
|
import {writable} from "@welshman/lib"
|
||||||
import type {Writable, Collection} from "@welshman/lib"
|
import type {IWritable} from "@welshman/lib"
|
||||||
import logger from "src/util/logger"
|
import logger from "src/util/logger"
|
||||||
import {sessions} from "src/engine/session/state"
|
import {sessions} from "src/engine/session/state"
|
||||||
import {people} from "src/engine/people/state"
|
import {people} from "src/engine/people/state"
|
||||||
@ -143,7 +143,7 @@ export type LocalStorageAdapterOpts = {
|
|||||||
export class LocalStorageAdapter {
|
export class LocalStorageAdapter {
|
||||||
constructor(
|
constructor(
|
||||||
readonly key: string,
|
readonly key: string,
|
||||||
readonly store: Writable<any>,
|
readonly store: IWritable<any>,
|
||||||
readonly opts?: LocalStorageAdapterOpts,
|
readonly opts?: LocalStorageAdapterOpts,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -162,7 +162,8 @@ export class LocalStorageAdapter {
|
|||||||
export class IndexedDBAdapter {
|
export class IndexedDBAdapter {
|
||||||
constructor(
|
constructor(
|
||||||
readonly key: string,
|
readonly key: string,
|
||||||
readonly store: Collection<any>,
|
readonly keyPath: string,
|
||||||
|
readonly store: IWritable<any>,
|
||||||
readonly max: number,
|
readonly max: number,
|
||||||
readonly sort?: (xs: any[]) => any[],
|
readonly sort?: (xs: any[]) => any[],
|
||||||
readonly filter?: (x: any) => boolean,
|
readonly filter?: (x: any) => boolean,
|
||||||
@ -173,13 +174,13 @@ export class IndexedDBAdapter {
|
|||||||
return {
|
return {
|
||||||
name: this.key,
|
name: this.key,
|
||||||
opts: {
|
opts: {
|
||||||
keyPath: this.store.pk,
|
keyPath: this.keyPath,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialize(storage: Storage) {
|
async initialize(storage: Storage) {
|
||||||
const {key, store} = this
|
const {key, keyPath, store} = this
|
||||||
const data = await storage.db.getAll(key)
|
const data = await storage.db.getAll(key)
|
||||||
const filter = this.filter || identity
|
const filter = this.filter || identity
|
||||||
const migrate = this.migrate || identity
|
const migrate = this.migrate || identity
|
||||||
@ -193,7 +194,7 @@ export class IndexedDBAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do it in small steps to avoid clogging stuff up
|
// Do it in small steps to avoid clogging stuff up
|
||||||
for (const records of chunk(100, (rows as any[]).filter(prop(store.pk)))) {
|
for (const records of chunk(100, (rows as any[]).filter(prop(keyPath)))) {
|
||||||
await storage.db.bulkPut(key, records)
|
await storage.db.bulkPut(key, records)
|
||||||
await sleep(50)
|
await sleep(50)
|
||||||
|
|
||||||
@ -206,7 +207,7 @@ export class IndexedDBAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prune(storage) {
|
prune(storage) {
|
||||||
const {store, key, max, sort} = this
|
const {store, key, keyPath, max, sort} = this
|
||||||
const data = store.get()
|
const data = store.get()
|
||||||
|
|
||||||
if (data.length < max * 1.1 || storage.dead.get()) {
|
if (data.length < max * 1.1 || storage.dead.get()) {
|
||||||
@ -217,7 +218,10 @@ export class IndexedDBAdapter {
|
|||||||
|
|
||||||
store.set(keep)
|
store.set(keep)
|
||||||
|
|
||||||
storage.db.bulkDelete(key, pluck(store.pk, discard))
|
storage.db.bulkDelete(
|
||||||
|
key,
|
||||||
|
discard.map(x => x[keyPath]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import {topics} from "./topics"
|
|||||||
import {deletes, seen, _events, isDeleted, publishes} from "./events"
|
import {deletes, seen, _events, isDeleted, publishes} from "./events"
|
||||||
import {pubkey, sessions} from "./session"
|
import {pubkey, sessions} from "./session"
|
||||||
import {channels} from "./channels"
|
import {channels} from "./channels"
|
||||||
import {onAuth, getExecutor, tracker} from "./network"
|
import {onAuth, getExecutor, tracker, repository} from "./network"
|
||||||
|
|
||||||
export * from "./core"
|
export * from "./core"
|
||||||
export * from "./auth"
|
export * from "./auth"
|
||||||
@ -48,6 +48,12 @@ const setAdapter = {
|
|||||||
load: a => new Set(a || []),
|
load: a => new Set(a || []),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const repositoryStore = {
|
||||||
|
get: () => repository.get(),
|
||||||
|
set: data => repository.load(data),
|
||||||
|
subscribe: () => repository.derived(r => r.dump()),
|
||||||
|
}
|
||||||
|
|
||||||
// Nip 04 channels weren't getting members set
|
// Nip 04 channels weren't getting members set
|
||||||
const migrateChannels = channels => {
|
const migrateChannels = channels => {
|
||||||
return channels.map(c => {
|
return channels.map(c => {
|
||||||
@ -67,35 +73,56 @@ const sessionsAdapter = {
|
|||||||
dump: identity,
|
dump: identity,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const storage = new Storage(11, [
|
export const storage = new Storage(12, [
|
||||||
new LocalStorageAdapter("pubkey", pubkey),
|
new LocalStorageAdapter("pubkey", pubkey),
|
||||||
new LocalStorageAdapter("sessions", sessions, sessionsAdapter),
|
new LocalStorageAdapter("sessions", sessions, sessionsAdapter),
|
||||||
new LocalStorageAdapter("deletes2", deletes, setAdapter),
|
new LocalStorageAdapter("deletes2", deletes, setAdapter),
|
||||||
new IndexedDBAdapter("seen3", seen, 10000, sortBy(prop("created_at"))),
|
new IndexedDBAdapter("seen3", "id", seen, 10000, sortBy(prop("created_at"))),
|
||||||
new IndexedDBAdapter("events", _events, 10000, sortByPubkeyWhitelist(prop("created_at"))),
|
new IndexedDBAdapter("events", "id", _events, 10000, sortByPubkeyWhitelist(prop("created_at"))),
|
||||||
new IndexedDBAdapter("publishes", publishes, 100, sortByPubkeyWhitelist(prop("created_at"))),
|
new IndexedDBAdapter(
|
||||||
new IndexedDBAdapter("labels", _labels, 1000, sortBy(prop("created_at"))),
|
"publishes",
|
||||||
new IndexedDBAdapter("topics", topics, 1000, sortBy(prop("last_seen"))),
|
"id",
|
||||||
|
publishes,
|
||||||
|
100,
|
||||||
|
sortByPubkeyWhitelist(prop("created_at")),
|
||||||
|
),
|
||||||
|
new IndexedDBAdapter("labels", "id", _labels, 1000, sortBy(prop("created_at"))),
|
||||||
|
new IndexedDBAdapter("topics", "name", topics, 1000, sortBy(prop("last_seen"))),
|
||||||
new IndexedDBAdapter(
|
new IndexedDBAdapter(
|
||||||
"lists",
|
"lists",
|
||||||
|
"naddr",
|
||||||
_lists,
|
_lists,
|
||||||
1000,
|
1000,
|
||||||
sortByPubkeyWhitelist(prop("created_at")),
|
sortByPubkeyWhitelist(prop("created_at")),
|
||||||
l => l.address,
|
l => l.address,
|
||||||
),
|
),
|
||||||
new IndexedDBAdapter("people", people, 5000, sortByPubkeyWhitelist(prop("last_fetched"))),
|
new IndexedDBAdapter(
|
||||||
new IndexedDBAdapter("relays", relays, 1000, sortBy(prop("count"))),
|
"people",
|
||||||
|
"pubkey",
|
||||||
|
people,
|
||||||
|
5000,
|
||||||
|
sortByPubkeyWhitelist(prop("last_fetched")),
|
||||||
|
),
|
||||||
|
new IndexedDBAdapter("relays", "url", relays, 1000, sortBy(prop("count"))),
|
||||||
new IndexedDBAdapter(
|
new IndexedDBAdapter(
|
||||||
"channels",
|
"channels",
|
||||||
|
"id",
|
||||||
channels,
|
channels,
|
||||||
1000,
|
1000,
|
||||||
sortBy(prop("last_checked")),
|
sortBy(prop("last_checked")),
|
||||||
null,
|
null,
|
||||||
migrateChannels,
|
migrateChannels,
|
||||||
),
|
),
|
||||||
new IndexedDBAdapter("groups", groups, 1000, sortBy(prop("count"))),
|
new IndexedDBAdapter("groups", "address", groups, 1000, sortBy(prop("count"))),
|
||||||
new IndexedDBAdapter("groupAlerts", groupAlerts, 30, sortBy(prop("created_at"))),
|
new IndexedDBAdapter("groupAlerts", "id", groupAlerts, 30, sortBy(prop("created_at"))),
|
||||||
new IndexedDBAdapter("groupRequests", groupRequests, 100, sortBy(prop("created_at"))),
|
new IndexedDBAdapter("groupRequests", "id", groupRequests, 100, sortBy(prop("created_at"))),
|
||||||
new IndexedDBAdapter("groupSharedKeys", groupSharedKeys, 1000, sortBy(prop("created_at"))),
|
new IndexedDBAdapter(
|
||||||
new IndexedDBAdapter("groupAdminKeys", groupAdminKeys, 1000),
|
"groupSharedKeys",
|
||||||
|
"pubkey",
|
||||||
|
groupSharedKeys,
|
||||||
|
1000,
|
||||||
|
sortBy(prop("created_at")),
|
||||||
|
),
|
||||||
|
new IndexedDBAdapter("groupAdminKeys", "pubkey", groupAdminKeys, 1000),
|
||||||
|
new IndexedDBAdapter("repository", "id", repositoryStore as any, 10000),
|
||||||
])
|
])
|
||||||
|
@ -217,7 +217,7 @@ export const createAndPublish = async ({
|
|||||||
const template = createEvent(kind, {content, tags})
|
const template = createEvent(kind, {content, tags})
|
||||||
const event = await sign(template, {anonymous, sk})
|
const event = await sign(template, {anonymous, sk})
|
||||||
|
|
||||||
return publish({event, relays, verb, signal: AbortSignal.timeout(timeout)})
|
return publish({event, relays, verb, timeout})
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
|
@ -22,16 +22,17 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={cx($$props.class, "shadow-inset relative rounded h-7 overflow-hidden", {
|
class={cx($$props.class, "shadow-inset relative h-7 overflow-hidden rounded", {
|
||||||
|
"!bg-transparent": $$props.type === "range",
|
||||||
"bg-neutral-900 text-neutral-100": dark,
|
"bg-neutral-900 text-neutral-100": dark,
|
||||||
"bg-white dark:text-neutral-900": !dark,
|
"bg-white dark:text-neutral-900": !dark,
|
||||||
})}>
|
})}>
|
||||||
<input
|
<input
|
||||||
{...$$props}
|
{...$$props}
|
||||||
class={cx(
|
class={cx("h-7 w-full bg-transparent px-3 pb-px outline-none placeholder:text-neutral-400", {
|
||||||
"outline-none px-3 w-full placeholder:text-neutral-400 h-7 bg-transparent pb-px",
|
"pl-10": showBefore,
|
||||||
{"pl-10": showBefore, "pr-10": showAfter},
|
"pr-10": showAfter,
|
||||||
)}
|
})}
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
bind:this={element}
|
bind:this={element}
|
||||||
on:input={onInput}
|
on:input={onInput}
|
||||||
@ -41,14 +42,15 @@
|
|||||||
on:input
|
on:input
|
||||||
on:keydown />
|
on:keydown />
|
||||||
{#if showBefore}
|
{#if showBefore}
|
||||||
<div class="absolute left-0 top-0 flex items-center gap-2 px-3 opacity-75 h-7">
|
<div class="absolute left-0 top-0 flex h-7 items-center gap-2 px-3 opacity-75">
|
||||||
<div>
|
<div>
|
||||||
<slot name="before" />
|
<slot name="before" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if showAfter}
|
{#if showAfter}
|
||||||
<div class="absolute right-0 top-0 m-px flex items-center gap-2 rounded-full px-3 opacity-75 h-7">
|
<div
|
||||||
|
class="absolute right-0 top-0 m-px flex h-7 items-center gap-2 rounded-full px-3 opacity-75">
|
||||||
<div>
|
<div>
|
||||||
<slot name="after" />
|
<slot name="after" />
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user