mirror of
https://github.com/block-core/blockcore-notes.git
synced 2024-09-29 22:40:44 +00:00
Add failure notification from relays
This commit is contained in:
parent
981f22988a
commit
14ae68bb4d
@ -114,6 +114,13 @@ Thoughts and ideas:
|
||||
- Validate the content of certain limit and don't render at all if content is too long, or at least cut the content and only render X length. Then allow users to manually retrieve
|
||||
that exact event upon request.
|
||||
|
||||
Data Flow:
|
||||
|
||||
- Event received from relays... pushed into an event processor, which pushes events into individual services based upon the type.
|
||||
- Individual services grabs existing event from StateService, if available, updates (if replaceable event or profile) or simply ignores. Maybe log "observed on relay".
|
||||
- If not available, push into the StateService and schedule a database put.
|
||||
- StateService should always keep some items in-memory: Profiles, Circles and more.
|
||||
|
||||
## Security
|
||||
|
||||
There are many ways a web app can be exploited when it allow user contributed content. Any and all measurements to avoid exploits should be done, like sanitizing the input.
|
||||
|
@ -435,3 +435,12 @@ export interface LNURLSuccessAction {
|
||||
description?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
|
||||
// export interface ProfileView {
|
||||
|
||||
// }
|
||||
|
||||
// export interface EventView {
|
||||
|
||||
// }
|
||||
|
@ -18,6 +18,8 @@ import { ArticleService } from './article';
|
||||
import { LoggerService } from './logger';
|
||||
import { BadgeService } from './badge';
|
||||
import { ZapUiService } from './zap-ui';
|
||||
import { StateService } from './state';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -57,7 +59,9 @@ export class RelayService {
|
||||
private options: OptionsService,
|
||||
private eventService: EventService,
|
||||
private appState: ApplicationState,
|
||||
private zapUi: ZapUiService
|
||||
private zapUi: ZapUiService,
|
||||
private stateService: StateService,
|
||||
private snackBar: MatSnackBar
|
||||
) {
|
||||
// Whenever the visibility becomes visible, run connect to ensure we're connected to the relays.
|
||||
this.appState.visibility$.subscribe((visible) => {
|
||||
@ -417,6 +421,8 @@ export class RelayService {
|
||||
|
||||
this.logger.debug('SAVE EVENT?:', event);
|
||||
|
||||
this.stateService.addEvent(event);
|
||||
|
||||
if (event.kind == Kind.Zap) {
|
||||
this.zapUi.addZap(event);
|
||||
}
|
||||
@ -656,6 +662,16 @@ export class RelayService {
|
||||
const response = ev.data as RelayResponse;
|
||||
|
||||
switch (response.type) {
|
||||
case 'failure':
|
||||
this.logger.debug(`Relay ${url} failure: ${response.data}.`);
|
||||
|
||||
this.snackBar.open(`Failure: ${response.data}. (${url})`, 'Hide', {
|
||||
duration: 3500,
|
||||
horizontalPosition: 'center',
|
||||
verticalPosition: 'bottom',
|
||||
});
|
||||
|
||||
break;
|
||||
case 'timeout':
|
||||
this.logger.debug(`Relay ${url} timeout: ${response.data}.`);
|
||||
this.setRelayTimeout(url, response.data);
|
||||
|
144
src/app/services/state.ts
Normal file
144
src/app/services/state.ts
Normal file
@ -0,0 +1,144 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Kind } from 'nostr-tools';
|
||||
import { Circle, NostrEvent, NostrProfileDocument } from './interfaces';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class StateService {
|
||||
constructor(private state: State) {}
|
||||
|
||||
addEvent(event: NostrEvent) {
|
||||
// TODO: Temporarily removed to avoid building massive in-memory state.
|
||||
// switch (event.kind) {
|
||||
// case Kind.Metadata:
|
||||
// this.addIfNewer(event, this.state.events.shortTextNote);
|
||||
// break;
|
||||
// case Kind.Text:
|
||||
// this.addIfMissing(event, this.state.events.shortTextNote);
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
addIfMissing(event: NostrEvent, map: Map<string, NostrEvent>) {
|
||||
if (map.has(event.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
map.set(event.id, event);
|
||||
}
|
||||
|
||||
addIfNewer(event: NostrEvent, map: Map<string, NostrEvent>) {
|
||||
if (!map.has(event.id)) {
|
||||
map.set(event.id, event);
|
||||
} else {
|
||||
const existing = map.get(event.id);
|
||||
|
||||
if (existing!.created_at > event.created_at) {
|
||||
return;
|
||||
}
|
||||
|
||||
map.set(event.id, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class State {
|
||||
profiles: NostrProfileDocument[] = [];
|
||||
|
||||
circles: Circle[] = [];
|
||||
|
||||
events: EventsState = {
|
||||
metadata: new Map(),
|
||||
shortTextNote: new Map(),
|
||||
recommendRelay: new Map(),
|
||||
contacts: new Map(),
|
||||
encryptedDirectMessages: new Map(),
|
||||
eventDeletion: new Map(),
|
||||
reposts: new Map(),
|
||||
reaction: new Map(),
|
||||
badgeAward: new Map(),
|
||||
channelCreation: new Map(),
|
||||
channelMetadata: new Map(),
|
||||
channelMessage: new Map(),
|
||||
channelHideMessage: new Map(),
|
||||
channelMuteUser: new Map(),
|
||||
reporting: new Map(),
|
||||
zapRequest: new Map(),
|
||||
zap: new Map(),
|
||||
muteList: new Map(),
|
||||
relayListMetadata: new Map(),
|
||||
clientAuthentication: new Map(),
|
||||
nostrConnect: new Map(),
|
||||
categorizedPeopleList: new Map(),
|
||||
categorizedBookmarkList: new Map(),
|
||||
profileBadges: new Map(),
|
||||
badgeDefinition: new Map(),
|
||||
longFormContent: new Map(),
|
||||
applicationSpecificData: new Map(),
|
||||
regularEvents: new Map(),
|
||||
replaceableEvents: new Map(),
|
||||
ephemeralEvents: new Map(),
|
||||
parameterizedReplaceableEvents: new Map(),
|
||||
};
|
||||
|
||||
relays: RelaysState = {
|
||||
notice: new Map(),
|
||||
auth: new Map(),
|
||||
};
|
||||
}
|
||||
|
||||
export interface EventsState {
|
||||
metadata: Map<string, NostrEvent>; // 0
|
||||
shortTextNote: Map<string, NostrEvent>; // 1
|
||||
recommendRelay: Map<string, NostrEvent>; // 2
|
||||
contacts: Map<string, NostrEvent>; // 3
|
||||
encryptedDirectMessages: Map<string, NostrEvent>; // 4
|
||||
eventDeletion: Map<string, NostrEvent>; // 5
|
||||
reposts: Map<string, NostrEvent>; // 6
|
||||
reaction: Map<string, NostrEvent>; // 7
|
||||
badgeAward: Map<string, NostrEvent>; // 8
|
||||
channelCreation: Map<string, NostrEvent>; // 40
|
||||
channelMetadata: Map<string, NostrEvent>; // 41
|
||||
channelMessage: Map<string, NostrEvent>; // 42
|
||||
channelHideMessage: Map<string, NostrEvent>; // 43
|
||||
channelMuteUser: Map<string, NostrEvent>; // 44
|
||||
reporting: Map<string, NostrEvent>; // 1984
|
||||
zapRequest: Map<string, NostrEvent>; // 9734
|
||||
zap: Map<string, NostrEvent>; // 9735
|
||||
muteList: Map<string, NostrEvent>; // 10000
|
||||
relayListMetadata: Map<string, NostrEvent>; // 10002
|
||||
clientAuthentication: Map<string, NostrEvent>; // 22242
|
||||
nostrConnect: Map<string, NostrEvent>; // 24133
|
||||
categorizedPeopleList: Map<string, NostrEvent>; // 30000
|
||||
categorizedBookmarkList: Map<string, NostrEvent>; // 30001
|
||||
profileBadges: Map<string, NostrEvent>; // 30008
|
||||
badgeDefinition: Map<string, NostrEvent>; // 30009
|
||||
longFormContent: Map<string, NostrEvent>; // 30023
|
||||
applicationSpecificData: Map<string, NostrEvent>; // 30078
|
||||
regularEvents: Map<string, NostrEvent>; // 1000-9999
|
||||
replaceableEvents: Map<string, NostrEvent>; // 10000-19999
|
||||
ephemeralEvents: Map<string, NostrEvent>; // 20000-29999
|
||||
parameterizedReplaceableEvents: Map<string, NostrEvent>; // 30000-39999
|
||||
}
|
||||
|
||||
export interface RelaysState {
|
||||
notice: Map<string, NoticeItem>;
|
||||
auth: Map<string, AuthItem>;
|
||||
}
|
||||
|
||||
export interface NoticeItem {
|
||||
relay: string;
|
||||
notice: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
// https://github.com/nostr-protocol/nips/blob/master/42.md
|
||||
export interface AuthItem {
|
||||
relay: string;
|
||||
notice: string;
|
||||
timestamp: number;
|
||||
}
|
@ -40,6 +40,7 @@ export class RelayWorker {
|
||||
// });
|
||||
pub.on('failed', (reason: any) => {
|
||||
console.log(`failed to publish to ${this.relay.url}: ${reason}`);
|
||||
postMessage({ type: 'failure', data: reason, url: this.relay.url } as RelayResponse);
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user