feat: add procedure to relay
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { ServerContext, UnauthorizedError } from "@spec/relay";
|
||||
import { ServerContext } from "@spec/relay";
|
||||
|
||||
import type { Sockets } from "~libraries/socket/sockets.ts";
|
||||
|
||||
import { Session } from "../auth/auth.ts";
|
||||
import { req } from "./request.ts";
|
||||
@@ -11,15 +13,25 @@ declare module "@spec/relay" {
|
||||
request: Request;
|
||||
|
||||
/**
|
||||
* Get request session instance.
|
||||
* Is the request authenticated.
|
||||
*/
|
||||
session: Session;
|
||||
isAuthenticated: boolean;
|
||||
|
||||
/**
|
||||
* Get account id from session, throws an error if the request
|
||||
* does not have a valid session.
|
||||
*/
|
||||
accountId: string;
|
||||
|
||||
/**
|
||||
* Get request session instance.
|
||||
*/
|
||||
session: Session;
|
||||
|
||||
/**
|
||||
* Sockets instance attached to the server.
|
||||
*/
|
||||
sockets: Sockets;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,15 +39,20 @@ export function getRequestContext(request: Request): ServerContext {
|
||||
return {
|
||||
request,
|
||||
|
||||
get session(): Session {
|
||||
if (req.session === undefined) {
|
||||
throw new UnauthorizedError();
|
||||
}
|
||||
return req.session;
|
||||
get isAuthenticated(): boolean {
|
||||
return req.isAuthenticated;
|
||||
},
|
||||
|
||||
get accountId() {
|
||||
return this.session.accountId;
|
||||
},
|
||||
|
||||
get session(): Session {
|
||||
return req.session;
|
||||
},
|
||||
|
||||
get sockets(): Sockets {
|
||||
return req.sockets;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { InternalServerError, UnauthorizedError } from "@spec/relay";
|
||||
|
||||
import { Session } from "../auth/auth.ts";
|
||||
import { asyncLocalStorage } from "./storage.ts";
|
||||
|
||||
@@ -5,21 +7,16 @@ export const req = {
|
||||
get store() {
|
||||
const store = asyncLocalStorage.getStore();
|
||||
if (store === undefined) {
|
||||
throw new Error("Request > AsyncLocalStorage not defined.");
|
||||
throw new InternalServerError("AsyncLocalStorage not defined.");
|
||||
}
|
||||
return store;
|
||||
},
|
||||
|
||||
get socket() {
|
||||
return this.store.socket;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get store that is potentially undefined.
|
||||
* Typically used when utility functions might run in and out of request scope.
|
||||
*/
|
||||
get unsafeStore() {
|
||||
return asyncLocalStorage.getStore();
|
||||
get sockets() {
|
||||
if (this.store.sockets === undefined) {
|
||||
throw new InternalServerError("Sockets not defined.");
|
||||
}
|
||||
return this.store.sockets;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -32,7 +29,10 @@ export const req = {
|
||||
/**
|
||||
* Get current session.
|
||||
*/
|
||||
get session(): Session | undefined {
|
||||
get session(): Session {
|
||||
if (this.store.session === undefined) {
|
||||
throw new UnauthorizedError();
|
||||
}
|
||||
return this.store.session;
|
||||
},
|
||||
|
||||
@@ -44,14 +44,18 @@ export const req = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends a JSON-RPC 2.0 notification to the request if sent through a
|
||||
* WebSocket connection.
|
||||
*
|
||||
* @param method - Method to send notification to.
|
||||
* @param params - Params to pass to the method.
|
||||
* Get current session.
|
||||
*/
|
||||
notify(method: string, params: any): void {
|
||||
this.socket?.send(JSON.stringify({ jsonrpc: "2.0", method, params }));
|
||||
getSession(): Session | undefined {
|
||||
return this.store.session;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get store that is potentially undefined.
|
||||
* Typically used when utility functions might run in and out of request scope.
|
||||
*/
|
||||
getStore() {
|
||||
return asyncLocalStorage.getStore();
|
||||
},
|
||||
} as const;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
|
||||
import type { Session } from "~libraries/auth/mod.ts";
|
||||
import type { Sockets } from "~libraries/socket/sockets.ts";
|
||||
|
||||
export const asyncLocalStorage = new AsyncLocalStorage<{
|
||||
session?: Session;
|
||||
@@ -9,7 +10,7 @@ export const asyncLocalStorage = new AsyncLocalStorage<{
|
||||
start: number;
|
||||
end?: number;
|
||||
};
|
||||
socket?: WebSocket;
|
||||
sockets?: Sockets;
|
||||
response: {
|
||||
headers: Headers;
|
||||
};
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export { Sockets } from "./sockets.ts";
|
||||
@@ -2,6 +2,7 @@ import { toJsonRpc } from "@valkyr/json-rpc";
|
||||
|
||||
import { Session } from "~libraries/auth/mod.ts";
|
||||
import { logger } from "~libraries/logger/mod.ts";
|
||||
import { asyncLocalStorage } from "~libraries/server/storage.ts";
|
||||
|
||||
import { sockets } from "./sockets.ts";
|
||||
|
||||
@@ -23,35 +24,35 @@ export function upgrade(request: Request, session?: Session) {
|
||||
return;
|
||||
}
|
||||
|
||||
const body = toJsonRpc(event.data);
|
||||
const message = toJsonRpc(event.data);
|
||||
|
||||
logger.prefix("Socket").info(body);
|
||||
logger.prefix("Socket").info(message);
|
||||
|
||||
asyncLocalStorage.run(
|
||||
{
|
||||
session,
|
||||
info: {
|
||||
method: body.method!,
|
||||
method: message.method!,
|
||||
start: Date.now(),
|
||||
},
|
||||
socket,
|
||||
sockets,
|
||||
response: {
|
||||
headers: new Headers(),
|
||||
},
|
||||
},
|
||||
async () => {
|
||||
api
|
||||
.handleCommand(body)
|
||||
.then((response) => {
|
||||
if (response !== undefined) {
|
||||
logger.info({ response });
|
||||
socket.send(JSON.stringify(response));
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.info({ error });
|
||||
socket.send(JSON.stringify(error));
|
||||
});
|
||||
// api
|
||||
// .send(body)
|
||||
// .then((response) => {
|
||||
// if (response !== undefined) {
|
||||
// logger.info({ response });
|
||||
// socket.send(JSON.stringify(response));
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// logger.info({ error });
|
||||
// socket.send(JSON.stringify(error));
|
||||
// });
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"@valkyr/auth": "npm:@jsr/valkyr__auth@2",
|
||||
"@valkyr/event-store": "npm:@jsr/valkyr__event-store@2.0.0-beta.6",
|
||||
"@valkyr/inverse": "npm:@jsr/valkyr__inverse@1",
|
||||
"@valkyr/json-rpc": "npm:@jsr/valkyr__json-rpc@1",
|
||||
"cookie": "1",
|
||||
"mongodb": "6",
|
||||
"zod": "4"
|
||||
|
||||
22
api/procedures/event.ts
Normal file
22
api/procedures/event.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { procedure } from "@spec/relay/mod.ts";
|
||||
import z from "zod";
|
||||
|
||||
const EventSchema = z.object({
|
||||
id: z.uuid(),
|
||||
stream: z.uuid(),
|
||||
type: z.string(),
|
||||
data: z.any(),
|
||||
meta: z.any(),
|
||||
recorded: z.string(),
|
||||
created: z.string(),
|
||||
});
|
||||
|
||||
export default procedure
|
||||
.method("event")
|
||||
.access("public")
|
||||
.params(EventSchema)
|
||||
.response(z.uuid())
|
||||
.handle(async (event) => {
|
||||
console.log(event);
|
||||
return crypto.randomUUID();
|
||||
});
|
||||
Reference in New Issue
Block a user