feat: Add types and IDE comments to session

This commit is contained in:
Wanjohi
2025-11-03 23:04:29 +03:00
parent c99962ee1d
commit 6947230a1d
6 changed files with 584 additions and 185 deletions

View File

@@ -1,189 +1,38 @@
import { z } from "zod/v4";
import { Identifier } from "../id.js";
import { Examples } from "../examples.js";
import { fn } from "../utils/fn.js";
import { sessionTable } from "./session.sql.js";
import {
MachinePresetName,
ScreenResolutionPresetName,
VideoCodecName,
AudioCodecName,
RetryOptions,
SessionInfo,
type SessionInfo as SessionInfoType,
type Session as SessionInterface,
type Config as SessionConfig,
} from "./types.js";
// Basic types we need
export const MachinePresetName = z.enum([
"ns3-micro",
"ns3-mini",
"ns3-small",
"ns3-medium",
"ns3-large",
]);
// Re-export all types and schemas from types.ts
export {
MachinePresetName,
ScreenResolutionPresetName,
VideoCodecName,
AudioCodecName,
RetryOptions,
SessionInfo,
};
export const ScreenResolutionPresetName = z.enum([
"1280x720",
"1080x1920",
"1440x2560",
"2160x3840",
]);
export const VideoCodecName = z.enum(["h264", "h265", "vp8", "vp9", "av1"]);
export const AudioCodecName = z.enum(["opus", "aac", "mp3", "pcm"]);
export const RetryOptions = z.object({
maxAttempts: z.number().int().optional(),
factor: z.number().optional(),
minTimeoutInMs: z.number().int().optional(),
maxTimeoutInMs: z.number().int().optional(),
randomize: z.boolean().optional(),
outOfMemory: z
.object({
machine: MachinePresetName.optional(),
})
.optional(),
});
export type {
SessionInfoType,
SessionInterface as Session,
SessionConfig as SessionConfigType,
};
// Maintain backward compatibility with existing namespace structure
export namespace Session {
export const Info = z
.object({
id: Identifier.schema("session").meta({
description: "The unique identifier of the session",
example: Examples.Session.id,
}),
description: z.string().optional().meta({
description: "Description of what the session does",
example: Examples.Session.description,
}),
retry: RetryOptions.optional().meta({
description: "Retry configuration for failed session attempts",
example: Examples.Session.retry,
}),
queue: z
.object({
name: z.string().optional(),
concurrencyLimit: z.number().optional(),
})
.optional()
.meta({
description: "Queue configuration for concurrent session execution",
example: Examples.Session.queue,
}),
machine: MachinePresetName.optional().meta({
description: "Machine preset for the session",
example: Examples.Session.machine,
}),
maxDuration: z.number().optional().meta({
description: "Maximum duration in seconds the session can run",
example: Examples.Session.maxDuration,
}),
relayUrl: z.url().optional().meta({
description: "Nestri relay URL for streaming and signaling",
example: Examples.Session.relayUrl,
}),
resolution: ScreenResolutionPresetName.optional().meta({
description: "Display or stream resolution in 'WxH' format",
example: Examples.Session.resolution,
}),
framerate: z.number().optional().meta({
description: "Display or stream framerate",
example: Examples.Session.framerate,
}),
room: z.string().optional().meta({
description: "Room name or identifier for multiplayer sessions",
example: Examples.Session.room,
}),
gpuVendor: z.string().optional().meta({
description: "Preferred GPU vendor",
example: Examples.Session.gpuVendor,
}),
gpuName: z.string().optional().meta({
description: "Preferred GPU name",
example: Examples.Session.gpuName,
}),
gpuIndex: z.number().optional().meta({
description: "Specific GPU index to use",
example: Examples.Session.gpuIndex,
}),
gpuCardPath: z.string().optional().meta({
description: "Force specific GPU card by /dev/dri path",
example: Examples.Session.gpuCardPath,
}),
videoCodec: VideoCodecName.optional().meta({
description: "Preferred video codec for streaming",
example: Examples.Session.videoCodec,
}),
videoEncoder: z.string().optional().meta({
description: "Override video encoder implementation",
example: Examples.Session.videoEncoder,
}),
videoRateControl: z
.enum(["cbr", "vbr", "cq", "lossless"])
.optional()
.meta({
description: "Video rate control method",
example: Examples.Session.videoRateControl,
}),
videoCqp: z.number().min(1).max(51).optional().meta({
description: "Constant Quantization Parameter for quality control",
example: Examples.Session.videoCqp,
}),
videoBitrate: z.number().min(1).optional().meta({
description: "Target video bitrate in kbps",
example: Examples.Session.videoBitrate,
}),
videoBitrateMax: z.number().min(1).optional().meta({
description: "Maximum video bitrate in kbps",
example: Examples.Session.videoBitrateMax,
}),
videoEncoderType: z.enum(["hardware", "software"]).optional().meta({
description: "Encoder type: hardware or software",
example: Examples.Session.videoEncoderType,
}),
videoBitDepth: z
.union([z.literal(8), z.literal(10)])
.optional()
.meta({
description: "Video bit depth (8 or 10)",
example: Examples.Session.videoBitDepth,
}),
audioCaptureMethod: z
.enum(["pipewire", "pulse", "alsa"])
.optional()
.meta({
description: "Audio capture method",
example: Examples.Session.audioCaptureMethod,
}),
audioCodec: AudioCodecName.optional().meta({
description: "Preferred audio codec for streaming",
example: Examples.Session.audioCodec,
}),
audioEncoder: z.string().optional().meta({
description: "Override audio encoder binary",
example: Examples.Session.audioEncoder,
}),
audioRateControl: z.enum(["cbr", "vbr"]).optional().meta({
description: "Audio rate control method",
example: Examples.Session.audioRateControl,
}),
audioBitrate: z.number().min(1).optional().meta({
description: "Target audio bitrate in kbps",
example: Examples.Session.audioBitrate,
}),
audioBitrateMax: z.number().optional().meta({
description: "Maximum audio bitrate in kbps",
example: Examples.Session.audioBitrateMax,
}),
zeroCopy: z.boolean().optional().meta({
description: "Whether to use DMA-BUF for zero-copy video pipelines",
example: Examples.Session.zeroCopy,
}),
verbose: z.boolean().optional().meta({
description: "Enable verbose output for debugging",
example: Examples.Session.verbose,
}),
})
.meta({
ref: "Session",
description:
"Represents a session configuration with streaming and execution options",
example: Examples.Session,
});
export type Info = z.infer<typeof Info>;
// Session interface that matches the SDK session object
export const Info = SessionInfo;
export type Info = SessionInfoType;
export interface Session {
/** Optional description of the session */
description?: string;
@@ -195,9 +44,49 @@ export namespace Session {
startAndWait: (options?: any) => any;
}
// Session configuration type that includes the run function
export type Config = Omit<Info, "id"> & {
export type Config = Omit<SessionInfoType, "id"> & {
/** The function that executes when the session is started */
run: (ctx: any) => Promise<any>;
};
export const list = fn(z.void(), () => {
// Placeholder implementation
});
export function serialize(
input: typeof sessionTable.$inferSelect,
): z.infer<typeof SessionInfo> {
return {
id: input.id,
room: input.room || undefined,
retry: input.retry || undefined,
queue: input.queue || undefined,
machine: input.machine || undefined,
description: input.description || undefined,
maxDuration: input.maxDuration || undefined,
relayUrl: input.relayUrl || undefined,
resolution: input.resolution || undefined,
framerate: input.framerate || undefined,
gpuVendor: input.gpuVendor || undefined,
gpuName: input.gpuName || undefined,
gpuIndex: input.gpuIndex || undefined,
gpuCardPath: input.gpuCardPath || undefined,
videoCodec: input.videoCodec || undefined,
videoEncoder: input.videoEncoder || undefined,
videoRateControl: input.videoRateControl || undefined,
videoCqp: input.videoCqp || undefined,
videoBitrate: input.videoBitrate || undefined,
videoBitrateMax: input.videoBitrateMax || undefined,
videoEncoderType: input.videoEncoderType || undefined,
videoBitDepth: input.videoBitDepth || undefined,
audioCaptureMethod: input.audioCaptureMethod || undefined,
audioCodec: input.audioCodec || undefined,
audioEncoder: input.audioEncoder || undefined,
audioRateControl: input.audioRateControl || undefined,
audioBitrate: input.audioBitrate || undefined,
audioBitrateMax: input.audioBitrateMax || undefined,
zeroCopy: input.zeroCopy || undefined,
verbose: input.verbose || undefined,
};
}
}

View File

@@ -0,0 +1,66 @@
import { id, timestamps } from "../drizzle/types.js";
import {
pgTable,
varchar,
text,
integer,
boolean,
jsonb,
} from "drizzle-orm/pg-core";
import {
type Queue,
type RetryOptions,
type VideoCodecName,
type AudioCodecName,
type MachinePresetName,
type ScreenResolutionPresetName,
VideoEncoderType,
VideoRateControl,
AudioCaptureMethod,
AudioRateControl,
VideoBitDepth,
} from "./types.js";
export const sessionTable = pgTable("sessions", {
...id,
...timestamps,
description: text("description"),
retry: jsonb("retry").$type<RetryOptions>(),
queue: jsonb("queue").$type<Queue>(),
machine: varchar("machine", { length: 200 }).$type<MachinePresetName>(),
maxDuration: integer("max_duration"),
relayUrl: varchar("relay_url", { length: 500 }),
resolution: varchar("resolution", {
length: 20,
}).$type<ScreenResolutionPresetName>(),
framerate: integer("framerate"),
room: varchar("room", { length: 255 }),
gpuVendor: varchar("gpu_vendor", { length: 100 }),
gpuName: varchar("gpu_name", { length: 255 }),
gpuIndex: integer("gpu_index"),
gpuCardPath: varchar("gpu_card_path", { length: 500 }),
videoCodec: varchar("video_codec", { length: 20 }).$type<VideoCodecName>(),
videoEncoder: varchar("video_encoder", { length: 100 }),
videoRateControl: varchar("video_rate_control", {
length: 20,
}).$type<VideoRateControl>(),
videoCqp: integer("video_cqp"),
videoBitrate: integer("video_bitrate"),
videoBitrateMax: integer("video_bitrate_max"),
videoEncoderType: varchar("video_encoder_type", {
length: 20,
}).$type<VideoEncoderType>(),
videoBitDepth: integer("video_bit_depth").$type<VideoBitDepth>(),
audioCaptureMethod: varchar("audio_capture_method", {
length: 20,
}).$type<AudioCaptureMethod>(),
audioCodec: varchar("audio_codec", { length: 20 }).$type<AudioCodecName>(),
audioEncoder: varchar("audio_encoder", { length: 100 }),
audioRateControl: varchar("audio_rate_control", {
length: 20,
}).$type<AudioRateControl>(),
audioBitrate: integer("audio_bitrate"),
audioBitrateMax: integer("audio_bitrate_max"),
zeroCopy: boolean("zero_copy"),
verbose: boolean("verbose"),
});

View File

@@ -0,0 +1,286 @@
import { z } from "zod/v4";
import { Identifier } from "../id.js";
import { Examples } from "../examples.js";
/**
* Available machine preset sizes for session execution
*/
export const MachinePresetName = z.enum([
"ns3-micro",
"ns3-mini",
"ns3-small",
"ns3-medium",
"ns3-large",
]);
export type MachinePresetName = z.infer<typeof MachinePresetName>;
/**
* Available screen resolution presets in 'WxH' format
*/
export const ScreenResolutionPresetName = z.enum([
"1280x720",
"1080x1920",
"1440x2560",
"2160x3840",
]);
export type ScreenResolutionPresetName = z.infer<
typeof ScreenResolutionPresetName
>;
/**
* Supported video codecs for streaming
*/
export const VideoCodecName = z.enum(["h264", "h265", "vp8", "vp9", "av1"]);
export type VideoCodecName = z.infer<typeof VideoCodecName>;
/**
* Supported audio codecs for streaming
*/
export const AudioCodecName = z.enum(["opus", "aac", "mp3", "pcm"]);
export type AudioCodecName = z.infer<typeof AudioCodecName>;
/**
* Retry configuration for failed operations
*/
export const RetryOptions = z.object({
/** Maximum number of retry attempts */
maxAttempts: z.number().int().optional(),
/** Exponential backoff factor for retry delays */
factor: z.number().optional(),
/** Minimum timeout between retries in milliseconds */
minTimeoutInMs: z.number().int().optional(),
/** Maximum timeout between retries in milliseconds */
maxTimeoutInMs: z.number().int().optional(),
/** Whether to randomize retry delays to avoid thundering herd */
randomize: z.boolean().optional(),
/** Configuration for handling out of memory errors */
outOfMemory: z
.object({
/** Machine preset to upgrade to on out of memory errors */
machine: MachinePresetName.optional(),
})
.optional(),
});
export type RetryOptions = z.infer<typeof RetryOptions>;
export const Queue = z.object({
/** Queue name for organizing sessions */
name: z.string().optional(),
/** Maximum number of concurrent sessions in queue */
concurrencyLimit: z.number().optional(),
});
export type Queue = z.infer<typeof Queue>;
export const VideoRateControl = z.enum(["cbr", "vbr", "cq", "lossless"]);
export type VideoRateControl = z.infer<typeof VideoRateControl>;
export const VideoEncoderType = z.enum(["hardware", "software"]);
export type VideoEncoderType = z.infer<typeof VideoEncoderType>;
export const AudioCaptureMethod = z.enum(["pipewire", "pulse", "alsa"]);
export type AudioCaptureMethod = z.infer<typeof AudioCaptureMethod>;
export const AudioRateControl = z.enum(["cbr", "vbr"]);
export type AudioRateControl = z.infer<typeof AudioRateControl>;
export const VideoBitDepth = z.union([z.literal(8), z.literal(10)]);
export type VideoBitDepth = z.infer<typeof VideoBitDepth>;
/**
* Represents a session configuration with streaming and execution options
*/
export const SessionInfo = z
.object({
/** The unique identifier of the session */
id: Identifier.schema("session").meta({
description: "The unique identifier of the session",
example: Examples.Session.id,
}),
/** Description of what the session does */
description: z.string().optional().meta({
description: "Description of what the session does",
example: Examples.Session.description,
}),
/** Retry configuration for failed session attempts */
retry: RetryOptions.optional().meta({
description: "Retry configuration for failed session attempts",
example: Examples.Session.retry,
}),
/** Queue configuration for concurrent session execution */
queue: Queue.optional().meta({
description: "Queue configuration for concurrent session execution",
example: Examples.Session.queue,
}),
/** Machine preset for the session */
machine: MachinePresetName.optional().meta({
description: "Machine preset for the session",
example: Examples.Session.machine,
}),
/** Maximum duration in seconds the session can run */
maxDuration: z.number().optional().meta({
description: "Maximum duration in seconds the session can run",
example: Examples.Session.maxDuration,
}),
/** Nestri relay URL for streaming and signaling */
relayUrl: z.url().optional().meta({
description: "Nestri relay URL for streaming and signaling",
example: Examples.Session.relayUrl,
}),
/** Display or stream resolution in 'WxH' format */
resolution: ScreenResolutionPresetName.optional().meta({
description: "Display or stream resolution in 'WxH' format",
example: Examples.Session.resolution,
}),
/** Display or stream framerate */
framerate: z.number().optional().meta({
description: "Display or stream framerate",
example: Examples.Session.framerate,
}),
/** Room name or identifier for multiplayer sessions */
room: z.string().optional().meta({
description: "Room name or identifier for multiplayer sessions",
example: Examples.Session.room,
}),
/** Preferred GPU vendor */
gpuVendor: z.string().optional().meta({
description: "Preferred GPU vendor",
example: Examples.Session.gpuVendor,
}),
/** Preferred GPU name */
gpuName: z.string().optional().meta({
description: "Preferred GPU name",
example: Examples.Session.gpuName,
}),
/** Specific GPU index to use */
gpuIndex: z.number().optional().meta({
description: "Specific GPU index to use",
example: Examples.Session.gpuIndex,
}),
/** Force specific GPU card by /dev/dri path */
gpuCardPath: z.string().optional().meta({
description: "Force specific GPU card by /dev/dri path",
example: Examples.Session.gpuCardPath,
}),
/** Preferred video codec for streaming */
videoCodec: VideoCodecName.optional().meta({
description: "Preferred video codec for streaming",
example: Examples.Session.videoCodec,
}),
/** Override video encoder implementation */
videoEncoder: z.string().optional().meta({
description: "Override video encoder implementation",
example: Examples.Session.videoEncoder,
}),
/** Video rate control method */
videoRateControl: VideoRateControl.optional().meta({
description: "Video rate control method",
example: Examples.Session.videoRateControl,
}),
/** Constant Quantization Parameter for quality control */
videoCqp: z.number().min(1).max(51).optional().meta({
description: "Constant Quantization Parameter for quality control",
example: Examples.Session.videoCqp,
}),
/** Target video bitrate in kbps */
videoBitrate: z.number().min(1).optional().meta({
description: "Target video bitrate in kbps",
example: Examples.Session.videoBitrate,
}),
/** Maximum video bitrate in kbps */
videoBitrateMax: z.number().min(1).optional().meta({
description: "Maximum video bitrate in kbps",
example: Examples.Session.videoBitrateMax,
}),
/** Encoder type: hardware or software */
videoEncoderType: VideoEncoderType.optional().meta({
description: "Encoder type: hardware or software",
example: Examples.Session.videoEncoderType,
}),
/** Video bit depth (8 or 10) */
videoBitDepth: VideoBitDepth.optional().meta({
description: "Video bit depth (8 or 10)",
example: Examples.Session.videoBitDepth,
}),
/** Audio capture method */
audioCaptureMethod: AudioCaptureMethod.optional().meta({
description: "Audio capture method",
example: Examples.Session.audioCaptureMethod,
}),
/** Preferred audio codec for streaming */
audioCodec: AudioCodecName.optional().meta({
description: "Preferred audio codec for streaming",
example: Examples.Session.audioCodec,
}),
/** Override audio encoder binary */
audioEncoder: z.string().optional().meta({
description: "Override audio encoder binary",
example: Examples.Session.audioEncoder,
}),
/** Audio rate control method */
audioRateControl: AudioRateControl.optional().meta({
description: "Audio rate control method",
example: Examples.Session.audioRateControl,
}),
/** Target audio bitrate in kbps */
audioBitrate: z.number().min(1).optional().meta({
description: "Target audio bitrate in kbps",
example: Examples.Session.audioBitrate,
}),
/** Maximum audio bitrate in kbps */
audioBitrateMax: z.number().optional().meta({
description: "Maximum audio bitrate in kbps",
example: Examples.Session.audioBitrateMax,
}),
/** Whether to use DMA-BUF for zero-copy video pipelines */
zeroCopy: z.boolean().optional().meta({
description: "Whether to use DMA-BUF for zero-copy video pipelines",
example: Examples.Session.zeroCopy,
}),
/** Enable verbose output for debugging */
verbose: z.boolean().optional().meta({
description: "Enable verbose output for debugging",
example: Examples.Session.verbose,
}),
})
.meta({
ref: "Session",
description:
"Represents a session configuration with streaming and execution options",
example: Examples.Session,
});
/** Inferred type from SessionInfo schema */
export type SessionInfo = z.infer<typeof SessionInfo>;
/**
* Session interface that matches the SDK session object
*/
export interface Session {
/** Optional description of the session */
description?: string;
/** Start a session without waiting for the result */
start: (options?: any, requestOptions?: any) => Promise<any>;
/** Start a session and wait for the result */
startAndWait: (options?: any) => any;
}
/**
* Session configuration type that includes the run function
*/
export type Config = Omit<SessionInfo, "id"> & {
/** The function that executes when the session is started */
run: (ctx: any) => Promise<any>;
};