phase 4 foundations: vendor missing lexicons, refreshSession api, toLex no-op purge, de-agent link-meta
This commit is contained in:
@@ -2,7 +2,6 @@ import {type Client} from '@atproto/lex-client'
|
||||
|
||||
import {DEMO_FEED} from '#/lib/demo'
|
||||
import {type app} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
export class DemoFeedAPI implements FeedAPI {
|
||||
@@ -12,17 +11,13 @@ export class DemoFeedAPI implements FeedAPI {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
async peekLatest(): Promise<app.bsky.feed.defs.FeedViewPost> {
|
||||
/*
|
||||
* TODO(phase4): drop this cast once `#/lib/demo` (DEMO_FEED) sources its
|
||||
* feed items from `#/lexicons`. Its records are still typed against the old
|
||||
* `@atproto/api` FeedViewPost, which does not assign to the branded lexicon
|
||||
* type this method must return.
|
||||
*/
|
||||
return toLex(DEMO_FEED.feed[0])
|
||||
return DEMO_FEED.feed[0]
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
async fetch(): Promise<FeedAPIResponse> {
|
||||
return toLex(DEMO_FEED)
|
||||
return DEMO_FEED
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import {feedUriToHref} from '#/lib/strings/url-helpers'
|
||||
import {getContentLanguages} from '#/state/preferences/languages'
|
||||
import {type FeedParams} from '#/state/queries/post-feed'
|
||||
import {app} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {FeedTuner} from '../feed-manip'
|
||||
import {type FeedTunerFn} from '../feed-manip'
|
||||
import {
|
||||
@@ -264,13 +263,7 @@ class MergeFeedSource_Following extends MergeFeedSource {
|
||||
return {
|
||||
success: true,
|
||||
cursor: res.cursor,
|
||||
/*
|
||||
* TODO(phase4): drop the toLex once `#/lib/api/feed-manip` (FeedTuner)
|
||||
* flips its FeedViewPost source from `@atproto/api` to `#/lexicons`. Its
|
||||
* `_feedPost` is still the old-world view type, which does not assign to
|
||||
* the branded lexicon type this page carries.
|
||||
*/
|
||||
feed: slices.map(slice => toLex(slice._feedPost)),
|
||||
feed: slices.map(slice => slice._feedPost),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-35
@@ -91,16 +91,7 @@ export async function post(
|
||||
for (let i = 0; i < thread.posts.length; i++) {
|
||||
const draft = thread.posts[i]
|
||||
|
||||
/*
|
||||
* Not awaited to avoid waterfalls. `draft.richtext` is still an
|
||||
* `@atproto/api` RichText (composer state is migrated by Task 7); the SDK
|
||||
* RichText is structurally the same transplant, so bridge it here.
|
||||
* TODO(phase4): drop toLex once composer state migrates to SDK RichText.
|
||||
*/
|
||||
const rtPromise = resolveRT(
|
||||
resolveClients.appview,
|
||||
bsky.toLex<RichText>(draft.richtext),
|
||||
)
|
||||
const rtPromise = resolveRT(resolveClients.appview, draft.richtext)
|
||||
const embedPromise = resolveEmbed(
|
||||
clients,
|
||||
queryClient,
|
||||
@@ -138,17 +129,11 @@ export async function post(
|
||||
langs,
|
||||
labels,
|
||||
}
|
||||
/*
|
||||
* `value` is typed `LexMap` (a loose index-signature map). A generated
|
||||
* record type is a valid LexMap at runtime but a strict interface is not
|
||||
* assignable to an index-signature type, so widen with `toLex` at this
|
||||
* boundary. Not a brand cast - the record is already fully typed.
|
||||
*/
|
||||
writes.push({
|
||||
$type: 'com.atproto.repo.applyWrites#create',
|
||||
collection: 'app.bsky.feed.post',
|
||||
rkey: rkey,
|
||||
value: bsky.toLex(record),
|
||||
value: record,
|
||||
})
|
||||
|
||||
if (i === 0 && thread.threadgate.some(tg => tg.type !== 'everybody')) {
|
||||
@@ -156,14 +141,10 @@ export async function post(
|
||||
$type: 'com.atproto.repo.applyWrites#create',
|
||||
collection: 'app.bsky.feed.threadgate',
|
||||
rkey: rkey,
|
||||
value: bsky.toLex(
|
||||
createThreadgateRecord({
|
||||
post: uri,
|
||||
allow: threadgateAllowUISettingToAllowRecordValue(
|
||||
thread.threadgate,
|
||||
),
|
||||
}),
|
||||
),
|
||||
value: createThreadgateRecord({
|
||||
post: uri,
|
||||
allow: threadgateAllowUISettingToAllowRecordValue(thread.threadgate),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -175,12 +156,12 @@ export async function post(
|
||||
$type: 'com.atproto.repo.applyWrites#create',
|
||||
collection: 'app.bsky.feed.postgate',
|
||||
rkey: rkey,
|
||||
value: bsky.toLex({
|
||||
value: {
|
||||
...thread.postgate,
|
||||
$type: 'app.bsky.feed.postgate',
|
||||
createdAt: now.toISOString(),
|
||||
post: uri,
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -426,7 +407,7 @@ async function resolveMedia(
|
||||
* structural shape matches the lexicon blob field; the CID hasher handles
|
||||
* both class instances and plain lex blobs (see computeCid).
|
||||
*/
|
||||
video: bsky.toLex(videoDraft.pendingPublish.blobRef),
|
||||
video: videoDraft.pendingPublish.blobRef,
|
||||
alt: videoDraft.altText || undefined,
|
||||
captions: captions.length === 0 ? undefined : captions,
|
||||
aspectRatio,
|
||||
@@ -475,13 +456,7 @@ async function resolveMedia(
|
||||
title: resolvedLink.title,
|
||||
description: resolvedLink.description,
|
||||
thumb: blob,
|
||||
/*
|
||||
* associatedRefs comes from getLinkMeta, still typed with the old
|
||||
* `@atproto/api` StrongRef (link-meta.ts is out of scope). The shape
|
||||
* is identical; bridge with toLex.
|
||||
* TODO(phase4): drop toLex once link-meta migrates.
|
||||
*/
|
||||
associatedRefs: bsky.toLex(resolvedLink.associatedRefs),
|
||||
associatedRefs: resolvedLink.associatedRefs,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
+3
-15
@@ -23,7 +23,6 @@ import {
|
||||
import {type ComposerImage} from '#/state/gallery'
|
||||
import {createComposerImage} from '#/state/gallery'
|
||||
import {type ChatInvitePreview} from '#/state/queries/join-links'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {type Gif} from '#/features/gifPicker/types'
|
||||
import {app, chat, com} from '#/lexicons'
|
||||
import {createGIFDescription} from '../gif-alt-text'
|
||||
@@ -31,13 +30,10 @@ import {createGIFDescription} from '../gif-alt-text'
|
||||
/**
|
||||
* Clients the link resolver needs. `appview` serves the `app.bsky.*` feed/graph
|
||||
* reads plus handle resolution; `chat` serves the group join-link previews.
|
||||
* `agent` is still threaded through to {@link getLinkMeta}, which has not yet
|
||||
* migrated off the bridge - it only reads the (unused) service URL from it.
|
||||
*/
|
||||
export type ResolveClients = {
|
||||
appview: Client
|
||||
chat: Client
|
||||
agent: SessionAgent
|
||||
}
|
||||
|
||||
type ResolvedExternalLink = {
|
||||
@@ -195,7 +191,7 @@ export async function resolveLink(
|
||||
view: res.starterPack,
|
||||
}
|
||||
}
|
||||
return resolveExternal(clients, uri)
|
||||
return resolveExternal(uri)
|
||||
|
||||
// Forked from useGetPost. TODO: move into RQ.
|
||||
async function getPost({uri}: {uri: string}) {
|
||||
@@ -267,16 +263,8 @@ function getFileSlug(url: string | undefined): string | undefined {
|
||||
return dotIndex > 0 ? filename.slice(0, dotIndex) : undefined
|
||||
}
|
||||
|
||||
async function resolveExternal(
|
||||
clients: ResolveClients,
|
||||
uri: string,
|
||||
): Promise<ResolvedExternalLink> {
|
||||
/*
|
||||
* getLinkMeta still takes the bridge agent (not yet migrated); it only reads
|
||||
* a service URL from it that LINK_META_PROXY ignores. Keep threading the
|
||||
* agent here until link-meta migrates.
|
||||
*/
|
||||
const result = await getLinkMeta(clients.agent, uri)
|
||||
async function resolveExternal(uri: string): Promise<ResolvedExternalLink> {
|
||||
const result = await getLinkMeta(uri)
|
||||
return {
|
||||
type: 'external',
|
||||
uri: result.url,
|
||||
|
||||
Reference in New Issue
Block a user