From 2ed88c334599878702ca025e5bce20c7a18bfc62 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Tue, 15 Jul 2025 21:26:53 -0700 Subject: [PATCH] Add setProfile and sync helper --- docs/app/publishing-events.md | 26 ++++++++++++++------ packages/app/src/commands.ts | 15 +++++++++++- packages/store/src/synced.ts | 45 ++++++++++++++++++++--------------- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/docs/app/publishing-events.md b/docs/app/publishing-events.md index 276508c..62ad69f 100644 --- a/docs/app/publishing-events.md +++ b/docs/app/publishing-events.md @@ -53,11 +53,23 @@ const publish = async (content: string) => { ## Built in commands -Several thunk factories are provided for more complicated scenarios like updating lists: +Several thunk factories are provided for common or more complicated scenarios like updating lists: -- `follow(pubkey)` -- `unfollow(pubkey)` -- `mute(pubkey)` -- `unmute(pubkey)` -- `pin(tag)` -- `unpin(tag)` +- `removeRelay(url: string, mode: RelayMode)` +- `addRelay(url: string, mode: RelayMode)` +- `removeInboxRelay(url: string)` +- `addInboxRelay(url: string)` +- `setProfile(profile: Profile)` +- `unfollow(value: string)` +- `follow(tag: string[])` +- `unmute(value: string)` +- `mute(tag: string[])` +- `unpin(value: string)` +- `pin(tag: string[])` +- `sendWrapped({template, pubkeys, ...options}: SendWrappedOptions)` +- `manageRelay(url: string, request: ManagementRequest)` +- `createRoom(url: string, room: RoomMeta)` +- `deleteRoom(url: string, room: RoomMeta)` +- `editRoom(url: string, room: RoomMeta)` +- `joinRoom(url: string, room: RoomMeta)` +- `leaveRoom(url: string, room: RoomMeta)` diff --git a/packages/app/src/commands.ts b/packages/app/src/commands.ts index 37cfe45..fcc7c95 100644 --- a/packages/app/src/commands.ts +++ b/packages/app/src/commands.ts @@ -15,6 +15,9 @@ import { makeRoomEditEvent, makeRoomJoinEvent, makeRoomLeaveEvent, + isPublishedProfile, + createProfile, + editProfile, RelayMode, INBOX_RELAYS, FOLLOWS, @@ -22,7 +25,7 @@ import { MUTES, PINS, } from "@welshman/util" -import type {RoomMeta} from "@welshman/util" +import type {RoomMeta, Profile} from "@welshman/util" import {Nip59, stamp} from "@welshman/signer" import {Router, addMaximalFallbacks} from "@welshman/router" import { @@ -86,6 +89,16 @@ export const addInboxRelay = async (url: string) => { return publishThunk({event, relays}) } +// NIP 01 + +export const setProfile = (profile: Profile) => { + const router = Router.get() + const relays = router.merge([router.Index(), router.FromUser()]).getUrls() + const event = isPublishedProfile(profile) ? editProfile(profile) : createProfile(profile) + + return publishThunk({event, relays}) +} + // NIP 02 export const unfollow = async (value: string) => { diff --git a/packages/store/src/synced.ts b/packages/store/src/synced.ts index e550623..77c6819 100644 --- a/packages/store/src/synced.ts +++ b/packages/store/src/synced.ts @@ -1,4 +1,4 @@ -import {writable} from "svelte/store" +import {writable, Writable} from "svelte/store" import {getJson, setJson} from "@welshman/lib" export interface StorageProvider { @@ -6,32 +6,39 @@ export interface StorageProvider { set: (key: string, value: any) => Promise } +export const localStorageProvider: StorageProvider = { + get: async (key: string) => getJson(key), + set: async (key: string, value: any) => setJson(key, value), +} + +export interface SyncConfig { + key: string + store: Writable + storage: StorageProvider +} + +export const sync = ({key, store, storage}: SyncConfig) => { + storage.get(key).then((value: T | undefined) => { + if (value !== undefined) { + store.set(value) + } + }) + + store.subscribe(async (value: T) => { + await storage.set(key, value) + }) +} + export interface SyncedConfig { key: string storage: StorageProvider defaultValue: T } -export const localStorageProvider: StorageProvider = { - get: async (key: string) => getJson(key), - set: async (key: string, value: any) => setJson(key, value), -} - -export const synced = (config: SyncedConfig) => { - const {key, storage, defaultValue} = config +export const synced = ({key, storage, defaultValue}: SyncedConfig) => { const store = writable(defaultValue) - // Async initialization - storage.get(key).then((value: any) => { - if (value !== undefined) { - store.set(value) - } - }) - - // Subscribe to changes - store.subscribe(async (value: T) => { - await storage.set(key, value) - }) + sync({key, store, storage}) return store }