···152152};
153153154154const rules = (inputs: RulesFnInput<Context, Params, Skeleton>): Skeleton => {
155155- const { ctx, params, skeleton, hydration } = inputs;
156156- const viewer = params.viewer;
155155+ const { ctx, skeleton, hydration } = inputs;
157156158158- // Filter out expired stories (24 hours, except for owner's stories)
157157+ // Filter out expired stories (24 hours)
159158 const activeStories = skeleton.stories.filter((uri) => {
160159 const storyInfo = hydration.stories?.get(uri);
161160 if (!storyInfo) return false;
162162-163163- // If the authenticated user is the author, don't apply the 24h expiration filter
164164- const authorDid = uriToDid(uri);
165165- if (viewer && authorDid === viewer) return true;
166161167162 // Check if story is expired (older than 24 hours)
168163 const twentyFourHoursAgo = new Date();
+4-9
api/so/sprk/story/getTimeline.ts
···128128};
129129130130const rules = (inputs: RulesFnInput<Context, Params, Skeleton>): Skeleton => {
131131- const { ctx, params, skeleton, hydration } = inputs;
132132- const viewer = params.hydrateCtx.viewer!;
131131+ const { ctx, skeleton, hydration } = inputs;
133132134134- // Filter out expired stories (24 hours, except for owner's stories)
135135- // Note: The dataplane already filters expired stories, but we do an additional
136136- // check here for stories from the viewer (which shouldn't be filtered)
133133+ // Filter out expired stories (24 hours)
134134+ // Note: The dataplane already filters expired stories, so we only ensure
135135+ // records still exist after hydration.
137136 const activeStories = skeleton.stories.filter((uri) => {
138137 const storyInfo = hydration.stories?.get(uri);
139138 if (!storyInfo) return false;
140140-141141- // If the authenticated user is the author, don't apply the 24h expiration filter
142142- const authorDid = uriToDid(uri);
143143- if (authorDid === viewer) return true;
144139145140 // The dataplane already filtered expired stories, so we just check if it exists
146141 return true;
+3
data-plane/index.ts
···2121import { Search } from "./routes/search.ts";
2222import { Labels } from "./routes/labels.ts";
2323import { PushTokens } from "./routes/push-tokens.ts";
2424+import { CrosspostThread } from "./routes/crosspost-threads.ts";
24252526export { RepoSubscription } from "./subscription/index.ts";
2627···5556 public search: Search;
5657 public labels: Labels;
5758 public pushTokens: PushTokens;
5959+ public crosspostThread: CrosspostThread;
58605961 constructor(
6062 db: Database,
···8587 this.search = new Search(db);
8688 this.labels = new Labels(db);
8789 this.pushTokens = new PushTokens(db);
9090+ this.crosspostThread = new CrosspostThread(db);
8891 }
8992}
···199199import type * as SoSprkFeedDescribeFeedGenerator from "./types/so/sprk/feed/describeFeedGenerator.ts";
200200import type * as SoSprkFeedSearchPosts from "./types/so/sprk/feed/searchPosts.ts";
201201import type * as SoSprkFeedGetPosts from "./types/so/sprk/feed/getPosts.ts";
202202+import type * as SoSprkFeedGetCrosspostThread from "./types/so/sprk/feed/getCrosspostThread.ts";
202203import type * as SoSprkFeedGetFeed from "./types/so/sprk/feed/getFeed.ts";
203204import type * as SoSprkFeedGetFeedSkeleton from "./types/so/sprk/feed/getFeedSkeleton.ts";
204205import type * as SoSprkFeedGetSuggestedFeeds from "./types/so/sprk/feed/getSuggestedFeeds.ts";
···30773078 >,
30783079 ) {
30793080 const nsid = "so.sprk.feed.getPosts"; // @ts-ignore - dynamically generated
30813081+ return this._server.xrpc.method(nsid, cfg);
30823082+ }
30833083+30843084+ getCrosspostThread<A extends Auth = void>(
30853085+ cfg: MethodConfigOrHandler<
30863086+ A,
30873087+ SoSprkFeedGetCrosspostThread.QueryParams,
30883088+ SoSprkFeedGetCrosspostThread.HandlerInput,
30893089+ SoSprkFeedGetCrosspostThread.HandlerOutput
30903090+ >,
30913091+ ) {
30923092+ const nsid = "so.sprk.feed.getCrosspostThread"; // @ts-ignore - dynamically generated
30803093 return this._server.xrpc.method(nsid, cfg);
30813094 }
30823095