Skip to content

Commit

Permalink
feat: support type extension on database events
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurgeron committed Nov 12, 2024
1 parent 684c18a commit 0252f5f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 57 deletions.
109 changes: 58 additions & 51 deletions packages/app/src/systems/CRX/background/services/DatabaseEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {
Connection,
EventMessage,
EventMessageEvents,
NetworkData,
} from '@fuel-wallet/types';
import { CONTENT_SCRIPT_NAME, MessageTypes } from '@fuel-wallet/types';
import { ConnectionService } from '~/systems/DApp/services';
Expand Down Expand Up @@ -40,70 +41,76 @@ export class DatabaseEvents {
}

setupApplicationWatcher() {
this.databaseObservable.on('networks:update', async (updateEvent) => {
// Broadcast only if the network is selected
if (!updateEvent.obj.isSelected) return;
this.databaseObservable.on<'networks:update', NetworkData>(
'networks:update',
async (updateEvent) => {
// Broadcast only if the network is selected
if (!updateEvent.obj.isSelected) return;

const connections = await ConnectionService.getConnections();
const origins = connections.map((connection) => connection.origin);
const connections = await ConnectionService.getConnections();
const origins = connections.map((connection) => connection.origin);

this.communicationProtocol.broadcast(
origins,
this.createEvents([
{
event: 'currentNetwork',
params: [
{
url: updateEvent.obj.url,
},
],
},
])
);
});
this.communicationProtocol.broadcast(
origins,
this.createEvents([
{
event: 'currentNetwork',
params: [
{
url: updateEvent.obj.url,
},
],
},
])
);
}
);

this.databaseObservable.on('accounts:update', async (updateEvent) => {
// Broadcast only if it's the current account
if (!updateEvent.obj.isCurrent) return;
this.databaseObservable.on<'accounts:update', Account>(
'accounts:update',
async (updateEvent) => {
// Broadcast only if it's the current account
if (!updateEvent.obj.isCurrent) return;

const currentAccount = updateEvent.obj as Account;
const connections = await ConnectionService.getConnections();
const getOriginsForConnections = (connections: Array<Connection>) =>
connections.map((c) => c.origin);
const addressConnectedOrigins = getOriginsForConnections(
connections.filter((c) => c.accounts.includes(currentAccount.address))
);
const addressNotConnectedOrigins = getOriginsForConnections(
connections.filter((c) => !addressConnectedOrigins.includes(c.origin))
);
const hasUnconnectedOrigins =
addressNotConnectedOrigins.length !== addressConnectedOrigins.length;
const currentAccount = updateEvent.obj;
const connections = await ConnectionService.getConnections();
const getOriginsForConnections = (connections: Array<Connection>) =>
connections.map((c) => c.origin);
const addressConnectedOrigins = getOriginsForConnections(
connections.filter((c) => c.accounts.includes(currentAccount.address))
);
const addressNotConnectedOrigins = getOriginsForConnections(
connections.filter((c) => !addressConnectedOrigins.includes(c.origin))
);
const hasUnconnectedOrigins =
addressNotConnectedOrigins.length !== addressConnectedOrigins.length;

// Notify all connections that the current account is connected
// by sending the current account address
this.communicationProtocol.broadcast(
addressConnectedOrigins,
this.createEvents([
{
event: 'currentAccount',
params: [updateEvent.obj.address],
},
])
);
// Nofity all connections that the current account is not connected
// by sending a null value
if (hasUnconnectedOrigins) {
// Notify all connections that the current account is connected
// by sending the current account address
this.communicationProtocol.broadcast(
addressNotConnectedOrigins,
addressConnectedOrigins,
this.createEvents([
{
event: 'currentAccount',
params: [null],
params: [updateEvent.obj.address],
},
])
);
// Nofity all connections that the current account is not connected
// by sending a null value
if (hasUnconnectedOrigins) {
this.communicationProtocol.broadcast(
addressNotConnectedOrigins,
this.createEvents([
{
event: 'currentAccount',
params: [null],
},
])
);
}
}
});
);

this.databaseObservable.on('connections:delete', async (updateEvent) => {
const deletedConnection = updateEvent.oldObj as Connection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ type EventName<Tables extends readonly string[]> =
`${Tables[number]}:${Action}`;

// biome-ignore lint/suspicious/noExplicitAny: <explanation>
type Listener<T extends EventName<any>> = T extends `${string}:create`
? (event: ICreateChange) => void
type Listener<T extends EventName<any>, D> = T extends `${string}:create`
? (event: ICreateChange<T, D>) => void
: T extends `${string}:update`
? (event: IUpdateChange) => void
? (event: IUpdateChange<T, D>) => void
: T extends `${string}:delete`
? (event: IDeleteChange) => void
? (event: IDeleteChange<T, D>) => void
: never;

export class DatabaseObservable<
Expand Down Expand Up @@ -54,7 +54,10 @@ export class DatabaseObservable<
}
}

on<T extends EventName<Tables>>(eventName: T, listener: Listener<T>): this {
on<T extends EventName<Tables>, D>(
eventName: T,
listener: Listener<T, D>
): this {
return super.on(eventName, listener);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/fuel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface ICreateChange<T = unknown, Y = unknown> {
source?: string;
}

export interface IUpdateChange<T = unknown, Y = unknown, _Z = unknown> {
export interface IUpdateChange<T = unknown, Y = unknown> {
type: DatabaseChangeType.Update;
table: string;
key: T;
Expand Down

0 comments on commit 0252f5f

Please sign in to comment.