dispatch -> cmd

This commit is contained in:
Jonathan Staab 2022-12-23 13:32:31 -08:00
parent a7a41a659c
commit 34db1df405
9 changed files with 92 additions and 140 deletions

View File

@ -52,7 +52,6 @@ Coracle is currently in _alpha_ - expect bugs, slow loading times, and rough edg
- [ ] Note detail context not showing when navigating between note details (e.g. to parent)
- [ ] Show reply to on feed
- [ ] Write blog post
- [ ] Get rid of dispatch
- https://vitejs.dev/guide/features.html#web-workers
- https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
- https://web.dev/module-workers/

View File

@ -7,12 +7,11 @@
import {findReply} from "src/util/nostr"
import Preview from 'src/partials/Preview.svelte'
import Anchor from 'src/partials/Anchor.svelte'
import {dispatch} from "src/state/dispatch"
import {settings, modal} from "src/state/app"
import {formatTimestamp} from 'src/util/misc'
import Badge from "src/partials/Badge.svelte"
import Card from "src/partials/Card.svelte"
import {user} from 'src/relay'
import relay, {user} from 'src/relay'
export let note
export let depth = 0
@ -46,7 +45,7 @@
const react = content => {
if ($user) {
dispatch('reaction/create', content, note)
relay.cmd.createReaction(content, note)
} else {
navigate('/login')
}
@ -63,7 +62,7 @@
}
const deleteReaction = e => {
dispatch('event/delete', [e.id])
relay.cmd.deleteEvent([e.id])
if (e.content === '+') {
like = false
@ -86,7 +85,7 @@
const sendReply = () => {
if (reply) {
dispatch("reply/create", reply, note)
relay.cmd.createReply(reply, note)
reply = null
}

78
src/relay/cmd.js Normal file
View File

@ -0,0 +1,78 @@
import {isNil, uniqBy, last} from 'ramda'
import {first} from "hurdak/lib/hurdak"
import relay from 'src/relay'
const updateUser = updates => publishEvent(0, JSON.stringify(updates))
const addPetname = (person, pubkey, name) =>
publishEvent(3, '', uniqBy(t => t[1], person.petnames.concat([t("p", pubkey, name)])))
const removePetname = (person, pubkey) =>
publishEvent(3, '', uniqBy(t => t[1], person.petnames.filter(t => t[1] !== pubkey)))
const muffle = (person, pubkey, value) => {
const muffle = person.muffle
.filter(x => x[1] !== pubkey)
.concat([t("p", pubkey, value.toString())])
.filter(x => last(x) !== "1")
return publishEvent(12165, '', muffle)
}
const createRoom = room => publishEvent(40, JSON.stringify(room))
const updateRoom = ({id, ...room}) => publishEvent(41, JSON.stringify(room), [t("e", id)])
const createMessage = (roomId, content) => publishEvent(42, content, [t("e", roomId, "root")])
const createNote = (content, tags=[]) => publishEvent(1, content, tags)
const createReaction = (content, e) =>
publishEvent(7, content, copyTags(e, [t("p", e.pubkey), t("e", e.id, 'reply')]))
const createReply = (content, e) =>
publishEvent(1, content, copyTags(e, [t("p", e.pubkey), t("e", e.id, 'reply')]))
const deleteEvent = ids => publishEvent(5, '', ids.map(id => t("e", id)))
export default {
updateUser, addPetname, removePetname, muffle, createRoom, updateRoom, createMessage, createNote,
createReaction, createReply, deleteEvent,
}
// utils
const copyTags = (e, newTags = []) => {
return uniqBy(
t => t.join(':'),
e.tags
.filter(t => ["p", "e"].includes(t[0]))
.map(t => last(t) === 'reply' ? t.slice(0, -1) : t)
.concat(newTags)
)
}
export const t = (type, content, marker) => {
const tag = [type, content, first(Object.keys(relay.pool.getRelays()))]
if (!isNil(marker)) {
tag.push(marker)
}
return tag
}
const makeEvent = (kind, content = '', tags = []) => {
const pubkey = relay.pool.getPubkey()
const createdAt = Math.round(new Date().valueOf() / 1000)
return {kind, content, tags, pubkey, created_at: createdAt}
}
const publishEvent = async (...args) => {
const event = makeEvent(...args)
await relay.pool.publishEvent(event)
return event
}

View File

@ -6,6 +6,7 @@ import {escapeHtml} from 'src/util/html'
import {filterTags, findReply, findRoot} from 'src/util/nostr'
import {db} from 'src/relay/db'
import pool from 'src/relay/pool'
import cmd from 'src/relay/cmd'
// Livequery appears to swallow errors
@ -270,7 +271,7 @@ export const network = db.network
export const connections = db.connections
export default {
db, pool, lq, filterEvents, getOrLoadNote, filterReplies, findNote,
db, pool, cmd, lq, filterEvents, getOrLoadNote, filterReplies, findNote,
annotateChunk, renderNote, filterAlerts, login, addRelay, removeRelay,
follow, unfollow, loadNoteContext,
}

View File

@ -4,16 +4,15 @@
import {navigate} from "svelte-routing"
import Textarea from "src/partials/Textarea.svelte"
import Button from "src/partials/Button.svelte"
import {dispatch} from "src/state/dispatch"
import toast from "src/state/toast"
import {user} from "src/relay"
import relay, {user} from "src/relay"
let values = {}
const submit = async e => {
e.preventDefault()
await dispatch("note/create", values.content)
await relay.cmd.createNote(values.content)
toast.show("info", `Your note has been created!`)

View File

@ -8,7 +8,6 @@
import Tabs from "src/partials/Tabs.svelte"
import Button from "src/partials/Button.svelte"
import Notes from "src/partials/Notes.svelte"
import {t, dispatch} from 'src/state/dispatch'
import {modal} from "src/state/app"
import relay, {user, people} from 'src/relay'
@ -56,19 +55,13 @@
const setActiveTab = tab => navigate(`/people/${pubkey}/${tab}`)
const follow = () => {
const petnames = $user.petnames
.concat([t("p", pubkey, getPerson()?.name)])
dispatch('user/petnames', petnames)
relay.cmd.addPetname($user, pubkey, getPerson()?.name)
following = true
}
const unfollow = () => {
const petnames = $user.petnames
.filter(([_, pubkey]) => pubkey !== pubkey)
dispatch('user/petnames', petnames)
relay.cmd.removePetname($user, pubkey)
following = false
}

View File

@ -8,9 +8,8 @@
import Textarea from "src/partials/Textarea.svelte"
import Anchor from "src/partials/Anchor.svelte"
import Button from "src/partials/Button.svelte"
import {dispatch} from "src/state/dispatch"
import toast from "src/state/toast"
import {user} from "src/relay"
import relay, {user} from "src/relay"
let values = {picture: null, about: null, name: null}
@ -38,7 +37,7 @@
const submit = async event => {
event.preventDefault()
await dispatch("user/update", values)
await relay.cmd.updateUser(values)
navigate(`/people/${$user.pubkey}/profile`)

View File

@ -1,110 +0,0 @@
import {identity, isNil, uniqBy, last} from 'ramda'
import {first, defmulti} from "hurdak/lib/hurdak"
import relay from 'src/relay'
// Commands are processed in two layers:
// - App-oriented commands are created via dispatch
// - processEvent, which can be used to populate the database
// whether commands are coming from our instance or a remote instance.
export const dispatch = defmulti("dispatch", identity)
dispatch.addMethod("user/update", async (topic, updates) => {
await relay.pool.publishEvent(makeEvent(0, JSON.stringify(updates)))
})
dispatch.addMethod("user/petnames", async (topic, petnames) => {
await relay.pool.publishEvent(makeEvent(3, '', petnames))
})
dispatch.addMethod("user/muffle", async (topic, muffle) => {
await relay.pool.publishEvent(makeEvent(12165, '', muffle))
})
dispatch.addMethod("room/create", async (topic, room) => {
const event = makeEvent(40, JSON.stringify(room))
await relay.pool.publishEvent(event)
return event
})
dispatch.addMethod("room/update", async (topic, {id, ...room}) => {
const event = makeEvent(41, JSON.stringify(room), [t("e", id)])
await relay.pool.publishEvent(event)
return event
})
dispatch.addMethod("message/create", async (topic, roomId, content) => {
const event = makeEvent(42, content, [t("e", roomId, "root")])
await relay.pool.publishEvent(event)
return event
})
dispatch.addMethod("note/create", async (topic, content, tags=[]) => {
const event = makeEvent(1, content, tags)
await relay.pool.publishEvent(event)
return event
})
dispatch.addMethod("reaction/create", async (topic, content, e) => {
const tags = copyTags(e, [t("p", e.pubkey), t("e", e.id, 'reply')])
const event = makeEvent(7, content, tags)
await relay.pool.publishEvent(event)
return event
})
dispatch.addMethod("reply/create", async (topic, content, e) => {
const tags = copyTags(e, [t("p", e.pubkey), t("e", e.id, 'reply')])
const event = makeEvent(1, content, tags)
await relay.pool.publishEvent(event)
return event
})
dispatch.addMethod("event/delete", async (topic, ids) => {
const event = makeEvent(5, '', ids.map(id => t("e", id)))
await relay.pool.publishEvent(event)
return event
})
// utils
export const copyTags = (e, newTags = []) => {
// Remove reply type from e tags
return uniqBy(
t => t.join(':'),
e.tags
.filter(t => ["p", "e"].includes(t[0]))
.map(t => last(t) === 'reply' ? t.slice(0, -1) : t)
.concat(newTags)
)
}
export const t = (type, content, marker) => {
const tag = [type, content, first(Object.keys(relay.pool.getRelays()))]
if (!isNil(marker)) {
tag.push(marker)
}
return tag
}
export const makeEvent = (kind, content = '', tags = []) => {
const pubkey = relay.pool.getPubkey()
const createdAt = Math.round(new Date().valueOf() / 1000)
return {kind, content, tags, pubkey, created_at: createdAt}
}

View File

@ -1,13 +1,11 @@
<script>
import {last} from 'ramda'
import {switcher} from 'hurdak/lib/hurdak'
import {fly} from 'svelte/transition'
import Button from "src/partials/Button.svelte"
import SelectButton from "src/partials/SelectButton.svelte"
import {getMuffleValue} from "src/util/nostr"
import {dispatch, t} from 'src/state/dispatch'
import {modal} from "src/state/app"
import {user} from 'src/relay'
import relay, {user} from 'src/relay'
const muffleOptions = ['Never', 'Sometimes', 'Often', 'Always']
@ -21,12 +19,8 @@
// Scale back down to a decimal based on string value
const muffleValue = muffleOptions.indexOf(values.muffle) / 3
const muffle = $user.muffle
.filter(x => x[1] !== $modal.person.pubkey)
.concat([t("p", $modal.person.pubkey, muffleValue.toString())])
.filter(x => last(x) !== "1")
dispatch('user/muffle', muffle)
relay.cmd.muffle($user, $modal.person.pubkey, muffleValue)
modal.set(null)
}