From bfc0dff3a09662d2a57b486d9871e8daae5bfcd7 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Fri, 31 Jul 2026 10:23:40 +0100 Subject: [PATCH] web/api: refactor records.ts into domain specific handlers Signed-off-by: oppiliappan --- web/src/lib/api/comment.ts | 19 +++- web/src/lib/api/issue.ts | 59 +++++++++++- web/src/lib/api/reaction.ts | 19 +++- web/src/lib/api/records.ts | 96 +++---------------- .../components/comment/CommentEditor.svelte | 2 +- .../components/reaction/ReactionPicker.svelte | 2 +- .../lib/components/reaction/Reactions.svelte | 2 +- web/src/lib/components/reaction/reactions.ts | 3 +- .../components/repo/issues/IssueForm.svelte | 3 +- .../routes/[handle]/[repo]/issues/+page.ts | 2 +- .../[repo]/issues/[aturi]/+page.svelte | 4 +- .../[handle]/[repo]/issues/[aturi]/+page.ts | 12 +-- 12 files changed, 122 insertions(+), 101 deletions(-) diff --git a/web/src/lib/api/comment.ts b/web/src/lib/api/comment.ts index ea647d811..6d156ede9 100644 --- a/web/src/lib/api/comment.ts +++ b/web/src/lib/api/comment.ts @@ -4,7 +4,12 @@ import { mainSchema as deleteRecordSchema } from "@atcute/atproto/types/repo/del import type { Nsid, RecordKey } from "@atcute/lexicons/syntax"; import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; import { createClient } from "$lib/auth/agent"; -import type { CommentRecord, RecordView } from "./records"; +import type { BobbinContext, XrpcRequestInit } from "./client"; +import { jsonGet } from "./_request"; +import type { RecordView } from "./records"; +import type * as ShTangledFeedComment from "./lexicons/types/sh/tangled/feed/comment"; + +export type CommentRecord = ShTangledFeedComment.Main; const COMMENT_COLLECTION = "sh.tangled.feed.comment" as Nsid; @@ -35,3 +40,15 @@ export const deleteComment = async (agent: OAuthUserAgent, rkey: string): Promis }) ); }; + +export interface CommentListPage { + cursor?: string | null; + items: RecordView[]; +} + +export const listComments = ( + ctx: BobbinContext, + subject: string, + filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {}, + init?: XrpcRequestInit +) => jsonGet(ctx, "sh.tangled.feed.listComments", { subject, ...filter }, init); diff --git a/web/src/lib/api/issue.ts b/web/src/lib/api/issue.ts index 21db8cc14..bd654b96a 100644 --- a/web/src/lib/api/issue.ts +++ b/web/src/lib/api/issue.ts @@ -4,7 +4,14 @@ import { mainSchema as deleteRecordSchema } from "@atcute/atproto/types/repo/del import type { Nsid, RecordKey } from "@atcute/lexicons/syntax"; import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; import { createClient } from "$lib/auth/agent"; -import type { IssueRecord, RecordView } from "./records"; +import type { BobbinContext, XrpcRequestInit } from "./client"; +import { jsonGet } from "./_request"; +import type { RecordList, RecordView } from "./records"; +import type * as ShTangledRepoIssue from "./lexicons/types/sh/tangled/repo/issue"; +import type * as ShTangledRepoIssueState from "./lexicons/types/sh/tangled/repo/issue/state"; + +export type IssueRecord = ShTangledRepoIssue.Main; +export type IssueStateRecord = ShTangledRepoIssueState.Main; const ISSUE_COLLECTION = "sh.tangled.repo.issue" as Nsid; @@ -35,3 +42,53 @@ export const deleteIssue = async (agent: OAuthUserAgent, rkey: string): Promise< }) ); }; + +export const getIssue = (ctx: BobbinContext, issue: string, init?: XrpcRequestInit) => + jsonGet>(ctx, "sh.tangled.repo.getIssue", { issue }, init); + +export const getIssues = (ctx: BobbinContext, issues: readonly string[], init?: XrpcRequestInit) => + jsonGet>(ctx, "sh.tangled.repo.getIssues", { issues }, init); + +export type IssueState = "open" | "closed"; + +// a listIssues row: the embedded issue record plus bobbin-derived state/counts. +export interface IssueListItem { + cid?: string; + commentCount: number; + state: string; + stateUpdatedAt?: string; + uri: string; + value: IssueRecord; +} + +export interface IssueListPage { + cursor?: string | null; + items: IssueListItem[]; +} + +export interface ListIssuesFilter { + state?: IssueState; + author?: string; + limit?: number; + cursor?: string; + order?: "asc" | "desc"; +} + +export const listIssues = ( + ctx: BobbinContext, + subject: string, + filter: ListIssuesFilter = {}, + init?: XrpcRequestInit +) => jsonGet(ctx, "sh.tangled.repo.listIssues", { subject, ...filter }, init); + +export interface IssueStateList { + cursor?: string | null; + items: RecordView[]; +} + +export const listIssueStates = ( + ctx: BobbinContext, + subject: string, + filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {}, + init?: XrpcRequestInit +) => jsonGet(ctx, "sh.tangled.repo.issue.listStates", { subject, ...filter }, init); diff --git a/web/src/lib/api/reaction.ts b/web/src/lib/api/reaction.ts index d30d5adaf..e224c76fd 100644 --- a/web/src/lib/api/reaction.ts +++ b/web/src/lib/api/reaction.ts @@ -4,7 +4,12 @@ import { mainSchema as deleteRecordSchema } from "@atcute/atproto/types/repo/del import type { Nsid, RecordKey } from "@atcute/lexicons/syntax"; import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; import { createClient } from "$lib/auth/agent"; -import type { ReactionRecord, RecordView } from "./records"; +import type { BobbinContext, XrpcRequestInit } from "./client"; +import { jsonGet } from "./_request"; +import type { RecordView } from "./records"; +import type * as ShTangledFeedReaction from "./lexicons/types/sh/tangled/feed/reaction"; + +export type ReactionRecord = ShTangledFeedReaction.Main; const REACTION_COLLECTION = "sh.tangled.feed.reaction" as Nsid; @@ -35,3 +40,15 @@ export const deleteReaction = async (agent: OAuthUserAgent, rkey: string): Promi }) ); }; + +export interface ReactionListPage { + cursor?: string | null; + items: RecordView[]; +} + +export const listReactions = ( + ctx: BobbinContext, + subject: string, + filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {}, + init?: XrpcRequestInit +) => jsonGet(ctx, "sh.tangled.feed.listReactions", { subject, ...filter }, init); diff --git a/web/src/lib/api/records.ts b/web/src/lib/api/records.ts index eb6e023f7..bfa00af74 100644 --- a/web/src/lib/api/records.ts +++ b/web/src/lib/api/records.ts @@ -1,12 +1,9 @@ import type { BobbinContext, XrpcRequestInit } from "./client"; import { jsonGet } from "./_request"; import type * as ShTangledActorProfile from "./lexicons/types/sh/tangled/actor/profile"; -import type * as ShTangledFeedComment from "./lexicons/types/sh/tangled/feed/comment"; -import type * as ShTangledFeedReaction from "./lexicons/types/sh/tangled/feed/reaction"; import type * as ShTangledPullGetPullView from "./lexicons/types/sh/tangled/pull/getPullView"; +import type * as ShTangledFeedStar from "./lexicons/types/sh/tangled/feed/star"; import type * as ShTangledRepo from "./lexicons/types/sh/tangled/repo"; -import type * as ShTangledRepoIssue from "./lexicons/types/sh/tangled/repo/issue"; -import type * as ShTangledRepoIssueState from "./lexicons/types/sh/tangled/repo/issue/state"; import type * as ShTangledRepoPull from "./lexicons/types/sh/tangled/repo/pull"; import type * as ShTangledRepoPullStatus from "./lexicons/types/sh/tangled/repo/pull/status"; import type * as ShTangledString from "./lexicons/types/sh/tangled/string"; @@ -23,13 +20,10 @@ export interface RecordList { export type RepoRecord = ShTangledRepo.Main; export type ProfileRecord = ShTangledActorProfile.Main; -export type IssueRecord = ShTangledRepoIssue.Main; -export type IssueStateRecord = ShTangledRepoIssueState.Main; export type PullRecord = ShTangledRepoPull.Main; export type PullStatusRecord = ShTangledRepoPullStatus.Main; export type StringRecord = ShTangledString.Main; -export type CommentRecord = ShTangledFeedComment.Main; -export type ReactionRecord = ShTangledFeedReaction.Main; +export type StarRecord = ShTangledFeedStar.Main; export const BULK_LIMIT = 50; @@ -66,77 +60,6 @@ export const getProfile = (ctx: BobbinContext, did: string, init?: XrpcRequestIn init ); -export const getIssue = (ctx: BobbinContext, issue: string, init?: XrpcRequestInit) => - jsonGet>(ctx, "sh.tangled.repo.getIssue", { issue }, init); - -export type IssueState = "open" | "closed"; - -// a listIssues row: the embedded issue record plus bobbin-derived state/counts. -export interface IssueListItem { - cid?: string; - commentCount: number; - state: string; - stateUpdatedAt?: string; - uri: string; - value: IssueRecord; -} - -export interface IssueListPage { - cursor?: string | null; - items: IssueListItem[]; -} - -export interface ListIssuesFilter { - state?: IssueState; - author?: string; - limit?: number; - cursor?: string; - order?: "asc" | "desc"; -} - -export const listIssues = ( - ctx: BobbinContext, - subject: string, - filter: ListIssuesFilter = {}, - init?: XrpcRequestInit -) => jsonGet(ctx, "sh.tangled.repo.listIssues", { subject, ...filter }, init); - -export interface IssueStateList { - cursor?: string | null; - items: RecordView[]; -} - -export const listIssueStates = ( - ctx: BobbinContext, - subject: string, - filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {}, - init?: XrpcRequestInit -) => jsonGet(ctx, "sh.tangled.repo.issue.listStates", { subject, ...filter }, init); - -export interface CommentListPage { - cursor?: string | null; - items: RecordView[]; -} - -export const listComments = ( - ctx: BobbinContext, - subject: string, - filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {}, - init?: XrpcRequestInit -) => jsonGet(ctx, "sh.tangled.feed.listComments", { subject, ...filter }, init); - -export interface ReactionListPage { - cursor?: string | null; - items: RecordView[]; -} - -export const listReactions = ( - ctx: BobbinContext, - subject: string, - filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {}, - init?: XrpcRequestInit -) => jsonGet(ctx, "sh.tangled.feed.listReactions", { subject, ...filter }, init); - export const getPull = (ctx: BobbinContext, pull: string, init?: XrpcRequestInit) => jsonGet>(ctx, "sh.tangled.repo.getPull", { pull }, init); @@ -176,8 +99,17 @@ export const getProfiles = ( init?: XrpcRequestInit ) => jsonGet>(ctx, "sh.tangled.actor.getProfiles", { actors }, init); -export const getIssues = (ctx: BobbinContext, issues: readonly string[], init?: XrpcRequestInit) => - jsonGet>(ctx, "sh.tangled.repo.getIssues", { issues }, init); - export const getPulls = (ctx: BobbinContext, pulls: readonly string[], init?: XrpcRequestInit) => jsonGet>(ctx, "sh.tangled.repo.getPulls", { pulls }, init); + +export interface StarListPage { + cursor?: string | null; + items: RecordView[]; +} + +export const listStars = ( + ctx: BobbinContext, + subject: string, + filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {}, + init?: XrpcRequestInit +) => jsonGet(ctx, "sh.tangled.feed.listStars", { subject, ...filter }, init); diff --git a/web/src/lib/components/comment/CommentEditor.svelte b/web/src/lib/components/comment/CommentEditor.svelte index a78dbf879..20005dd05 100644 --- a/web/src/lib/components/comment/CommentEditor.svelte +++ b/web/src/lib/components/comment/CommentEditor.svelte @@ -10,8 +10,8 @@ import MarkdownEditor from "$lib/components/ui/MarkdownEditor.svelte"; import Spinner from "$lib/components/ui/Spinner.svelte"; import { renderMarkup, type MarkupContext } from "$lib/markup"; - import type { CommentRecord } from "$lib/api/records"; import { createAction } from "$lib/action.svelte"; + import type { CommentRecord } from "$lib/api/comment"; import type { ThreadInput } from "./comments"; interface Props { diff --git a/web/src/lib/components/reaction/ReactionPicker.svelte b/web/src/lib/components/reaction/ReactionPicker.svelte index 1a45a14a9..87f3ceea4 100644 --- a/web/src/lib/components/reaction/ReactionPicker.svelte +++ b/web/src/lib/components/reaction/ReactionPicker.svelte @@ -4,7 +4,7 @@ import { createAction } from "$lib/action.svelte"; import { putReaction, deleteReaction } from "$lib/api/reaction"; import { getAuth } from "$lib/auth.svelte"; - import type { ReactionRecord } from "$lib/api/records"; + import type { ReactionRecord } from "$lib/api/reaction"; import Button from "$lib/components/ui/Button.svelte"; import { ORDERED_REACTION_KINDS, type ReactionKind } from "./reactions"; diff --git a/web/src/lib/components/reaction/Reactions.svelte b/web/src/lib/components/reaction/Reactions.svelte index 4880b82d6..c62ffcf86 100644 --- a/web/src/lib/components/reaction/Reactions.svelte +++ b/web/src/lib/components/reaction/Reactions.svelte @@ -3,7 +3,7 @@ import { now as tidNow } from "@atcute/tid"; import { putReaction, deleteReaction } from "$lib/api/reaction"; import { getAuth } from "$lib/auth.svelte"; - import type { ReactionRecord } from "$lib/api/records"; + import type { ReactionRecord } from "$lib/api/reaction"; import Reaction from "./Reaction.svelte"; import ReactionPicker from "./ReactionPicker.svelte"; import { diff --git a/web/src/lib/components/reaction/reactions.ts b/web/src/lib/components/reaction/reactions.ts index c19ad9c01..b4eceb3fc 100644 --- a/web/src/lib/components/reaction/reactions.ts +++ b/web/src/lib/components/reaction/reactions.ts @@ -1,5 +1,6 @@ import { didFromUri, rkeyFromUri } from "$lib/api/uri"; -import type { ReactionRecord, RecordView } from "$lib/api/records"; +import type { ReactionRecord } from "$lib/api/reaction"; +import type { RecordView } from "$lib/api/records"; export const ORDERED_REACTION_KINDS = ["👍", "👎", "😆", "🎉", "🫤", "❤️", "🚀", "👀"] as const; export type ReactionKind = (typeof ORDERED_REACTION_KINDS)[number]; diff --git a/web/src/lib/components/repo/issues/IssueForm.svelte b/web/src/lib/components/repo/issues/IssueForm.svelte index 46700cee4..a9e950f45 100644 --- a/web/src/lib/components/repo/issues/IssueForm.svelte +++ b/web/src/lib/components/repo/issues/IssueForm.svelte @@ -12,8 +12,9 @@ import MarkdownEditor from "$lib/components/ui/MarkdownEditor.svelte"; import Spinner from "$lib/components/ui/Spinner.svelte"; import { type MarkupContext } from "$lib/markup"; - import type { IssueRecord, RecordView } from "$lib/api/records"; import { createAction } from "$lib/action.svelte"; + import type { IssueRecord } from "$lib/api/issue"; + import type { RecordView } from "$lib/api/records"; interface Props { repoDid: string; diff --git a/web/src/routes/[handle]/[repo]/issues/+page.ts b/web/src/routes/[handle]/[repo]/issues/+page.ts index 6198ad0b0..19c23021f 100644 --- a/web/src/routes/[handle]/[repo]/issues/+page.ts +++ b/web/src/routes/[handle]/[repo]/issues/+page.ts @@ -1,7 +1,7 @@ import { createBobbinClient } from "$lib/api/client"; import { count } from "$lib/api/count"; import { enrich, handleOf, TYPE_MINIDOC } from "$lib/api/enrich"; -import type { IssueListPage } from "$lib/api/records"; +import type { IssueListPage } from "$lib/api/issue"; import { didFromUri, rkeyFromUri } from "$lib/api/uri"; import type { IssueSummary } from "$lib/components/repo/types"; import type { PageLoad } from "./$types"; diff --git a/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte b/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte index 905809aed..5b2d72226 100644 --- a/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte +++ b/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte @@ -15,8 +15,8 @@ import { goto } from "$app/navigation"; import { resolve } from "$app/paths"; import { renderMarkup } from "$lib/markup"; - import { deleteIssue } from "$lib/api/issue"; - import type { IssueRecord, RecordView } from "$lib/api/records"; + import { deleteIssue, type IssueRecord } from "$lib/api/issue"; + import type { RecordView } from "$lib/api/records"; import type { ThreadInput } from "$lib/components/comment/comments"; import { getAuth } from "$lib/auth.svelte"; import { createAction } from "$lib/action.svelte"; diff --git a/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.ts b/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.ts index ada883299..d2c92ccb4 100644 --- a/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.ts +++ b/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.ts @@ -2,14 +2,10 @@ import { error } from "@sveltejs/kit"; import { createBobbinClient } from "$lib/api/client"; import { enrich, handleOf, miniDocOf, TYPE_MINIDOC } from "$lib/api/enrich"; import { INVALID_HANDLE, type MiniDoc } from "$lib/api/identity"; -import { - listIssueStates, - type CommentListPage, - type IssueRecord, - type ReactionListPage, - type RecordView, - type ReactionRecord -} from "$lib/api/records"; +import { listIssueStates, type IssueRecord } from "$lib/api/issue"; +import type { CommentListPage } from "$lib/api/comment"; +import type { ReactionListPage, ReactionRecord } from "$lib/api/reaction"; +import type { RecordView } from "$lib/api/records"; import { didFromUri, rkeyFromUri } from "$lib/api/uri"; import { renderMarkup } from "$lib/markup"; import { buildCommentThreads, type ThreadInput } from "$lib/components/comment/comments"; -- 2.51.2