refactor(core): simplify session pagination
This commit is contained in:
@@ -15,7 +15,7 @@ import { Database } from "./database/database"
|
||||
import { SessionProjector } from "./session/projector"
|
||||
import { SessionMessageTable, SessionTable } from "./session/sql"
|
||||
import { SessionSchema } from "./session/schema"
|
||||
import { AbsolutePath, RelativePath } from "./schema"
|
||||
import { AbsolutePath, PositiveInt, RelativePath } from "./schema"
|
||||
import { AgentV2 } from "./agent"
|
||||
|
||||
// get project -> project.locations
|
||||
@@ -27,35 +27,35 @@ import { AgentV2 } from "./agent"
|
||||
// - by subpath
|
||||
// - by workspace (home is special)
|
||||
|
||||
export const ListCursor = Schema.Struct({
|
||||
export const ListAnchor = Schema.Struct({
|
||||
id: SessionSchema.ID,
|
||||
time: Schema.Finite,
|
||||
direction: Schema.Literals(["previous", "next"]),
|
||||
})
|
||||
export type ListCursor = typeof ListCursor.Type
|
||||
export type ListAnchor = typeof ListAnchor.Type
|
||||
|
||||
const ListInputBase = {
|
||||
workspaceID: WorkspaceV2.ID.pipe(Schema.optional),
|
||||
search: Schema.String.pipe(Schema.optional),
|
||||
limit: Schema.Int.pipe(Schema.optional),
|
||||
limit: PositiveInt.pipe(Schema.optional),
|
||||
order: Schema.Literals(["asc", "desc"]).pipe(Schema.optional),
|
||||
cursor: ListCursor.pipe(Schema.optional),
|
||||
anchor: ListAnchor.pipe(Schema.optional),
|
||||
}
|
||||
|
||||
export const ListInput = Schema.Union([
|
||||
Schema.Struct({
|
||||
...ListInputBase,
|
||||
}),
|
||||
Schema.Struct({
|
||||
...ListInputBase,
|
||||
directory: AbsolutePath,
|
||||
}),
|
||||
Schema.Struct({
|
||||
...ListInputBase,
|
||||
project: ProjectV2.ID,
|
||||
subpath: RelativePath.pipe(Schema.optional),
|
||||
}),
|
||||
])
|
||||
const ListDirectoryInput = Schema.Struct({
|
||||
...ListInputBase,
|
||||
directory: AbsolutePath,
|
||||
})
|
||||
|
||||
const ListProjectInput = Schema.Struct({
|
||||
...ListInputBase,
|
||||
project: ProjectV2.ID,
|
||||
subpath: RelativePath.pipe(Schema.optional),
|
||||
})
|
||||
|
||||
const ListAllInput = Schema.Struct(ListInputBase)
|
||||
|
||||
export const ListInput = Schema.Union([ListDirectoryInput, ListProjectInput, ListAllInput])
|
||||
export type ListInput = typeof ListInput.Type
|
||||
|
||||
type CreateInput = {
|
||||
@@ -205,25 +205,25 @@ export const layer = Layer.effect(
|
||||
return fromRow(row)
|
||||
}),
|
||||
list: Effect.fn("V2Session.list")(function* (input = {}) {
|
||||
const direction = input.cursor?.direction ?? "next"
|
||||
const direction = input.anchor?.direction ?? "next"
|
||||
const requestedOrder = input.order ?? "desc"
|
||||
const order = direction === "previous" ? (requestedOrder === "asc" ? "desc" : "asc") : requestedOrder
|
||||
const sortColumn = SessionTable.time_updated
|
||||
const sortColumn = SessionTable.time_created
|
||||
const conditions: SQL[] = []
|
||||
if ("directory" in input) conditions.push(eq(SessionTable.directory, input.directory))
|
||||
if (input.workspaceID) conditions.push(eq(SessionTable.workspace_id, input.workspaceID))
|
||||
if ("project" in input) conditions.push(eq(SessionTable.project_id, input.project))
|
||||
if (input.search) conditions.push(like(SessionTable.title, `%${input.search}%`))
|
||||
if (input.cursor) {
|
||||
if (input.anchor) {
|
||||
conditions.push(
|
||||
order === "asc"
|
||||
? or(
|
||||
gt(sortColumn, input.cursor.time),
|
||||
and(eq(sortColumn, input.cursor.time), gt(SessionTable.id, input.cursor.id)),
|
||||
gt(sortColumn, input.anchor.time),
|
||||
and(eq(sortColumn, input.anchor.time), gt(SessionTable.id, input.anchor.id)),
|
||||
)!
|
||||
: or(
|
||||
lt(sortColumn, input.cursor.time),
|
||||
and(eq(sortColumn, input.cursor.time), lt(SessionTable.id, input.cursor.id)),
|
||||
lt(sortColumn, input.anchor.time),
|
||||
and(eq(sortColumn, input.anchor.time), lt(SessionTable.id, input.anchor.id)),
|
||||
)!,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user