Replace mock-api with real api

zio/stable
Paul Frazee 2022-09-22 19:28:25 -05:00
parent 5193a5b48e
commit aabde2b401
110 changed files with 16045 additions and 3742 deletions

View File

@ -220,11 +220,11 @@ PODS:
- React-jsinspector (0.68.2)
- React-logger (0.68.2):
- glog
- react-native-safe-area-context (4.3.1):
- react-native-safe-area-context (4.3.4):
- RCT-Folly
- RCTRequired
- RCTTypeSafety
- React
- React-Core
- ReactCommon/turbomodule/core
- React-perflogger (0.68.2)
- React-RCTActionSheet (0.68.2):
@ -291,15 +291,17 @@ PODS:
- React-jsi (= 0.68.2)
- React-logger (= 0.68.2)
- React-perflogger (= 0.68.2)
- RNCAsyncStorage (1.17.6):
- rn-fetch-blob (0.12.0):
- React-Core
- RNCClipboard (1.10.0):
- RNCAsyncStorage (1.17.10):
- React-Core
- RNGestureHandler (2.5.0):
- RNCClipboard (1.11.1):
- React-Core
- RNInAppBrowser (3.6.3):
- RNGestureHandler (2.6.1):
- React-Core
- RNReanimated (2.9.1):
- RNInAppBrowser (3.7.0):
- React-Core
- RNReanimated (2.10.0):
- DoubleConversion
- FBLazyVector
- FBReactNativeSpec
@ -326,10 +328,10 @@ PODS:
- React-RCTText
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (3.13.1):
- RNScreens (3.17.0):
- React-Core
- React-RCTImage
- RNSVG (12.4.0):
- RNSVG (12.4.4):
- React-Core
- Yoga (1.14.0)
@ -368,6 +370,7 @@ DEPENDENCIES:
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- rn-fetch-blob (from `../node_modules/rn-fetch-blob`)
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
@ -446,6 +449,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
rn-fetch-blob:
:path: "../node_modules/rn-fetch-blob"
RNCAsyncStorage:
:path: "../node_modules/@react-native-async-storage/async-storage"
RNCClipboard:
@ -484,7 +489,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: b7b553412f2ec768fe6c8f27cd6bafdb9d8719e6
React-jsinspector: c5989c77cb89ae6a69561095a61cce56a44ae8e8
React-logger: a0833912d93b36b791b7a521672d8ee89107aff1
react-native-safe-area-context: 6c12e3859b6f27b25de4fee8201cfb858432d8de
react-native-safe-area-context: dfe5aa13bee37a0c7e8059d14f72ffc076d120e9
React-perflogger: a18b4f0bd933b8b24ecf9f3c54f9bf65180f3fe6
React-RCTActionSheet: 547fe42fdb4b6089598d79f8e1d855d7c23e2162
React-RCTAnimation: bc9440a1c37b06ae9ebbb532d244f607805c6034
@ -497,13 +502,14 @@ SPEC CHECKSUMS:
React-RCTVibration: 79040b92bfa9c3c2d2cb4f57e981164ec7ab9374
React-runtimeexecutor: b960b687d2dfef0d3761fbb187e01812ebab8b23
ReactCommon: 095366164a276d91ea704ce53cb03825c487a3f2
RNCAsyncStorage: 466b9df1a14bccda91da86e0b7d9a345d78e1673
RNCClipboard: f1736c75ab85b627a4d57587edb4b60999c4dd80
RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50
RNInAppBrowser: 3ff3a3b8f458aaf25aaee879d057352862edf357
RNReanimated: 5c8c17e26787fd8984cd5accdc70fef2ca70aafd
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
RNSVG: 3dd44d99d1c18e1342aee4bfa53ab3f6a8c4865f
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd
RNGestureHandler: 28ad20bf02257791f7f137b31beef34b9549f54b
RNInAppBrowser: e36d6935517101ccba0e875bac8ad7b0cb655364
RNReanimated: 5bdcbcc3a72aedeee7bb099604262403aa75a1e5
RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9
RNSVG: ecd661f380a07ba690c9c5929c475a44f432d674
Yoga: 99652481fcd320aefa4a7ef90095b95acd181952
PODFILE CHECKSUM: cf94853ebcb0d8e0d027dca9ab7a4ede886a8f20

View File

@ -4,18 +4,14 @@
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"ios": "react-native run-ios --simulator=\"iPhone 14\"",
"web": "react-scripts start",
"start": "react-native start",
"dev-pds": "node ./scripts/testing-server.mjs",
"dev-wallet": "cd node_modules/\\@adxp/auth-lobby && npm run start:authed",
"dev-env": "dev-env",
"test": "jest",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
},
"dependencies": {
"@adxp/auth": "*",
"@adxp/common": "*",
"@adxp/mock-api": "git+ssh://git@github.com:bluesky-social/adx-mock-api.git#e6f9ecd510fd54fbc5af32e319342634d9446a07",
"@fortawesome/fontawesome-svg-core": "^6.1.1",
"@fortawesome/free-regular-svg-icons": "^6.1.1",
"@fortawesome/free-solid-svg-icons": "^6.1.1",
@ -44,12 +40,10 @@
"react-native-svg": "^12.4.0",
"react-native-url-polyfill": "^1.3.0",
"react-native-web": "^0.17.7",
"rn-fetch-blob": "^0.12.0",
"ucans": "0.9.1"
},
"devDependencies": {
"@adxp/auth-lobby": "*",
"@adxp/server": "*",
"@adxp/ws-relay": "*",
"@babel/core": "^7.12.9",
"@babel/runtime": "^7.12.5",
"@react-native-community/eslint-config": "^2.0.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -1,36 +0,0 @@
import {IpldStore} from '@adxp/common'
import PDSServer from '@adxp/server/dist/server.js'
import PDSDatabase from '@adxp/server/dist/db/index.js'
import WSRelayServer from '@adxp/ws-relay/dist/index.js'
import AuthLobbyServer from '@adxp/auth-lobby'
const PDS_PORT = 2583
const AUTH_LOBBY1_PORT = 3001
const AUTH_LOBBY2_PORT = 3002
const WSR_PORT = 3005
async function start() {
console.log('Initializing...')
const db = PDSDatabase.memory()
const serverBlockstore = IpldStore.createInMemory()
await db.dropTables()
await db.createTables()
PDSServer(serverBlockstore, db, PDS_PORT)
init(AuthLobbyServer, AUTH_LOBBY1_PORT, 'Auth lobby')
if (process.argv.includes('--relay')) {
init(AuthLobbyServer, AUTH_LOBBY2_PORT, 'Auth lobby 2')
init(WSRelayServer, WSR_PORT, 'Relay server')
} else {
console.log('Include --relay to start the WS Relay and second auth lobby')
}
}
start()
function init(fn, port, name) {
const s = fn(port)
s.on('listening', () => console.log(`${name} running on port ${port}`))
s.on('error', e => console.log(`${name} failed to start:`, e))
}

View File

@ -1,5 +1,5 @@
import {autorun} from 'mobx'
import {AdxClient, blueskywebSchemas} from '@adxp/mock-api'
import AdxApi from '../third-party/api'
import {RootStoreModel} from './models/root-store'
import * as libapi from './lib/api'
import * as storage from './lib/storage'
@ -13,10 +13,7 @@ export async function setupState() {
let rootStore: RootStoreModel
let data: any
const api = new AdxClient({
pds: 'http://localhost',
schemas: blueskywebSchemas,
})
const api = AdxApi.service(`http://localhost:2583`)
await libapi.setup(api)
rootStore = new RootStoreModel(api)
try {

View File

@ -3,33 +3,18 @@
* models live. They are made available to every model via dependency injection.
*/
import RNFetchBlob from 'rn-fetch-blob'
// import {ReactNativeStore} from './auth'
import {
AdxClient,
AdxRepoClient,
AdxRepoCollectionClient,
AdxUri,
bsky,
SchemaOpt,
ListRecordsResponseValidated,
GetRecordResponseValidated,
} from '@adxp/mock-api'
import AdxApi, {ServiceClient} from '../../third-party/api'
import {AdxUri} from '../../third-party/uri'
import * as storage from './storage'
import {postTexts} from './mock-data/post-texts'
import {replyTexts} from './mock-data/reply-texts'
export async function setup(adx: AdxClient) {
await adx.setupMock(
() => storage.load('mock-root'),
async root => {
await storage.save('mock-root', root)
},
() => generateMockData(adx),
)
export async function setup(adx: ServiceClient) {
AdxApi.xrpc.fetch = fetchHandler
}
export async function post(
adx: AdxClient,
adx: ServiceClient,
user: string,
text: string,
replyToUri?: string,
@ -37,10 +22,10 @@ export async function post(
let reply
if (replyToUri) {
const replyToUrip = new AdxUri(replyToUri)
const parentPost = await adx
.repo(replyToUrip.host, false)
.collection(replyToUrip.collection)
.get('Post', replyToUrip.recordKey)
const parentPost = await adx.todo.social.post.get({
nameOrDid: replyToUrip.host,
tid: replyToUrip.recordKey,
})
if (parentPost) {
reply = {
root: parentPost.value.reply?.root || parentPost.uri,
@ -48,94 +33,126 @@ export async function post(
}
}
}
return await adx
.repo(user, true)
.collection('blueskyweb.xyz:Posts')
.create('Post', {
$type: 'blueskyweb.xyz:Post',
return await adx.todo.social.post.create(
{did: user},
{
text,
reply,
createdAt: new Date().toISOString(),
})
},
)
}
export async function like(adx: AdxClient, user: string, uri: string) {
return await adx
.repo(user, true)
.collection('blueskyweb.xyz:Likes')
.create('Like', {
$type: 'blueskyweb.xyz:Like',
export async function like(adx: ServiceClient, user: string, uri: string) {
return await adx.todo.social.like.create(
{did: user},
{
subject: uri,
createdAt: new Date().toISOString(),
})
},
)
}
export async function unlike(adx: AdxClient, user: string, uri: string) {
const coll = adx.repo(user, true).collection('blueskyweb.xyz:Likes')
const numDels = await deleteWhere(coll, 'Like', record => {
return record.value.subject === uri
})
return numDels > 0
export async function unlike(adx: ServiceClient, user: string, uri: string) {
throw new Error('TODO')
}
export async function repost(adx: AdxClient, user: string, uri: string) {
return await adx
.repo(user, true)
.collection('blueskyweb.xyz:Posts')
.create('Repost', {
$type: 'blueskyweb.xyz:Repost',
export async function repost(adx: ServiceClient, user: string, uri: string) {
return await adx.todo.social.repost.create(
{did: user},
{
subject: uri,
createdAt: new Date().toISOString(),
})
},
)
}
export async function unrepost(adx: AdxClient, user: string, uri: string) {
const coll = adx.repo(user, true).collection('blueskyweb.xyz:Posts')
const numDels = await deleteWhere(coll, 'Repost', record => {
return record.value.subject === uri
})
return numDels > 0
export async function unrepost(adx: ServiceClient, user: string, uri: string) {
throw new Error('TODO')
}
export async function follow(
adx: AdxClient,
adx: ServiceClient,
user: string,
subject: {did: string; name: string},
subject: string,
) {
return await adx
.repo(user, true)
.collection('blueskyweb.xyz:Follows')
.create('Follow', {
$type: 'blueskyweb.xyz:Follow',
return await adx.todo.social.follow.create(
{did: user},
{
subject,
createdAt: new Date().toISOString(),
})
},
)
}
export async function unfollow(
adx: AdxClient,
adx: ServiceClient,
user: string,
subject: {did: string},
) {
const coll = adx.repo(user, true).collection('blueskyweb.xyz:Follows')
const numDels = await deleteWhere(coll, 'Follow', record => {
return record.value.subject.did === subject.did
})
return numDels > 0
throw new Error('TODO')
}
export async function updateProfile(
adx: AdxClient,
adx: ServiceClient,
user: string,
profile: bsky.Profile.Record,
) {
return await adx
.repo(user, true)
.collection('blueskyweb.xyz:Profiles')
.put('Profile', 'profile', {$type: 'blueskyweb.xyz:Profile', ...profile})
throw new Error('TODO')
}
type WherePred = (_record: GetRecordResponseValidated) => Boolean
interface FetchHandlerResponse {
status: number
headers: Record<string, string>
body: ArrayBuffer | undefined
}
async function fetchHandler(
httpUri: string,
httpMethod: string,
httpHeaders: Record<string, string>,
httpReqBody: any,
): Promise<FetchHandlerResponse> {
httpHeaders['Authorization'] = 'did:test:alice' // DEBUG
const res = await RNFetchBlob.fetch(
/** @ts-ignore method coersion, it's fine -prf */
httpMethod,
httpUri,
httpHeaders,
httpReqBody,
)
const status = res.info().status
const headers = (res.info().headers || {}) as Record<string, string>
const mimeType = headers['Content-Type'] || headers['content-type']
let resBody
if (mimeType) {
if (mimeType.startsWith('application/json')) {
resBody = res.json()
} else if (mimeType.startsWith('text/')) {
resBody = res.text()
} else {
resBody = res.base64()
}
}
return {
status,
headers,
body: resBody,
}
// const res = await fetch(httpUri, {
// method: httpMethod,
// headers: httpHeaders,
// body: encodeMethodCallBody(httpHeaders, httpReqBody),
// })
// const resBody = await res.arrayBuffer()
// return {
// status: res.status,
// headers: Object.fromEntries(res.headers.entries()),
// body: httpResponseBodyParse(res.headers.get('content-type'), resBody),
// }
}
/*type WherePred = (_record: GetRecordResponseValidated) => Boolean
async function deleteWhere(
coll: AdxRepoCollectionClient,
schema: SchemaOpt,
@ -170,177 +187,4 @@ async function iterateAll(
}
}
} while (res.records.length === 100)
}
// TEMPORARY
// mock api config
// =======
function* dateGen() {
let start = 1657846031914
while (true) {
yield new Date(start).toISOString()
start += 1e3
}
}
const date = dateGen()
function repo(adx: AdxClient, didOrName: string) {
const userDb = adx.mockDb.getUser(didOrName)
if (!userDb) throw new Error(`User not found: ${didOrName}`)
return adx.mainPds.repo(userDb.did, userDb.writable)
}
export async function generateMockData(adx: AdxClient) {
const rand = (n: number) => Math.floor(Math.random() * n)
const picka = <T>(arr: Array<T>): T => {
if (arr.length) {
return arr[rand(arr.length)] || arr[0]
}
throw new Error('Not found')
}
await adx.mockDb.addUser({name: 'alice.com', writable: true})
await adx.mockDb.addUser({name: 'bob.com', writable: true})
await adx.mockDb.addUser({name: 'carla.com', writable: true})
const alice = repo(adx, 'alice.com')
const bob = repo(adx, 'bob.com')
const carla = repo(adx, 'carla.com')
const repos = [alice, bob, carla]
await alice.collection('blueskyweb.xyz:Profiles').put('Profile', 'profile', {
$type: 'blueskyweb.xyz:Profile',
displayName: 'Alice',
description: 'Test user 1',
})
await bob.collection('blueskyweb.xyz:Profiles').put('Profile', 'profile', {
$type: 'blueskyweb.xyz:Profile',
displayName: 'Bob',
description: 'Test user 2',
})
await carla.collection('blueskyweb.xyz:Profiles').put('Profile', 'profile', {
$type: 'blueskyweb.xyz:Profile',
displayName: 'Carla',
description: 'Test user 3',
})
// everybody follows everybody
const follow = async (who: AdxRepoClient, subjectName: string) => {
const subjectDb = adx.mockDb.getUser(subjectName)
return who.collection('blueskyweb.xyz:Follows').create('Follow', {
$type: 'blueskyweb.xyz:Follow',
subject: {
did: subjectDb?.did,
name: subjectDb?.name,
},
createdAt: date.next().value,
})
}
await follow(alice, 'bob.com')
await follow(alice, 'carla.com')
await follow(bob, 'alice.com')
await follow(bob, 'carla.com')
await follow(carla, 'alice.com')
await follow(carla, 'bob.com')
// a set of posts and reposts
const posts: {uri: string}[] = []
for (let i = 0; i < postTexts.length; i++) {
const author = picka(repos)
posts.push(
await author.collection('blueskyweb.xyz:Posts').create('Post', {
$type: 'blueskyweb.xyz:Post',
text: postTexts[i],
createdAt: date.next().value,
}),
)
if (rand(10) === 0) {
await picka(repos)
.collection('blueskyweb.xyz:Posts')
.create('Repost', {
$type: 'blueskyweb.xyz:Repost',
subject: picka(posts).uri,
createdAt: date.next().value,
})
}
}
// a set of replies
for (let i = 0; i < 100; i++) {
const targetUri = picka(posts).uri
const urip = new AdxUri(targetUri)
const target = await adx.mainPds
.repo(urip.host, true)
.collection(urip.collection)
.get('Post', urip.recordKey)
const targetRecord = target.value as bsky.Post.Record
const author = picka(repos)
posts.push(
await author.collection('blueskyweb.xyz:Posts').create('Post', {
$type: 'blueskyweb.xyz:Post',
text: picka(replyTexts),
reply: {
root: targetRecord.reply ? targetRecord.reply.root : target.uri,
parent: target.uri,
},
createdAt: date.next().value,
}),
)
}
// a set of likes
for (const post of posts) {
for (const repo of repos) {
if (rand(3) === 0) {
await repo.collection('blueskyweb.xyz:Likes').create('Like', {
$type: 'blueskyweb.xyz:Like',
subject: post.uri,
createdAt: date.next().value,
})
}
}
}
// give alice 3 badges, 2 from bob and 2 from carla, with one ignored
const inviteBadge = await bob
.collection('blueskyweb.xyz:Badges')
.create('Badge', {
$type: 'blueskyweb.xyz:Badge',
subject: {did: alice.did, name: 'alice.com'},
assertion: {type: 'invite'},
createdAt: date.next().value,
})
const techTagBadge1 = await bob
.collection('blueskyweb.xyz:Badges')
.create('Badge', {
$type: 'blueskyweb.xyz:Badge',
subject: {did: alice.did, name: 'alice.com'},
assertion: {type: 'tag', tag: 'tech'},
createdAt: date.next().value,
})
const techTagBadge2 = await carla
.collection('blueskyweb.xyz:Badges')
.create('Badge', {
$type: 'blueskyweb.xyz:Badge',
subject: {did: alice.did, name: 'alice.com'},
assertion: {type: 'tag', tag: 'tech'},
createdAt: date.next().value,
})
await bob.collection('blueskyweb.xyz:Badges').create('Badge', {
$type: 'blueskyweb.xyz:Badge',
subject: {did: alice.did, name: 'alice.com'},
assertion: {type: 'employee'},
createdAt: date.next().value,
})
await alice.collection('blueskyweb.xyz:Profiles').put('Profile', 'profile', {
$type: 'blueskyweb.xyz:Profile',
displayName: 'Alice',
description: 'Test user 1',
badges: [
{uri: inviteBadge.uri},
{uri: techTagBadge1.uri},
{uri: techTagBadge2.uri},
],
})
}
}*/

View File

@ -1,4 +1,5 @@
import * as auth from '@adxp/auth'
export {} // TODO
/*import * as auth from '@adxp/auth'
import * as ucan from 'ucans'
import {
getInitialURL,
@ -114,3 +115,4 @@ export class ReactNativeStore extends auth.AuthStore {
this.ucanStore = await ucan.Store.fromTokens([])
}
}
*/

View File

@ -1,147 +0,0 @@
// I just scraped some of my twitter timeline into here
// hope nobody minds
// -prf
export const postTexts = [
'last call! share your most offbeat home idea and you could get $100,000 USD to build it. applications to the OMG! fund are open until july 22. for rules and how to apply→ http://airbnb.com/omgfund?twclid=2-6f25jsvulsw1bpglil5jvkku0',
'Great to get some quality time with @DavidJWest #Agile2022',
'vive la sybil résistance',
'Where does one mint on @tezos these days?',
'Tame the day with the soothing and luxurious all-new 2022 INFINITI QX60.',
"In case you're wondering how it's going in the UK, here's the person most likely to be our next PM:",
'Really thought I was watching an SNL clip',
'Mediocrity is like a magnet pulling organizations toward it. You can only avoid it by constant effort.',
'Nobody in the replies talking about RegCF, DAOs, etc…\n' +
'\n' +
'The innovation is non, perhaps contra-hierarchical.',
'There are times when I think DevOps is just group therapy for system administrators.',
'Is DevOps still relevant?\n' +
'\n' +
'Join me tomorrow, at 11:00 AM PDT, to discuss the state of DevOps with @nathenharvey, as we attempt to answer that question. https://twitter.com/i/spaces/1dRKZlMPbWaJB…',
'trash is love. trash is life.',
'I want you guys to know Ive done it. Ive killed the legendary Michael Myers with a series of good stabs. No one could survive it. Hell, I even checked to be sure he was dead. Anyone got weekend plans?',
'Orgs that performed timely server upgrades averaged 19% revenue growth.',
'Seeing all of the @ mention mint scams of late…',
"For fuck's sake, Gary.",
'And another',
'Ah go on, one more',
"Wait, so there's no way to test microphone settings for Twitter Spaces without creating a Twitter Space, going 'live', and having it notify everyone? Amazing.",
'gidge day',
'British Defense Intelligence Ukraine Update, July 20, 2022\n' +
'#RussiaUkraineWar',
' Were launching a brand new template soon on @tailwindui Im really excited about this one! \n' +
'\n' +
'Here is a preview:',
'Are you looking for a pediatrician near your home or work? ARC has pediatricians in 23 locations around Central Texas. \n' +
'\n' +
'Our pediatricians are ready to partner with you in the growth and development of your child and family, no matter where you live.',
'And well be making undici-fetch happen. H/t @matteocollina',
"It's Wednesday, you know what that means....\n" +
'\n' +
' Office Hours - 9:30AM PDT / 12:30PM EDT / 4:30PM (16:30) GMT \n' +
'\n' +
' Maker Hour - 1:00PM PDT / 4:00PM EDT / 8:00PM (20:00) GMT\n' +
'\n' +
'Join us in @discord',
"Europe's bleak Russian winter, made stark: \n" +
'\n' +
"Brussels proposes Europe cuts its gas usage by 15 per cent between now and April next year if governments literally want to keep the lights on and people's homes warm.",
'Tips for using TypeScript via JSDoc comments',
'My talk is today come say hi!',
'Im giving a talk on private smart contract using homomorphic encryption on Wednesday at 2:20pm. Come say hi! #fhe #web3 #privacy #ethereum',
'We have just showcased the new build and discussed our future plans to support developers Recording coming soon! If you are in Paris drop us a line to grab a coffee ',
'TFW you forget to buy milk for your morning coffee and now have to get dressed and go outside at 6:30am.',
'seeing an awful lot of articles referring to the "European heatwave" in the past tense. first of all:',
'Is there a way to fix this issue this when using TypeScript via JSDoc comments? (Reply to the quoted tweet.)',
'For instance in this code I dont know how to tell TS that, no, the `res` will not be `string`. (`api` is an instance of the `got` npm package).',
'In the latest magazine, bob kindly invited me to write about techniques for ensuring convergence in distributed systems. Article is now up!',
"This is a reboot of the “Research for Practice” column that @alice.com used to run. The idea is to distill some key ideas from recent CS research and to make them accessible to folks in industry who don't normally have time for reading papers.",
"This is cool: post a video to @whimful's REVERSE CONFERENCE @ DWeb so you can maximize your human connecting time at camp ",
'New blog post: How to speed up the Rust compiler in July 2022\n' +
'\n' +
'https://nnethercote.github.io/2022/07/20/how-to-speed-up-the-rust-compiler-in-july-2022.html…\n' +
'\n' +
'PGO on Windows, MIR inlining, better derived code for builtin traits, and much more!',
'my new favorite past time is watching older couples at the airport \n' +
'\n' +
'Wife: “Put your mask on. I dont want you sick for your birthday.”\n' +
'Husband: “Can you leave me alone for one goddamn minute?”',
"We're all gonna die",
'Builders building, this month at @NativeHostels on 4th Street.\n' +
'- Coworking & coffee on Tuesdays 11am-3pm \n' +
'- HAPPY HOUR HANGOUTS on Thursdays 7:30-10pm \n' +
'RSVP: https://ATXDAO-Native-HH.eventbrite.com',
'crypto meetings IRL are my favorite.\n' +
'\n' +
'@ATXDAO\n' +
'@HopeCampaign\n' +
'@NativeHostels\n' +
'@wagmiyall \n' +
'@evrydayresearch \n' +
'@zcreativemedia \n' +
'@CrystalGravy2\n' +
'@NickCPlusPlus\n' +
'@_ElaineAlonzo',
'I recommend @Scroll_ZKP create and hire for a developer advocate position to deliver world class developer experience.',
'Intelligent Tracking Prevention identifies trackers and helps prevent them from profiling or following you across the web.',
"Big story in Norway this summer is a walrus we've named Freya has made it to our shores and is touring the country, laying around and sinking boats",
'"the other fellows at the CIA were unequivocally against assassinating three of the greatest musicians of their generation, but I went in there and held my convictions and said my piece."',
'hls is annoying technology',
'This summer, prey for survival. Experience #BeastMovie only in theaters August 19.',
"got the new twitter update. i don't like it",
'Might just set this as a daily reminder.',
'Gm. Today, ask yourself:\n' +
'\n' +
'Is my Web3/NFT/DeFi/crypto making a better life for someone other than myself?',
'every time I add a piece to my native #webgl engine I end up crying and appreciating even more the work @mrdoob and the @threejs team is doing. yall have no idea',
'i dont like having 2 plagues and no healthcare. i should have 0 plagues and 2 healthcare',
'this is the only lotr behind the scenes pic that matters actually',
'Photographer took pictures of a baby hippo scared of birds',
'lol',
"VC's explaining web3.",
'Cyberattacks cost banks $18.3 million annually per company. We ensure that youre not part of that statistic.#stayrelentless.',
'In SF, you can choose kind of weather you want',
'a day in earth 2.0 should be 26 hours',
'who wants to start a religion',
'We just launched our code-hosting platform!\n' +
'\n' +
"It's like Github, but has hyperlinked syntax-highlighted code and docs from day one \n" +
'\n' +
"I can't overemphasize how nice it feels to push code and immediately see it there, published, highlighted, and linked up!",
'Now that youve seen them do the universe, its time for them to do a new series. Mike Judges Beavis and Butt-Head is coming to #ParamountPlus on August 4th. #beavisandbutthead',
'Organized a nice crypto research dinner with @protocollabs and @zama_fhe - very vibrant community with a lot of open problems :)\n' +
'\n' +
'Planning to organize more going forward - reach out if this is your vibe!',
"Houston drivers are crazy. Been here two days and have had multiple vehicles charging up and tailing me, then switching lanes, roaring past, and weaving through traffic. While I'm going 75mph, keeping with the flow of traffic. WTF??",
`LIVE NOW: a mix of projects coming to #DWebCamp2022! @gvelez17 of @dsocialcommons is planning "Dogfooding Decentralization" a user-testing lab at DWeb Camp. You can sign up to present your tools. We'll send you the link tomorrow! 1/n`,
`Fabiola of @guardianproject is bringing "Butter Box" "Inspiration Beans" & more. (They must love ) Butter Box is raspberry pi-based hotspot w/ encrypted chat. It's opensource & offline first. Come onboard & connect with others offline. (8/n)`,
"Up Now: @guardianproject's Jack Fox Keen w/ tools to verify the authencity++ of data. They are leading a Cryptographically Verified Scavenger Hunt (9/n)",
'Translating VC Language',
'What would Sherlock Holmes do? Listen to true crime podcasts early on Amazon Music. #TrueCrimeonAmazonMusic',
'How to deal with a hung Linux system',
'ALRIGHT PELOTON HAPPY MONDAY I WANNA FEEL THAT ENERGY COMING THROUGH THE SCREEN AS WE START GETTING OUR AMAZING BODIES WARMED UP. THIS FIRST TRACK IS CALLED "DONALD DUCK GETTING A BLOWJOB" RESISTANCE 30 CADENCE 80',
"Thank you to all who joined us at @pbailis' executive roundtable lunch at @VentureBeat's #VBTransform!\n" +
'\n' +
'#ICYMI, stop by the Sisu table today to meet the team & learn how to supercharge your analytics workflow with decision intelligence.',
'Prescribing Info: http://bit.ly/2cTmItE?twclid=2-1jogj2v7zxu2rw1zmzyms8jpg \n' +
'Med Guide: http://bit.ly/2yon94P?twclid=2-1jogj2v7zxu2rw1zmzyms8jpg\n' +
'\n' +
'Discover a treatment for certain patients with kidney cancer (RCC).',
'Want to learn how to write E2EE P2P apps without even trying? Check out the new application sandbox and api in Peergos!',
'Ageism was always a reality in tech. \n' +
'\n' +
'The “in-office” only crowd have found a way to make their ageism more respectable.\n' +
'\n' +
'PS - most startups would rather hire the 32 yo Senior FAANG engineer than a 20 something grad who needs a ton of mentorship.',
"I don't mind jumping on a call at work. I think that should be the last resort, not the first one.",
'If you missed attending #MSInspire, we missed you too. You can still find plenty of on-demand content available at your convenience. Take advantage of the ongoing opportunity to enrich your business prospects.',
"TODAY AT 4 PM PT: Join for the DWeb Meetup where we'll see some of the workshops coming to DWeb Camp 2022:\n" +
'@metagov_project\n' +
' @ameliawb\n' +
' @guardianproject\n' +
' @gvelez17\n' +
' @infrared_ether\n' +
'@LauBenedict\n' +
' @guardianproject\n' +
'@byUnfinished\n' +
' Come be inspired:',
]

View File

@ -1,24 +0,0 @@
export const replyTexts = [
'Wow, so true!',
'Haha ikr',
'lol',
'What does this mean for democrats in the midterms?',
'What does this mean for republicans in the midterms?',
'What does this mean for pet owners in the midterms?',
'is it cool if I DM?',
"This is sort of accurate, but honestly it misses a huge part of the issue at hand. There are just so many factors and I don't think a vibe is enough to cover it.",
'Wen token',
'This is disgusting and you should take it down',
'fire',
'a/s/l?',
'this is so much better than twitter',
'this is so much better than tiktok',
'this is so much better than gab',
'this is so much better than truth social',
'finally! decentralization!',
'ugh when will hashtags get supported in vibe',
'ted cruz is the deep state!',
'aoc is the deep state!',
'donald trump is the deep state!',
'taco tuesdays is the deep state!',
]

View File

@ -1,30 +1,30 @@
import {makeAutoObservable, runInAction} from 'mobx'
import {bsky} from '@adxp/mock-api'
import * as GetFeedView from '../../third-party/api/src/types/todo/social/getFeed'
import {RootStoreModel} from './root-store'
import * as apilib from '../lib/api'
export class FeedViewItemMyStateModel {
hasLiked: boolean = false
hasReposted: boolean = false
repost?: string
like?: string
constructor() {
makeAutoObservable(this)
}
}
export class FeedViewItemModel implements bsky.FeedView.FeedItem {
export class FeedViewItemModel implements GetFeedView.FeedItem {
// ui state
_reactKey: string = ''
// data
uri: string = ''
author: bsky.FeedView.User = {did: '', name: '', displayName: ''}
repostedBy?: bsky.FeedView.User
author: GetFeedView.User = {did: '', name: '', displayName: ''}
repostedBy?: GetFeedView.User
record: Record<string, unknown> = {}
embed?:
| bsky.FeedView.RecordEmbed
| bsky.FeedView.ExternalEmbed
| bsky.FeedView.UnknownEmbed
| GetFeedView.RecordEmbed
| GetFeedView.ExternalEmbed
| GetFeedView.UnknownEmbed
replyCount: number = 0
repostCount: number = 0
likeCount: number = 0
@ -34,14 +34,14 @@ export class FeedViewItemModel implements bsky.FeedView.FeedItem {
constructor(
public rootStore: RootStoreModel,
reactKey: string,
v: bsky.FeedView.FeedItem,
v: GetFeedView.FeedItem,
) {
makeAutoObservable(this, {rootStore: false})
this._reactKey = reactKey
this.copy(v)
}
copy(v: bsky.FeedView.FeedItem) {
copy(v: GetFeedView.FeedItem) {
this.uri = v.uri
this.author = v.author
this.repostedBy = v.repostedBy
@ -52,52 +52,56 @@ export class FeedViewItemModel implements bsky.FeedView.FeedItem {
this.likeCount = v.likeCount
this.indexedAt = v.indexedAt
if (v.myState) {
this.myState.hasLiked = v.myState.hasLiked
this.myState.hasReposted = v.myState.hasReposted
this.myState.like = v.myState.like
this.myState.repost = v.myState.repost
}
}
async toggleLike() {
if (this.myState.hasLiked) {
await apilib.unlike(this.rootStore.api, 'alice.com', this.uri)
if (this.myState.like) {
await apilib.unlike(this.rootStore.api, 'alice.test', this.uri)
runInAction(() => {
this.likeCount--
this.myState.hasLiked = false
this.myState.like = undefined
})
} else {
await apilib.like(this.rootStore.api, 'alice.com', this.uri)
const res = await apilib.like(this.rootStore.api, 'alice.test', this.uri)
runInAction(() => {
this.likeCount++
this.myState.hasLiked = true
this.myState.like = res.uri
})
}
}
async toggleRepost() {
if (this.myState.hasReposted) {
await apilib.unrepost(this.rootStore.api, 'alice.com', this.uri)
if (this.myState.repost) {
await apilib.unrepost(this.rootStore.api, 'alice.test', this.uri)
runInAction(() => {
this.repostCount--
this.myState.hasReposted = false
this.myState.repost = undefined
})
} else {
await apilib.repost(this.rootStore.api, 'alice.com', this.uri)
const res = await apilib.repost(
this.rootStore.api,
'alice.test',
this.uri,
)
runInAction(() => {
this.repostCount++
this.myState.hasReposted = true
this.myState.repost = res.uri
})
}
}
}
export class FeedViewModel implements bsky.FeedView.Response {
export class FeedViewModel {
// state
isLoading = false
isRefreshing = false
hasLoaded = false
hasReachedEnd = false
error = ''
params: bsky.FeedView.Params
params: GetFeedView.QueryParams
_loadPromise: Promise<void> | undefined
_loadMorePromise: Promise<void> | undefined
_updatePromise: Promise<void> | undefined
@ -105,7 +109,10 @@ export class FeedViewModel implements bsky.FeedView.Response {
// data
feed: FeedViewItemModel[] = []
constructor(public rootStore: RootStoreModel, params: bsky.FeedView.Params) {
constructor(
public rootStore: RootStoreModel,
params: GetFeedView.QueryParams,
) {
makeAutoObservable(
this,
{
@ -223,10 +230,7 @@ export class FeedViewModel implements bsky.FeedView.Response {
this._xLoading(isRefreshing)
await new Promise(r => setTimeout(r, 250)) // DEBUG
try {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:FeedView',
this.params,
)) as bsky.FeedView.Response
const res = await this.rootStore.api.todo.social.getFeed(this.params)
this._replaceAll(res)
this._xIdle()
} catch (e: any) {
@ -241,11 +245,8 @@ export class FeedViewModel implements bsky.FeedView.Response {
const params = Object.assign({}, this.params, {
before: this.loadMoreCursor,
})
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:FeedView',
params,
)) as bsky.FeedView.Response
if (res.feed.length === 0) {
const res = await this.rootStore.api.todo.social.getFeed(params)
if (res.data.feed.length === 0) {
runInAction(() => {
this.hasReachedEnd = true
})
@ -265,20 +266,18 @@ export class FeedViewModel implements bsky.FeedView.Response {
let cursor = undefined
try {
do {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:FeedView',
{
const res: GetFeedView.Response =
await this.rootStore.api.todo.social.getFeed({
before: cursor,
limit: Math.min(numToFetch, 100),
},
)) as bsky.FeedView.Response
if (res.feed.length === 0) {
})
if (res.data.feed.length === 0) {
break // sanity check
}
this._updateAll(res)
numToFetch -= res.feed.length
cursor = this.feed[res.feed.length - 1].indexedAt
console.log(numToFetch, cursor, res.feed.length)
numToFetch -= res.data.feed.length
cursor = this.feed[res.data.feed.length - 1].indexedAt
console.log(numToFetch, cursor, res.data.feed.length)
} while (numToFetch > 0)
this._xIdle()
} catch (e: any) {
@ -286,26 +285,26 @@ export class FeedViewModel implements bsky.FeedView.Response {
}
}
private _replaceAll(res: bsky.FeedView.Response) {
private _replaceAll(res: GetFeedView.Response) {
this.feed.length = 0
this.hasReachedEnd = false
this._appendAll(res)
}
private _appendAll(res: bsky.FeedView.Response) {
private _appendAll(res: GetFeedView.Response) {
let counter = this.feed.length
for (const item of res.feed) {
for (const item of res.data.feed) {
this._append(counter++, item)
}
}
private _append(keyId: number, item: bsky.FeedView.FeedItem) {
private _append(keyId: number, item: GetFeedView.FeedItem) {
// TODO: validate .record
this.feed.push(new FeedViewItemModel(this.rootStore, `item-${keyId}`, item))
}
private _updateAll(res: bsky.FeedView.Response) {
for (const item of res.feed) {
private _updateAll(res: GetFeedView.Response) {
for (const item of res.data.feed) {
const existingItem = this.feed.find(
// this find function has a key subtley- the indexedAt comparison
// the reason for this is reposts: they set the URI of the original post, not of the repost record

View File

@ -1,8 +1,9 @@
import {makeAutoObservable, runInAction} from 'mobx'
import {bsky, AdxUri} from '@adxp/mock-api'
import {AdxUri} from '../../third-party/uri'
import * as GetLikedBy from '../../third-party/api/src/types/todo/social/getLikedBy'
import {RootStoreModel} from './root-store'
type LikedByItem = bsky.LikedByView.Response['likedBy'][number]
type LikedByItem = GetLikedBy.OutputSchema['likedBy'][number]
export class LikedByViewItemModel implements LikedByItem {
// ui state
@ -22,14 +23,14 @@ export class LikedByViewItemModel implements LikedByItem {
}
}
export class LikedByViewModel implements bsky.LikedByView.Response {
export class LikedByViewModel {
// state
isLoading = false
isRefreshing = false
hasLoaded = false
error = ''
resolvedUri = ''
params: bsky.LikedByView.Params
params: GetLikedBy.QueryParams
// data
uri: string = ''
@ -37,7 +38,7 @@ export class LikedByViewModel implements bsky.LikedByView.Response {
constructor(
public rootStore: RootStoreModel,
params: bsky.LikedByView.Params,
params: GetLikedBy.QueryParams,
) {
makeAutoObservable(
this,
@ -113,10 +114,9 @@ export class LikedByViewModel implements bsky.LikedByView.Response {
this._xLoading(isRefreshing)
await new Promise(r => setTimeout(r, 250)) // DEBUG
try {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:LikedByView',
const res = await this.rootStore.api.todo.social.getLikedBy(
Object.assign({}, this.params, {uri: this.resolvedUri}),
)) as bsky.LikedByView.Response
)
this._replaceAll(res)
this._xIdle()
} catch (e: any) {
@ -124,10 +124,10 @@ export class LikedByViewModel implements bsky.LikedByView.Response {
}
}
private _replaceAll(res: bsky.LikedByView.Response) {
private _replaceAll(res: GetLikedBy.Response) {
this.likedBy.length = 0
let counter = 0
for (const item of res.likedBy) {
for (const item of res.data.likedBy) {
this._append(counter++, item)
}
}

View File

@ -14,18 +14,16 @@ export class MeModel {
async load() {
const sess = this.rootStore.session
if (sess.isAuthed) {
const userDb = this.rootStore.api.mockDb.mainUser
this.did = userDb.did
this.name = userDb.name
const profile = await this.rootStore.api
.repo(this.did, true)
.collection('blueskyweb.xyz:Profiles')
.get('Profile', 'profile')
.catch(_ => undefined)
// TODO
this.did = 'did:test:alice'
this.name = 'alice.todo'
const profile = await this.rootStore.api.todo.social.getProfile({
user: this.did,
})
runInAction(() => {
if (profile?.valid) {
this.displayName = profile.value.displayName
this.description = profile.value.description
if (profile?.data) {
this.displayName = profile.data.displayName
this.description = profile.data.description
} else {
this.displayName = ''
this.description = ''

View File

@ -231,8 +231,9 @@ export class NavigationModel {
}
hydrate(v: unknown) {
this.tabs.length = 0
this.tabIndex = 0
// this.tabs.length = 0
// this.tabIndex = 0
return // DEBUG
if (isObj(v)) {
if (hasProp(v, 'tabs') && Array.isArray(v.tabs)) {
for (const tab of v.tabs) {

View File

@ -1,10 +1,10 @@
import {makeAutoObservable, runInAction} from 'mobx'
import {bsky} from '@adxp/mock-api'
import {makeAutoObservable} from 'mobx'
import * as GetNotifications from '../../third-party/api/src/types/todo/social/getNotifications'
import {RootStoreModel} from './root-store'
import {hasProp} from '../lib/type-guards'
export class NotificationsViewItemModel
implements bsky.NotificationsView.Notification
implements GetNotifications.Notification
{
// ui state
_reactKey: string = ''
@ -23,14 +23,14 @@ export class NotificationsViewItemModel
constructor(
public rootStore: RootStoreModel,
reactKey: string,
v: bsky.NotificationsView.Notification,
v: GetNotifications.Notification,
) {
makeAutoObservable(this, {rootStore: false})
this._reactKey = reactKey
this.copy(v)
}
copy(v: bsky.NotificationsView.Notification) {
copy(v: GetNotifications.Notification) {
this.uri = v.uri
this.author = v.author
this.record = v.record
@ -77,13 +77,13 @@ export class NotificationsViewItemModel
}
}
export class NotificationsViewModel implements bsky.NotificationsView.Response {
export class NotificationsViewModel {
// state
isLoading = false
isRefreshing = false
hasLoaded = false
error = ''
params: bsky.NotificationsView.Params
params: GetNotifications.QueryParams
_loadPromise: Promise<void> | undefined
_loadMorePromise: Promise<void> | undefined
_updatePromise: Promise<void> | undefined
@ -93,7 +93,7 @@ export class NotificationsViewModel implements bsky.NotificationsView.Response {
constructor(
public rootStore: RootStoreModel,
params: bsky.NotificationsView.Params,
params: GetNotifications.QueryParams,
) {
makeAutoObservable(
this,
@ -212,10 +212,9 @@ export class NotificationsViewModel implements bsky.NotificationsView.Response {
this._xLoading(isRefreshing)
await new Promise(r => setTimeout(r, 250)) // DEBUG
try {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:NotificationsView',
const res = await this.rootStore.api.todo.social.getNotifications(
this.params,
)) as bsky.NotificationsView.Response
)
this._replaceAll(res)
this._xIdle()
} catch (e: any) {
@ -230,10 +229,7 @@ export class NotificationsViewModel implements bsky.NotificationsView.Response {
const params = Object.assign({}, this.params, {
before: this.loadMoreCursor,
})
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:NotificationsView',
params,
)) as bsky.NotificationsView.Response
const res = await this.rootStore.api.todo.social.getNotifications(params)
this._appendAll(res)
this._xIdle()
} catch (e: any) {
@ -248,20 +244,18 @@ export class NotificationsViewModel implements bsky.NotificationsView.Response {
let cursor = undefined
try {
do {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:NotificationsView',
{
const res: GetNotifications.Response =
await this.rootStore.api.todo.social.getNotifications({
before: cursor,
limit: Math.min(numToFetch, 100),
},
)) as bsky.NotificationsView.Response
if (res.notifications.length === 0) {
})
if (res.data.notifications.length === 0) {
break // sanity check
}
this._updateAll(res)
numToFetch -= res.notifications.length
cursor = this.notifications[res.notifications.length - 1].indexedAt
console.log(numToFetch, cursor, res.notifications.length)
numToFetch -= res.data.notifications.length
cursor = this.notifications[res.data.notifications.length - 1].indexedAt
console.log(numToFetch, cursor, res.data.notifications.length)
} while (numToFetch > 0)
this._xIdle()
} catch (e: any) {
@ -269,27 +263,27 @@ export class NotificationsViewModel implements bsky.NotificationsView.Response {
}
}
private _replaceAll(res: bsky.NotificationsView.Response) {
private _replaceAll(res: GetNotifications.Response) {
this.notifications.length = 0
this._appendAll(res)
}
private _appendAll(res: bsky.NotificationsView.Response) {
private _appendAll(res: GetNotifications.Response) {
let counter = this.notifications.length
for (const item of res.notifications) {
for (const item of res.data.notifications) {
this._append(counter++, item)
}
}
private _append(keyId: number, item: bsky.NotificationsView.Notification) {
private _append(keyId: number, item: GetNotifications.Notification) {
// TODO: validate .record
this.notifications.push(
new NotificationsViewItemModel(this.rootStore, `item-${keyId}`, item),
)
}
private _updateAll(res: bsky.NotificationsView.Response) {
for (const item of res.notifications) {
private _updateAll(res: GetNotifications.Response) {
for (const item of res.data.notifications) {
const existingItem = this.notifications.find(
// this find function has a key subtley- the indexedAt comparison
// the reason for this is reposts: they set the URI of the original post, not of the repost record

View File

@ -1,5 +1,6 @@
import {makeAutoObservable, runInAction} from 'mobx'
import {bsky, AdxUri} from '@adxp/mock-api'
import * as GetPostThread from '../../third-party/api/src/types/todo/social/getPostThread'
import {AdxUri} from '../../third-party/uri'
import _omit from 'lodash.omit'
import {RootStoreModel} from './root-store'
import * as apilib from '../lib/api'
@ -12,15 +13,15 @@ function* reactKeyGenerator(): Generator<string> {
}
export class PostThreadViewPostMyStateModel {
hasLiked: boolean = false
hasReposted: boolean = false
like?: string
repost?: string
constructor() {
makeAutoObservable(this)
}
}
export class PostThreadViewPostModel implements bsky.PostThreadView.Post {
export class PostThreadViewPostModel implements GetPostThread.Post {
// ui state
_reactKey: string = ''
_depth = 0
@ -28,12 +29,12 @@ export class PostThreadViewPostModel implements bsky.PostThreadView.Post {
// data
uri: string = ''
author: bsky.PostThreadView.User = {did: '', name: '', displayName: ''}
author: GetPostThread.User = {did: '', name: '', displayName: ''}
record: Record<string, unknown> = {}
embed?:
| bsky.PostThreadView.RecordEmbed
| bsky.PostThreadView.ExternalEmbed
| bsky.PostThreadView.UnknownEmbed
| GetPostThread.RecordEmbed
| GetPostThread.ExternalEmbed
| GetPostThread.UnknownEmbed
parent?: PostThreadViewPostModel
replyCount: number = 0
replies?: PostThreadViewPostModel[]
@ -45,7 +46,7 @@ export class PostThreadViewPostModel implements bsky.PostThreadView.Post {
constructor(
public rootStore: RootStoreModel,
reactKey: string,
v?: bsky.PostThreadView.Post,
v?: GetPostThread.Post,
) {
makeAutoObservable(this, {rootStore: false})
this._reactKey = reactKey
@ -57,7 +58,7 @@ export class PostThreadViewPostModel implements bsky.PostThreadView.Post {
}
}
assignTreeModels(keyGen: Generator<string>, v: bsky.PostThreadView.Post) {
assignTreeModels(keyGen: Generator<string>, v: GetPostThread.Post) {
// parents
if (v.parent) {
// TODO: validate .record
@ -93,33 +94,37 @@ export class PostThreadViewPostModel implements bsky.PostThreadView.Post {
}
async toggleLike() {
if (this.myState.hasLiked) {
await apilib.unlike(this.rootStore.api, 'alice.com', this.uri)
if (this.myState.like) {
await apilib.unlike(this.rootStore.api, 'alice.test', this.uri)
runInAction(() => {
this.likeCount--
this.myState.hasLiked = false
this.myState.like = undefined
})
} else {
await apilib.like(this.rootStore.api, 'alice.com', this.uri)
const res = await apilib.like(this.rootStore.api, 'alice.test', this.uri)
runInAction(() => {
this.likeCount++
this.myState.hasLiked = true
this.myState.like = res.uri
})
}
}
async toggleRepost() {
if (this.myState.hasReposted) {
await apilib.unrepost(this.rootStore.api, 'alice.com', this.uri)
if (this.myState.repost) {
await apilib.unrepost(this.rootStore.api, 'alice.test', this.uri)
runInAction(() => {
this.repostCount--
this.myState.hasReposted = false
this.myState.repost = undefined
})
} else {
await apilib.repost(this.rootStore.api, 'alice.com', this.uri)
const res = await apilib.repost(
this.rootStore.api,
'alice.test',
this.uri,
)
runInAction(() => {
this.repostCount++
this.myState.hasReposted = true
this.myState.repost = res.uri
})
}
}
@ -132,14 +137,14 @@ export class PostThreadViewModel {
hasLoaded = false
error = ''
resolvedUri = ''
params: bsky.PostThreadView.Params
params: GetPostThread.QueryParams
// data
thread?: PostThreadViewPostModel
constructor(
public rootStore: RootStoreModel,
params: bsky.PostThreadView.Params,
params: GetPostThread.QueryParams,
) {
makeAutoObservable(
this,
@ -226,10 +231,9 @@ export class PostThreadViewModel {
private async _load(isRefreshing = false) {
this._xLoading(isRefreshing)
try {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:PostThreadView',
const res = await this.rootStore.api.todo.social.getPostThread(
Object.assign({}, this.params, {uri: this.resolvedUri}),
)) as bsky.PostThreadView.Response
)
this._replaceAll(res)
this._xIdle()
} catch (e: any) {
@ -237,16 +241,16 @@ export class PostThreadViewModel {
}
}
private _replaceAll(res: bsky.PostThreadView.Response) {
private _replaceAll(res: GetPostThread.Response) {
// TODO: validate .record
const keyGen = reactKeyGenerator()
const thread = new PostThreadViewPostModel(
this.rootStore,
keyGen.next().value,
res.thread,
res.data.thread,
)
thread._isHighlightedPost = true
thread.assignTreeModels(keyGen, res.thread)
thread.assignTreeModels(keyGen, res.data.thread)
this.thread = thread
}
}

View File

@ -1,10 +1,18 @@
import {makeAutoObservable} from 'mobx'
import {bsky, AdxUri} from '@adxp/mock-api'
import * as Post from '../../third-party/api/src/types/todo/social/post'
import {AdxUri} from '../../third-party/uri'
import {RootStoreModel} from './root-store'
export type PostEntities = bsky.Post.Record['entities']
export type PostReply = bsky.Post.Record['reply']
export class PostModel implements bsky.Post.Record {
export type PostEntities = Post.Record['entities']
export type PostReply = Post.Record['reply']
type RemoveIndex<T> = {
[P in keyof T as string extends P
? never
: number extends P
? never
: P]: T[P]
}
export class PostModel implements RemoveIndex<Post.Record> {
// state
isLoading = false
hasLoaded = false
@ -70,13 +78,14 @@ export class PostModel implements bsky.Post.Record {
await new Promise(r => setTimeout(r, 250)) // DEBUG
try {
const urip = new AdxUri(this.uri)
const res = await this.rootStore.api.mainPds
.repo(urip.host, false)
.collection(urip.collection)
.get('Post', urip.recordKey)
if (!res.valid) {
throw new Error(res.error)
}
const res = await this.rootStore.api.todo.social.post.get({
nameOrDid: urip.host,
tid: urip.recordKey,
})
// TODO
// if (!res.valid) {
// throw new Error(res.error)
// }
this._replaceAll(res.value)
this._xIdle()
} catch (e: any) {
@ -84,7 +93,7 @@ export class PostModel implements bsky.Post.Record {
}
}
private _replaceAll(res: bsky.Post.Record) {
private _replaceAll(res: Post.Record) {
this.text = res.text
this.entities = res.entities
this.reply = res.reply

View File

@ -1,38 +1,39 @@
import {makeAutoObservable, runInAction} from 'mobx'
import {bsky} from '@adxp/mock-api'
import * as GetProfile from '../../third-party/api/src/types/todo/social/getProfile'
import * as Profile from '../../third-party/api/src/types/todo/social/profile'
import {RootStoreModel} from './root-store'
import * as apilib from '../lib/api'
export class ProfileViewMyStateModel {
hasFollowed: boolean = false
follow?: string
constructor() {
makeAutoObservable(this)
}
}
export class ProfileViewModel implements bsky.ProfileView.Response {
export class ProfileViewModel {
// state
isLoading = false
isRefreshing = false
hasLoaded = false
error = ''
params: bsky.ProfileView.Params
params: GetProfile.QueryParams
// data
did: string = ''
name: string = ''
displayName: string = ''
description: string = ''
displayName?: string
description?: string
followersCount: number = 0
followsCount: number = 0
postsCount: number = 0
badges: bsky.ProfileView.Badge[] = []
badges: GetProfile.Badge[] = []
myState = new ProfileViewMyStateModel()
constructor(
public rootStore: RootStoreModel,
params: bsky.ProfileView.Params,
params: GetProfile.QueryParams,
) {
makeAutoObservable(
this,
@ -69,27 +70,31 @@ export class ProfileViewModel implements bsky.ProfileView.Response {
}
async toggleFollowing() {
if (this.myState.hasFollowed) {
await apilib.unfollow(this.rootStore.api, 'alice.com', {
if (!this.rootStore.me.did) {
throw new Error('Not logged in')
}
if (this.myState.follow) {
await apilib.unfollow(this.rootStore.api, this.rootStore.me.did, {
did: this.did,
})
runInAction(() => {
this.followersCount--
this.myState.hasFollowed = false
this.myState.follow = undefined
})
} else {
await apilib.follow(this.rootStore.api, 'alice.com', {
did: this.did,
name: this.name,
})
const res = await apilib.follow(
this.rootStore.api,
this.rootStore.me.did,
this.did,
)
runInAction(() => {
this.followersCount++
this.myState.hasFollowed = true
this.myState.follow = res.uri
})
}
}
async updateProfile(profile: bsky.Profile.Record) {
async updateProfile(profile: Profile.Record) {
if (this.did !== this.rootStore.me.did) {
throw new Error('Not your profile!')
}
@ -120,10 +125,7 @@ export class ProfileViewModel implements bsky.ProfileView.Response {
this._xLoading(isRefreshing)
await new Promise(r => setTimeout(r, 250)) // DEBUG
try {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:ProfileView',
this.params,
)) as bsky.ProfileView.Response
const res = await this.rootStore.api.todo.social.getProfile(this.params)
this._replaceAll(res)
this._xIdle()
} catch (e: any) {
@ -131,17 +133,17 @@ export class ProfileViewModel implements bsky.ProfileView.Response {
}
}
private _replaceAll(res: bsky.ProfileView.Response) {
this.did = res.did
this.name = res.name
this.displayName = res.displayName
this.description = res.description
this.followersCount = res.followersCount
this.followsCount = res.followsCount
this.postsCount = res.postsCount
this.badges = res.badges
if (res.myState) {
Object.assign(this.myState, res.myState)
private _replaceAll(res: GetProfile.Response) {
this.did = res.data.did
this.name = res.data.name
this.displayName = res.data.displayName
this.description = res.data.description
this.followersCount = res.data.followersCount
this.followsCount = res.data.followsCount
this.postsCount = res.data.postsCount
this.badges = res.data.badges
if (res.data.myState) {
Object.assign(this.myState, res.data.myState)
}
}
}

View File

@ -1,8 +1,9 @@
import {makeAutoObservable, runInAction} from 'mobx'
import {bsky, AdxUri} from '@adxp/mock-api'
import {AdxUri} from '../../third-party/uri'
import * as GetRepostedBy from '../../third-party/api/src/types/todo/social/getRepostedBy'
import {RootStoreModel} from './root-store'
type RepostedByItem = bsky.RepostedByView.Response['repostedBy'][number]
type RepostedByItem = GetRepostedBy.OutputSchema['repostedBy'][number]
export class RepostedByViewItemModel implements RepostedByItem {
// ui state
@ -22,14 +23,14 @@ export class RepostedByViewItemModel implements RepostedByItem {
}
}
export class RepostedByViewModel implements bsky.RepostedByView.Response {
export class RepostedByViewModel {
// state
isLoading = false
isRefreshing = false
hasLoaded = false
error = ''
resolvedUri = ''
params: bsky.RepostedByView.Params
params: GetRepostedBy.QueryParams
// data
uri: string = ''
@ -37,7 +38,7 @@ export class RepostedByViewModel implements bsky.RepostedByView.Response {
constructor(
public rootStore: RootStoreModel,
params: bsky.RepostedByView.Params,
params: GetRepostedBy.QueryParams,
) {
makeAutoObservable(
this,
@ -113,10 +114,9 @@ export class RepostedByViewModel implements bsky.RepostedByView.Response {
this._xLoading(isRefreshing)
await new Promise(r => setTimeout(r, 250)) // DEBUG
try {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:RepostedByView',
const res = await this.rootStore.api.todo.social.getRepostedBy(
Object.assign({}, this.params, {uri: this.resolvedUri}),
)) as bsky.RepostedByView.Response
)
this._replaceAll(res)
this._xIdle()
} catch (e: any) {
@ -131,10 +131,10 @@ export class RepostedByViewModel implements bsky.RepostedByView.Response {
this._xIdle()
}
private _replaceAll(res: bsky.RepostedByView.Response) {
private _replaceAll(res: GetRepostedBy.Response) {
this.repostedBy.length = 0
let counter = 0
for (const item of res.repostedBy) {
for (const item of res.data.repostedBy) {
this._append(counter++, item)
}
}

View File

@ -3,7 +3,7 @@
*/
import {makeAutoObservable} from 'mobx'
import {adx, AdxClient} from '@adxp/mock-api'
import AdxApi, {ServiceClient} from '../../third-party/api'
import {createContext, useContext} from 'react'
import {isObj, hasProp} from '../lib/type-guards'
import {SessionModel} from './session'
@ -17,7 +17,7 @@ export class RootStoreModel {
shell = new ShellModel()
me = new MeModel(this)
constructor(public api: AdxClient) {
constructor(public api: ServiceClient) {
makeAutoObservable(this, {
api: false,
resolveName: false,
@ -27,9 +27,11 @@ export class RootStoreModel {
}
async resolveName(didOrName: string) {
const userDb = this.api.mockDb.getUser(didOrName)
if (!userDb) throw new Error(`User not found: ${didOrName}`)
return userDb.did
throw new Error('TODO')
return ''
// const userDb = this.api.mockDb.getUser(didOrName)
// if (!userDb) throw new Error(`User not found: ${didOrName}`)
// return userDb.did
}
serialize(): unknown {
@ -51,7 +53,7 @@ export class RootStoreModel {
}
}
const throwawayInst = new RootStoreModel(adx) // this will be replaced by the loader
const throwawayInst = new RootStoreModel(AdxApi.service('http://localhost')) // this will be replaced by the loader
const RootStoreContext = createContext<RootStoreModel>(throwawayInst)
export const RootStoreProvider = RootStoreContext.Provider
export const useStores = () => useContext(RootStoreContext)

View File

@ -1,18 +1,18 @@
import {makeAutoObservable} from 'mobx'
import {bsky} from '@adxp/mock-api'
import * as GetUserFollowers from '../../third-party/api/src/types/todo/social/getUserFollowers'
import {RootStoreModel} from './root-store'
type Subject = bsky.UserFollowersView.Response['subject']
type Subject = GetUserFollowers.OutputSchema['subject']
export type FollowerItem =
bsky.UserFollowersView.Response['followers'][number] & {_reactKey: string}
GetUserFollowers.OutputSchema['followers'][number] & {_reactKey: string}
export class UserFollowersViewModel implements bsky.UserFollowersView.Response {
export class UserFollowersViewModel {
// state
isLoading = false
isRefreshing = false
hasLoaded = false
error = ''
params: bsky.UserFollowersView.Params
params: GetUserFollowers.QueryParams
// data
subject: Subject = {did: '', name: '', displayName: ''}
@ -20,7 +20,7 @@ export class UserFollowersViewModel implements bsky.UserFollowersView.Response {
constructor(
public rootStore: RootStoreModel,
params: bsky.UserFollowersView.Params,
params: GetUserFollowers.QueryParams,
) {
makeAutoObservable(
this,
@ -83,10 +83,9 @@ export class UserFollowersViewModel implements bsky.UserFollowersView.Response {
this._xLoading(isRefreshing)
await new Promise(r => setTimeout(r, 250)) // DEBUG
try {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:UserFollowersView',
const res = await this.rootStore.api.todo.social.getUserFollowers(
this.params,
)) as bsky.UserFollowersView.Response
)
this._replaceAll(res)
this._xIdle()
} catch (e: any) {
@ -94,13 +93,13 @@ export class UserFollowersViewModel implements bsky.UserFollowersView.Response {
}
}
private _replaceAll(res: bsky.UserFollowersView.Response) {
this.subject.did = res.subject.did
this.subject.name = res.subject.name
this.subject.displayName = res.subject.displayName
private _replaceAll(res: GetUserFollowers.Response) {
this.subject.did = res.data.subject.did
this.subject.name = res.data.subject.name
this.subject.displayName = res.data.subject.displayName
this.followers.length = 0
let counter = 0
for (const item of res.followers) {
for (const item of res.data.followers) {
this._append({_reactKey: `item-${counter++}`, ...item})
}
}

View File

@ -1,19 +1,19 @@
import {makeAutoObservable} from 'mobx'
import {bsky} from '@adxp/mock-api'
import * as GetUserFollows from '../../third-party/api/src/types/todo/social/getUserFollows'
import {RootStoreModel} from './root-store'
type Subject = bsky.UserFollowsView.Response['subject']
export type FollowItem = bsky.UserFollowsView.Response['follows'][number] & {
type Subject = GetUserFollows.OutputSchema['subject']
export type FollowItem = GetUserFollows.OutputSchema['follows'][number] & {
_reactKey: string
}
export class UserFollowsViewModel implements bsky.UserFollowsView.Response {
export class UserFollowsViewModel {
// state
isLoading = false
isRefreshing = false
hasLoaded = false
error = ''
params: bsky.UserFollowsView.Params
params: GetUserFollows.QueryParams
// data
subject: Subject = {did: '', name: '', displayName: ''}
@ -21,7 +21,7 @@ export class UserFollowsViewModel implements bsky.UserFollowsView.Response {
constructor(
public rootStore: RootStoreModel,
params: bsky.UserFollowsView.Params,
params: GetUserFollows.QueryParams,
) {
makeAutoObservable(
this,
@ -84,10 +84,9 @@ export class UserFollowsViewModel implements bsky.UserFollowsView.Response {
this._xLoading(isRefreshing)
await new Promise(r => setTimeout(r, 250)) // DEBUG
try {
const res = (await this.rootStore.api.mainPds.view(
'blueskyweb.xyz:UserFollowsView',
const res = await this.rootStore.api.todo.social.getUserFollows(
this.params,
)) as bsky.UserFollowsView.Response
)
this._replaceAll(res)
this._xIdle()
} catch (e: any) {
@ -95,13 +94,13 @@ export class UserFollowsViewModel implements bsky.UserFollowsView.Response {
}
}
private _replaceAll(res: bsky.UserFollowsView.Response) {
this.subject.did = res.subject.did
this.subject.name = res.subject.name
this.subject.displayName = res.subject.displayName
private _replaceAll(res: GetUserFollows.Response) {
this.subject.did = res.data.subject.did
this.subject.name = res.data.subject.name
this.subject.displayName = res.data.subject.displayName
this.follows.length = 0
let counter = 0
for (const item of res.follows) {
for (const item of res.data.follows) {
this._append({_reactKey: `item-${counter++}`, ...item})
}
}

12002
src/third-party/api/index.js vendored 100644

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,24 @@
export declare enum ErrorCode {
NetworkError = "NetworkError",
DidResolutionFailed = "DidResolutionFailed",
NameResolutionFailed = "NameResolutionFailed"
}
export declare class NameResolutionFailed extends Error {
code: ErrorCode;
constructor(name: string);
}
export declare class DidResolutionFailed extends Error {
code: ErrorCode;
constructor(did: string);
}
export declare class WritePermissionError extends Error {
constructor();
}
export declare class APIResponseError extends Error {
httpStatusCode: number;
httpStatusText: string;
httpHeaders?: Record<string, string> | undefined;
httpResponseBody?: any;
constructor(httpStatusCode: number, httpStatusText: string, httpHeaders?: Record<string, string> | undefined, httpResponseBody?: any);
get code(): ErrorCode;
}

View File

@ -0,0 +1,180 @@
import { z } from 'zod';
export declare const getRepoRequest: z.ZodObject<{
did: z.ZodString;
from: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, import("multiformats/cid").CID, string>>;
}, "strip", z.ZodTypeAny, {
from?: import("multiformats/cid").CID | undefined;
did: string;
}, {
from?: string | undefined;
did: string;
}>;
export declare type GetRepoRequest = z.infer<typeof getRepoRequest>;
export declare const postRepoRequest: z.ZodObject<{
did: z.ZodString;
}, "strip", z.ZodTypeAny, {
did: string;
}, {
did: string;
}>;
export declare type PostRepoRequest = z.infer<typeof postRepoRequest>;
export declare const describeRepoParams: z.ZodObject<{
confirmName: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
confirmName?: boolean | undefined;
}, {
confirmName?: boolean | undefined;
}>;
export declare type DescribeRepoParams = z.infer<typeof describeRepoParams>;
export declare const describeRepoResponse: z.ZodObject<{
name: z.ZodString;
did: z.ZodString;
didDoc: z.ZodAny;
collections: z.ZodArray<z.ZodString, "many">;
nameIsCorrect: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
didDoc?: any;
nameIsCorrect?: boolean | undefined;
name: string;
did: string;
collections: string[];
}, {
didDoc?: any;
nameIsCorrect?: boolean | undefined;
name: string;
did: string;
collections: string[];
}>;
export declare type DescribeRepoResponse = z.infer<typeof describeRepoResponse>;
export declare const listRecordsParams: z.ZodObject<{
limit: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, number, string>]>>;
before: z.ZodOptional<z.ZodString>;
after: z.ZodOptional<z.ZodString>;
reverse: z.ZodOptional<z.ZodEffects<z.ZodString, boolean, string>>;
}, "strip", z.ZodTypeAny, {
reverse?: boolean | undefined;
limit?: number | undefined;
before?: string | undefined;
after?: string | undefined;
}, {
reverse?: string | undefined;
limit?: string | number | undefined;
before?: string | undefined;
after?: string | undefined;
}>;
export declare type ListRecordsParams = z.infer<typeof listRecordsParams>;
export declare const listRecordsResponse: z.ZodObject<{
records: z.ZodArray<z.ZodObject<{
uri: z.ZodString;
value: z.ZodAny;
}, "strip", z.ZodTypeAny, {
value?: any;
uri: string;
}, {
value?: any;
uri: string;
}>, "many">;
}, "strip", z.ZodTypeAny, {
records: {
value?: any;
uri: string;
}[];
}, {
records: {
value?: any;
uri: string;
}[];
}>;
export declare type ListRecordsResponse = z.infer<typeof listRecordsResponse>;
export declare const getRecordResponse: z.ZodObject<{
uri: z.ZodString;
value: z.ZodAny;
}, "strip", z.ZodTypeAny, {
value?: any;
uri: string;
}, {
value?: any;
uri: string;
}>;
export declare type GetRecordResponse = z.infer<typeof getRecordResponse>;
export declare const batchWriteParams: z.ZodObject<{
writes: z.ZodArray<z.ZodUnion<[z.ZodObject<{
action: z.ZodLiteral<"create">;
collection: z.ZodString;
value: z.ZodAny;
}, "strip", z.ZodTypeAny, {
value?: any;
action: "create";
collection: string;
}, {
value?: any;
action: "create";
collection: string;
}>, z.ZodObject<{
action: z.ZodLiteral<"update">;
collection: z.ZodString;
tid: z.ZodString;
value: z.ZodAny;
}, "strip", z.ZodTypeAny, {
value?: any;
action: "update";
collection: string;
tid: string;
}, {
value?: any;
action: "update";
collection: string;
tid: string;
}>, z.ZodObject<{
action: z.ZodLiteral<"delete">;
collection: z.ZodString;
tid: z.ZodString;
}, "strip", z.ZodTypeAny, {
action: "delete";
collection: string;
tid: string;
}, {
action: "delete";
collection: string;
tid: string;
}>]>, "many">;
}, "strip", z.ZodTypeAny, {
writes: ({
value?: any;
action: "create";
collection: string;
} | {
value?: any;
action: "update";
collection: string;
tid: string;
} | {
action: "delete";
collection: string;
tid: string;
})[];
}, {
writes: ({
value?: any;
action: "create";
collection: string;
} | {
value?: any;
action: "update";
collection: string;
tid: string;
} | {
action: "delete";
collection: string;
tid: string;
})[];
}>;
export declare type BatchWriteParams = z.infer<typeof batchWriteParams>;
export declare const createRecordResponse: z.ZodObject<{
uri: z.ZodString;
}, "strip", z.ZodTypeAny, {
uri: string;
}, {
uri: string;
}>;
export declare type CreateRecordResponse = z.infer<typeof createRecordResponse>;

View File

@ -0,0 +1,239 @@
import { Client as XrpcClient, ServiceClient as XrpcServiceClient } from '@adxp/xrpc';
import * as TodoAdxCreateAccount from './types/todo/adx/createAccount';
import * as TodoAdxCreateSession from './types/todo/adx/createSession';
import * as TodoAdxDeleteAccount from './types/todo/adx/deleteAccount';
import * as TodoAdxDeleteSession from './types/todo/adx/deleteSession';
import * as TodoAdxGetAccount from './types/todo/adx/getAccount';
import * as TodoAdxGetSession from './types/todo/adx/getSession';
import * as TodoAdxRepoBatchWrite from './types/todo/adx/repoBatchWrite';
import * as TodoAdxRepoCreateRecord from './types/todo/adx/repoCreateRecord';
import * as TodoAdxRepoDeleteRecord from './types/todo/adx/repoDeleteRecord';
import * as TodoAdxRepoDescribe from './types/todo/adx/repoDescribe';
import * as TodoAdxRepoGetRecord from './types/todo/adx/repoGetRecord';
import * as TodoAdxRepoListRecords from './types/todo/adx/repoListRecords';
import * as TodoAdxRepoPutRecord from './types/todo/adx/repoPutRecord';
import * as TodoAdxResolveName from './types/todo/adx/resolveName';
import * as TodoAdxSyncGetRepo from './types/todo/adx/syncGetRepo';
import * as TodoAdxSyncGetRoot from './types/todo/adx/syncGetRoot';
import * as TodoAdxSyncUpdateRepo from './types/todo/adx/syncUpdateRepo';
import * as TodoSocialBadge from './types/todo/social/badge';
import * as TodoSocialFollow from './types/todo/social/follow';
import * as TodoSocialGetFeed from './types/todo/social/getFeed';
import * as TodoSocialGetLikedBy from './types/todo/social/getLikedBy';
import * as TodoSocialGetNotifications from './types/todo/social/getNotifications';
import * as TodoSocialGetPostThread from './types/todo/social/getPostThread';
import * as TodoSocialGetProfile from './types/todo/social/getProfile';
import * as TodoSocialGetRepostedBy from './types/todo/social/getRepostedBy';
import * as TodoSocialGetUserFollowers from './types/todo/social/getUserFollowers';
import * as TodoSocialGetUserFollows from './types/todo/social/getUserFollows';
import * as TodoSocialLike from './types/todo/social/like';
import * as TodoSocialMediaEmbed from './types/todo/social/mediaEmbed';
import * as TodoSocialPost from './types/todo/social/post';
import * as TodoSocialProfile from './types/todo/social/profile';
import * as TodoSocialRepost from './types/todo/social/repost';
export declare class Client {
xrpc: XrpcClient;
constructor();
service(serviceUri: string | URL): ServiceClient;
}
declare const defaultInst: Client;
export default defaultInst;
export declare class ServiceClient {
_baseClient: Client;
xrpc: XrpcServiceClient;
todo: TodoNS;
constructor(baseClient: Client, xrpcService: XrpcServiceClient);
}
export declare class TodoNS {
_service: ServiceClient;
adx: AdxNS;
social: SocialNS;
constructor(service: ServiceClient);
}
export declare class AdxNS {
_service: ServiceClient;
constructor(service: ServiceClient);
createAccount(params: TodoAdxCreateAccount.QueryParams, data?: TodoAdxCreateAccount.InputSchema, opts?: TodoAdxCreateAccount.CallOptions): Promise<TodoAdxCreateAccount.Response>;
createSession(params: TodoAdxCreateSession.QueryParams, data?: TodoAdxCreateSession.InputSchema, opts?: TodoAdxCreateSession.CallOptions): Promise<TodoAdxCreateSession.Response>;
deleteAccount(params: TodoAdxDeleteAccount.QueryParams, data?: TodoAdxDeleteAccount.InputSchema, opts?: TodoAdxDeleteAccount.CallOptions): Promise<TodoAdxDeleteAccount.Response>;
deleteSession(params: TodoAdxDeleteSession.QueryParams, data?: TodoAdxDeleteSession.InputSchema, opts?: TodoAdxDeleteSession.CallOptions): Promise<TodoAdxDeleteSession.Response>;
getAccount(params: TodoAdxGetAccount.QueryParams, data?: TodoAdxGetAccount.InputSchema, opts?: TodoAdxGetAccount.CallOptions): Promise<TodoAdxGetAccount.Response>;
getSession(params: TodoAdxGetSession.QueryParams, data?: TodoAdxGetSession.InputSchema, opts?: TodoAdxGetSession.CallOptions): Promise<TodoAdxGetSession.Response>;
repoBatchWrite(params: TodoAdxRepoBatchWrite.QueryParams, data?: TodoAdxRepoBatchWrite.InputSchema, opts?: TodoAdxRepoBatchWrite.CallOptions): Promise<TodoAdxRepoBatchWrite.Response>;
repoCreateRecord(params: TodoAdxRepoCreateRecord.QueryParams, data?: TodoAdxRepoCreateRecord.InputSchema, opts?: TodoAdxRepoCreateRecord.CallOptions): Promise<TodoAdxRepoCreateRecord.Response>;
repoDeleteRecord(params: TodoAdxRepoDeleteRecord.QueryParams, data?: TodoAdxRepoDeleteRecord.InputSchema, opts?: TodoAdxRepoDeleteRecord.CallOptions): Promise<TodoAdxRepoDeleteRecord.Response>;
repoDescribe(params: TodoAdxRepoDescribe.QueryParams, data?: TodoAdxRepoDescribe.InputSchema, opts?: TodoAdxRepoDescribe.CallOptions): Promise<TodoAdxRepoDescribe.Response>;
repoGetRecord(params: TodoAdxRepoGetRecord.QueryParams, data?: TodoAdxRepoGetRecord.InputSchema, opts?: TodoAdxRepoGetRecord.CallOptions): Promise<TodoAdxRepoGetRecord.Response>;
repoListRecords(params: TodoAdxRepoListRecords.QueryParams, data?: TodoAdxRepoListRecords.InputSchema, opts?: TodoAdxRepoListRecords.CallOptions): Promise<TodoAdxRepoListRecords.Response>;
repoPutRecord(params: TodoAdxRepoPutRecord.QueryParams, data?: TodoAdxRepoPutRecord.InputSchema, opts?: TodoAdxRepoPutRecord.CallOptions): Promise<TodoAdxRepoPutRecord.Response>;
resolveName(params: TodoAdxResolveName.QueryParams, data?: TodoAdxResolveName.InputSchema, opts?: TodoAdxResolveName.CallOptions): Promise<TodoAdxResolveName.Response>;
syncGetRepo(params: TodoAdxSyncGetRepo.QueryParams, data?: TodoAdxSyncGetRepo.InputSchema, opts?: TodoAdxSyncGetRepo.CallOptions): Promise<TodoAdxSyncGetRepo.Response>;
syncGetRoot(params: TodoAdxSyncGetRoot.QueryParams, data?: TodoAdxSyncGetRoot.InputSchema, opts?: TodoAdxSyncGetRoot.CallOptions): Promise<TodoAdxSyncGetRoot.Response>;
syncUpdateRepo(params: TodoAdxSyncUpdateRepo.QueryParams, data?: TodoAdxSyncUpdateRepo.InputSchema, opts?: TodoAdxSyncUpdateRepo.CallOptions): Promise<TodoAdxSyncUpdateRepo.Response>;
}
export declare class SocialNS {
_service: ServiceClient;
badge: BadgeRecord;
follow: FollowRecord;
like: LikeRecord;
mediaEmbed: MediaEmbedRecord;
post: PostRecord;
profile: ProfileRecord;
repost: RepostRecord;
constructor(service: ServiceClient);
getFeed(params: TodoSocialGetFeed.QueryParams, data?: TodoSocialGetFeed.InputSchema, opts?: TodoSocialGetFeed.CallOptions): Promise<TodoSocialGetFeed.Response>;
getLikedBy(params: TodoSocialGetLikedBy.QueryParams, data?: TodoSocialGetLikedBy.InputSchema, opts?: TodoSocialGetLikedBy.CallOptions): Promise<TodoSocialGetLikedBy.Response>;
getNotifications(params: TodoSocialGetNotifications.QueryParams, data?: TodoSocialGetNotifications.InputSchema, opts?: TodoSocialGetNotifications.CallOptions): Promise<TodoSocialGetNotifications.Response>;
getPostThread(params: TodoSocialGetPostThread.QueryParams, data?: TodoSocialGetPostThread.InputSchema, opts?: TodoSocialGetPostThread.CallOptions): Promise<TodoSocialGetPostThread.Response>;
getProfile(params: TodoSocialGetProfile.QueryParams, data?: TodoSocialGetProfile.InputSchema, opts?: TodoSocialGetProfile.CallOptions): Promise<TodoSocialGetProfile.Response>;
getRepostedBy(params: TodoSocialGetRepostedBy.QueryParams, data?: TodoSocialGetRepostedBy.InputSchema, opts?: TodoSocialGetRepostedBy.CallOptions): Promise<TodoSocialGetRepostedBy.Response>;
getUserFollowers(params: TodoSocialGetUserFollowers.QueryParams, data?: TodoSocialGetUserFollowers.InputSchema, opts?: TodoSocialGetUserFollowers.CallOptions): Promise<TodoSocialGetUserFollowers.Response>;
getUserFollows(params: TodoSocialGetUserFollows.QueryParams, data?: TodoSocialGetUserFollows.InputSchema, opts?: TodoSocialGetUserFollows.CallOptions): Promise<TodoSocialGetUserFollows.Response>;
}
export declare class BadgeRecord {
_service: ServiceClient;
constructor(service: ServiceClient);
list(params: Omit<TodoAdxRepoListRecords.QueryParams, 'type'>): Promise<{
records: {
uri: string;
value: TodoSocialBadge.Record;
}[];
}>;
get(params: Omit<TodoAdxRepoGetRecord.QueryParams, 'type'>): Promise<{
uri: string;
value: TodoSocialBadge.Record;
}>;
create(params: Omit<TodoAdxRepoCreateRecord.QueryParams, 'type'>, record: TodoSocialBadge.Record): Promise<{
uri: string;
}>;
put(params: Omit<TodoAdxRepoPutRecord.QueryParams, 'type'>, record: TodoSocialBadge.Record): Promise<{
uri: string;
}>;
delete(params: Omit<TodoAdxRepoDeleteRecord.QueryParams, 'type'>): Promise<void>;
}
export declare class FollowRecord {
_service: ServiceClient;
constructor(service: ServiceClient);
list(params: Omit<TodoAdxRepoListRecords.QueryParams, 'type'>): Promise<{
records: {
uri: string;
value: TodoSocialFollow.Record;
}[];
}>;
get(params: Omit<TodoAdxRepoGetRecord.QueryParams, 'type'>): Promise<{
uri: string;
value: TodoSocialFollow.Record;
}>;
create(params: Omit<TodoAdxRepoCreateRecord.QueryParams, 'type'>, record: TodoSocialFollow.Record): Promise<{
uri: string;
}>;
put(params: Omit<TodoAdxRepoPutRecord.QueryParams, 'type'>, record: TodoSocialFollow.Record): Promise<{
uri: string;
}>;
delete(params: Omit<TodoAdxRepoDeleteRecord.QueryParams, 'type'>): Promise<void>;
}
export declare class LikeRecord {
_service: ServiceClient;
constructor(service: ServiceClient);
list(params: Omit<TodoAdxRepoListRecords.QueryParams, 'type'>): Promise<{
records: {
uri: string;
value: TodoSocialLike.Record;
}[];
}>;
get(params: Omit<TodoAdxRepoGetRecord.QueryParams, 'type'>): Promise<{
uri: string;
value: TodoSocialLike.Record;
}>;
create(params: Omit<TodoAdxRepoCreateRecord.QueryParams, 'type'>, record: TodoSocialLike.Record): Promise<{
uri: string;
}>;
put(params: Omit<TodoAdxRepoPutRecord.QueryParams, 'type'>, record: TodoSocialLike.Record): Promise<{
uri: string;
}>;
delete(params: Omit<TodoAdxRepoDeleteRecord.QueryParams, 'type'>): Promise<void>;
}
export declare class MediaEmbedRecord {
_service: ServiceClient;
constructor(service: ServiceClient);
list(params: Omit<TodoAdxRepoListRecords.QueryParams, 'type'>): Promise<{
records: {
uri: string;
value: TodoSocialMediaEmbed.Record;
}[];
}>;
get(params: Omit<TodoAdxRepoGetRecord.QueryParams, 'type'>): Promise<{
uri: string;
value: TodoSocialMediaEmbed.Record;
}>;
create(params: Omit<TodoAdxRepoCreateRecord.QueryParams, 'type'>, record: TodoSocialMediaEmbed.Record): Promise<{
uri: string;
}>;
put(params: Omit<TodoAdxRepoPutRecord.QueryParams, 'type'>, record: TodoSocialMediaEmbed.Record): Promise<{
uri: string;
}>;
delete(params: Omit<TodoAdxRepoDeleteRecord.QueryParams, 'type'>): Promise<void>;
}
export declare class PostRecord {
_service: ServiceClient;
constructor(service: ServiceClient);
list(params: Omit<TodoAdxRepoListRecords.QueryParams, 'type'>): Promise<{
records: {
uri: string;
value: TodoSocialPost.Record;
}[];
}>;
get(params: Omit<TodoAdxRepoGetRecord.QueryParams, 'type'>): Promise<{
uri: string;
value: TodoSocialPost.Record;
}>;
create(params: Omit<TodoAdxRepoCreateRecord.QueryParams, 'type'>, record: TodoSocialPost.Record): Promise<{
uri: string;
}>;
put(params: Omit<TodoAdxRepoPutRecord.QueryParams, 'type'>, record: TodoSocialPost.Record): Promise<{
uri: string;
}>;
delete(params: Omit<TodoAdxRepoDeleteRecord.QueryParams, 'type'>): Promise<void>;
}
export declare class ProfileRecord {
_service: ServiceClient;
constructor(service: ServiceClient);
list(params: Omit<TodoAdxRepoListRecords.QueryParams, 'type'>): Promise<{
records: {
uri: string;
value: TodoSocialProfile.Record;
}[];
}>;
get(params: Omit<TodoAdxRepoGetRecord.QueryParams, 'type'>): Promise<{
uri: string;
value: TodoSocialProfile.Record;
}>;
create(params: Omit<TodoAdxRepoCreateRecord.QueryParams, 'type'>, record: TodoSocialProfile.Record): Promise<{
uri: string;
}>;
put(params: Omit<TodoAdxRepoPutRecord.QueryParams, 'type'>, record: TodoSocialProfile.Record): Promise<{
uri: string;
}>;
delete(params: Omit<TodoAdxRepoDeleteRecord.QueryParams, 'type'>): Promise<void>;
}
export declare class RepostRecord {
_service: ServiceClient;
constructor(service: ServiceClient);
list(params: Omit<TodoAdxRepoListRecords.QueryParams, 'type'>): Promise<{
records: {
uri: string;
value: TodoSocialRepost.Record;
}[];
}>;
get(params: Omit<TodoAdxRepoGetRecord.QueryParams, 'type'>): Promise<{
uri: string;
value: TodoSocialRepost.Record;
}>;
create(params: Omit<TodoAdxRepoCreateRecord.QueryParams, 'type'>, record: TodoSocialRepost.Record): Promise<{
uri: string;
}>;
put(params: Omit<TodoAdxRepoPutRecord.QueryParams, 'type'>, record: TodoSocialRepost.Record): Promise<{
uri: string;
}>;
delete(params: Omit<TodoAdxRepoDeleteRecord.QueryParams, 'type'>): Promise<void>;
}

View File

@ -0,0 +1,3 @@
import { MethodSchema, RecordSchema } from '@adxp/lexicon';
export declare const methodSchemas: MethodSchema[];
export declare const recordSchemas: RecordSchema[];

View File

@ -0,0 +1,28 @@
import { AdxRecordValidator, AdxRecordValidatorDescription } from '@adxp/schemas';
import { GetRecordResponse } from './http-types.js';
export declare type SchemaOpt = string | string[] | AdxRecordValidator | AdxRecordValidatorDescription | '*';
export interface AdxClientOpts {
pds?: string;
locale?: string;
schemas?: any[];
}
export interface RegisterRepoParams {
did: string;
username: string;
}
export interface GetRecordResponseValidated extends GetRecordResponse {
valid?: boolean;
fullySupported?: boolean;
compatible?: boolean;
error?: string | undefined;
fallbacks?: string[] | undefined;
}
export interface ListRecordsResponseValidated {
records: GetRecordResponseValidated[];
}
export interface BatchWrite {
action: 'create' | 'put' | 'del';
collection: string;
key?: string;
value?: any;
}

View File

@ -0,0 +1,17 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/json';
data: InputSchema;
}
export interface InputSchema {
username: string;
did: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
}

View File

@ -0,0 +1,20 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
data: InputSchema;
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,20 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
data: InputSchema;
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,20 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
data: InputSchema;
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,20 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
data: InputSchema;
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,20 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
data: InputSchema;
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,35 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
validate?: boolean;
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/json';
data: InputSchema;
}
export interface InputSchema {
writes: ({
action: 'create';
collection: string;
value: unknown;
} | {
action: 'update';
collection: string;
tid: string;
value: unknown;
} | {
action: 'delete';
collection: string;
tid: string;
})[];
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,23 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
type: string;
validate?: boolean;
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/json';
data: InputSchema;
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
uri: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,14 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
type: string;
tid: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
}

View File

@ -0,0 +1,20 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
nameOrDid: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
name: string;
did: string;
didDoc: {};
collections: string[];
nameIsCorrect: boolean;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,19 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
nameOrDid: string;
type: string;
tid: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
uri: string;
value: {};
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,24 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
nameOrDid: string;
type: string;
limit?: number;
before?: string;
after?: string;
reverse?: boolean;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
records: {
uri: string;
value: {};
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,24 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
type: string;
tid: string;
validate?: boolean;
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/json';
data: InputSchema;
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
uri: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,16 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
name: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
did: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,14 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
from?: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: Uint8Array;
}

View File

@ -0,0 +1,16 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
root: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,14 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/cbor';
data: Uint8Array;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
}

View File

@ -0,0 +1,16 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/json';
}
export interface InputSchema {
username: string;
did: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
}

View File

@ -0,0 +1,19 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,19 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,19 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,19 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,19 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
}
export interface CallOptions {
headers?: Headers;
encoding: '';
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,34 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
validate?: boolean;
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/json';
}
export interface InputSchema {
writes: ({
action: 'create';
collection: string;
value: unknown;
} | {
action: 'update';
collection: string;
tid: string;
value: unknown;
} | {
action: 'delete';
collection: string;
tid: string;
})[];
}
export interface OutputSchema {
[k: string]: unknown;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,22 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
type: string;
validate?: boolean;
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/json';
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
uri: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,15 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
type: string;
tid: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
}

View File

@ -0,0 +1,21 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
nameOrDid: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
name: string;
did: string;
didDoc: {};
collections: string[];
nameIsCorrect: boolean;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,20 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
nameOrDid: string;
type: string;
tid: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
uri: string;
value: {};
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,25 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
nameOrDid: string;
type: string;
limit?: number;
before?: string;
after?: string;
reverse?: boolean;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
records: {
uri: string;
value: {};
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,23 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
type: string;
tid: string;
validate?: boolean;
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/json';
}
export interface InputSchema {
[k: string]: unknown;
}
export interface OutputSchema {
uri: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,17 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
name?: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
did: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,15 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
from?: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: Uint8Array;
}

View File

@ -0,0 +1,17 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
root: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,14 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
did: string;
}
export interface CallOptions {
headers?: Headers;
encoding: 'application/cbor';
}
export declare type InputSchema = string | Uint8Array;
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
}

View File

@ -0,0 +1,23 @@
export interface Record {
assertion: InviteAssertion | EmployeeAssertion | TagAssertion | UnknownAssertion;
subject: string;
createdAt: string;
[k: string]: unknown;
}
export interface InviteAssertion {
type: 'invite';
[k: string]: unknown;
}
export interface EmployeeAssertion {
type: 'employee';
[k: string]: unknown;
}
export interface TagAssertion {
type: 'tag';
tag: string;
[k: string]: unknown;
}
export interface UnknownAssertion {
type: string;
[k: string]: unknown;
}

View File

@ -0,0 +1,5 @@
export interface Record {
subject: string;
createdAt: string;
[k: string]: unknown;
}

View File

@ -0,0 +1,54 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
author?: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
feed: FeedItem[];
}
export interface FeedItem {
uri: string;
author: User;
repostedBy?: User;
record: {};
embed?: RecordEmbed | ExternalEmbed | UnknownEmbed;
replyCount: number;
repostCount: number;
likeCount: number;
indexedAt: string;
myState?: {
repost?: string;
like?: string;
};
}
export interface User {
did: string;
name: string;
displayName?: string;
}
export interface RecordEmbed {
type: 'record';
author: User;
record: {};
}
export interface ExternalEmbed {
type: 'external';
uri: string;
title: string;
description: string;
imageUri: string;
}
export interface UnknownEmbed {
type: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,15 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
author?: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: Uint8Array;
}

View File

@ -0,0 +1,26 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
uri: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
uri: string;
likedBy: {
did: string;
name: string;
displayName?: string;
createdAt?: string;
indexedAt: string;
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,25 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
uri: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
uri: string;
likedBy: {
did: string;
name: string;
displayName?: string;
createdAt?: string;
indexedAt: string;
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,29 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
notifications: Notification[];
}
export interface Notification {
uri: string;
author: {
did: string;
name: string;
displayName: string;
};
record: {};
isRead: boolean;
indexedAt: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,28 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
notifications: Notification[];
}
export interface Notification {
uri: string;
author: {
did: string;
name: string;
displayName: string;
};
record: {};
isRead: boolean;
indexedAt: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,54 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
uri: string;
depth?: number;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
thread: Post;
}
export interface Post {
uri: string;
author: User;
record: {};
embed?: RecordEmbed | ExternalEmbed | UnknownEmbed;
parent?: Post;
replyCount: number;
replies?: Post[];
likeCount: number;
repostCount: number;
indexedAt: string;
myState?: {
repost?: string;
like?: string;
};
}
export interface User {
did: string;
name: string;
displayName?: string;
}
export interface RecordEmbed {
type: 'record';
author: User;
record: {};
}
export interface ExternalEmbed {
type: 'external';
uri: string;
title: string;
description: string;
imageUri: string;
}
export interface UnknownEmbed {
type: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,53 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
uri: string;
depth?: number;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
thread: Post;
}
export interface Post {
uri: string;
author: User;
record: {};
embed?: RecordEmbed | ExternalEmbed | UnknownEmbed;
parent?: Post;
replyCount: number;
replies?: Post[];
likeCount: number;
repostCount: number;
indexedAt: string;
myState?: {
repost?: string;
like?: string;
};
}
export interface User {
did: string;
name: string;
displayName?: string;
}
export interface RecordEmbed {
type: 'record';
author: User;
record: {};
}
export interface ExternalEmbed {
type: 'external';
uri: string;
title: string;
description: string;
imageUri: string;
}
export interface UnknownEmbed {
type: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,40 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
user: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
did: string;
name: string;
displayName?: string;
description?: string;
followersCount: number;
followsCount: number;
postsCount: number;
badges: Badge[];
myState?: {
follow?: string;
};
}
export interface Badge {
uri: string;
error?: string;
issuer?: {
did: string;
name: string;
displayName: string;
};
assertion?: {
type: string;
};
createdAt?: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,39 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
user: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
did: string;
name: string;
displayName?: string;
description?: string;
followersCount: number;
followsCount: number;
postsCount: number;
badges: Badge[];
myState?: {
follow?: string;
};
}
export interface Badge {
uri: string;
error?: string;
issuer?: {
did: string;
name: string;
displayName: string;
};
assertion?: {
type: string;
};
createdAt?: string;
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,26 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
uri: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
uri: string;
repostedBy: {
did: string;
name: string;
displayName?: string;
createdAt?: string;
indexedAt: string;
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,25 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
uri: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
uri: string;
repostedBy: {
did: string;
name: string;
displayName?: string;
createdAt?: string;
indexedAt: string;
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,30 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
user: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
subject: {
did: string;
name: string;
displayName?: string;
};
followers: {
did: string;
name: string;
displayName?: string;
createdAt?: string;
indexedAt: string;
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,29 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
user: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
subject: {
did: string;
name: string;
displayName?: string;
};
followers: {
did: string;
name: string;
displayName?: string;
createdAt?: string;
indexedAt: string;
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,30 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
user: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export declare type InputSchema = undefined;
export interface OutputSchema {
subject: {
did: string;
name: string;
displayName?: string;
};
follows: {
did: string;
name: string;
displayName?: string;
createdAt?: string;
indexedAt: string;
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,29 @@
import { Headers } from '@adxp/xrpc';
export interface QueryParams {
user: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export interface OutputSchema {
subject: {
did: string;
name: string;
displayName?: string;
};
follows: {
did: string;
name: string;
displayName?: string;
createdAt?: string;
indexedAt: string;
}[];
}
export interface Response {
success: boolean;
error: boolean;
headers: Headers;
data: OutputSchema;
}

View File

@ -0,0 +1,5 @@
export interface Record {
subject: string;
createdAt: string;
[k: string]: unknown;
}

View File

@ -0,0 +1,15 @@
export interface Record {
media: MediaEmbed[];
[k: string]: unknown;
}
export interface MediaEmbed {
alt?: string;
thumb?: MediaEmbedBlob;
original: MediaEmbedBlob;
[k: string]: unknown;
}
export interface MediaEmbedBlob {
mimeType: string;
blobId: string;
[k: string]: unknown;
}

View File

@ -0,0 +1,18 @@
export declare type TextSlice = [number, number];
export declare type Entity = {
index: TextSlice;
type: string;
value: string;
[k: string]: unknown;
}[];
export interface Record {
text: string;
entities?: Entity;
reply?: {
root: string;
parent?: string;
[k: string]: unknown;
};
createdAt: string;
[k: string]: unknown;
}

View File

@ -0,0 +1,10 @@
export interface Record {
displayName: string;
description?: string;
badges?: BadgeRef[];
[k: string]: unknown;
}
export interface BadgeRef {
uri: string;
[k: string]: unknown;
}

View File

@ -0,0 +1,5 @@
export interface Record {
subject: string;
createdAt: string;
[k: string]: unknown;
}

File diff suppressed because one or more lines are too long

136
src/third-party/uri/index.js vendored 100644
View File

@ -0,0 +1,136 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ADX_URI_REGEX: () => ADX_URI_REGEX,
AdxUri: () => AdxUri
});
module.exports = __toCommonJS(src_exports);
var ADX_URI_REGEX = /^(adx:\/\/)?((?:did:[a-z0-9:%-]+)|(?:[a-z][a-z0-9.:-]*))(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i;
var RELATIVE_REGEX = /^(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i;
var AdxUri = class {
constructor(uri, base) {
let parsed;
if (base) {
parsed = parse(base);
if (!parsed) {
throw new Error(`Invalid adx uri: ${base}`);
}
const relativep = parseRelative(uri);
if (!relativep) {
throw new Error(`Invalid path: ${uri}`);
}
Object.assign(parsed, relativep);
} else {
parsed = parse(uri);
if (!parsed) {
throw new Error(`Invalid adx uri: ${uri}`);
}
}
this.hash = parsed.hash;
this.host = parsed.host;
this.pathname = parsed.pathname;
this.searchParams = parsed.searchParams;
}
get protocol() {
return "adx:";
}
get origin() {
return `adx://${this.host}`;
}
get hostname() {
return this.host;
}
set hostname(v) {
this.host = v;
}
get search() {
return this.searchParams.toString();
}
set search(v) {
this.searchParams = new URLSearchParams(v);
}
get collection() {
return this.pathname.split("/").filter(Boolean)[0] || "";
}
set collection(v) {
const parts = this.pathname.split("/").filter(Boolean);
parts[0] = v;
this.pathname = parts.join("/");
}
get recordKey() {
return this.pathname.split("/").filter(Boolean)[1] || "";
}
set recordKey(v) {
const parts = this.pathname.split("/").filter(Boolean);
if (!parts[0])
parts[0] = "undefined";
parts[1] = v;
this.pathname = parts.join("/");
}
get href() {
return this.toString();
}
toString() {
let path = this.pathname || "/";
if (!path.startsWith("/")) {
path = `/${path}`;
}
let qs = this.searchParams.toString();
if (qs && !qs.startsWith("?")) {
qs = `?${qs}`;
}
let hash = this.hash;
if (hash && !hash.startsWith("#")) {
hash = `#${hash}`;
}
return `adx://${this.host}${path}${qs}${hash}`;
}
};
function parse(str) {
const match = ADX_URI_REGEX.exec(str);
if (match) {
return {
hash: match[5] || "",
host: match[2] || "",
pathname: match[3] || "",
searchParams: new URLSearchParams(match[4] || "")
};
}
return void 0;
}
function parseRelative(str) {
const match = RELATIVE_REGEX.exec(str);
if (match) {
return {
hash: match[3] || "",
pathname: match[1] || "",
searchParams: new URLSearchParams(match[2] || "")
};
}
return void 0;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ADX_URI_REGEX,
AdxUri
});
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/index.ts"],
"sourcesContent": ["export const ADX_URI_REGEX =\n // protocol- --did-------------- --name------------- --path---- --query-- --hash--\n /^(adx:\\/\\/)?((?:did:[a-z0-9:%-]+)|(?:[a-z][a-z0-9.:-]*))(\\/[^?#\\s]*)?(\\?[^#\\s]+)?(#[^\\s]+)?$/i\n// --path----- --query-- --hash--\nconst RELATIVE_REGEX = /^(\\/[^?#\\s]*)?(\\?[^#\\s]+)?(#[^\\s]+)?$/i\n\nexport class AdxUri {\n hash: string\n host: string\n pathname: string\n searchParams: URLSearchParams\n\n constructor(uri: string, base?: string) {\n let parsed\n if (base) {\n parsed = parse(base)\n if (!parsed) {\n throw new Error(`Invalid adx uri: ${base}`)\n }\n const relativep = parseRelative(uri)\n if (!relativep) {\n throw new Error(`Invalid path: ${uri}`)\n }\n Object.assign(parsed, relativep)\n } else {\n parsed = parse(uri)\n if (!parsed) {\n throw new Error(`Invalid adx uri: ${uri}`)\n }\n }\n\n this.hash = parsed.hash\n this.host = parsed.host\n this.pathname = parsed.pathname\n this.searchParams = parsed.searchParams\n }\n\n get protocol() {\n return 'adx:'\n }\n\n get origin() {\n return `adx://${this.host}`\n }\n\n get hostname() {\n return this.host\n }\n\n set hostname(v: string) {\n this.host = v\n }\n\n get search() {\n return this.searchParams.toString()\n }\n\n set search(v: string) {\n this.searchParams = new URLSearchParams(v)\n }\n\n get collection() {\n return this.pathname.split('/').filter(Boolean)[0] || ''\n }\n\n set collection(v: string) {\n const parts = this.pathname.split('/').filter(Boolean)\n parts[0] = v\n this.pathname = parts.join('/')\n }\n\n get recordKey() {\n return this.pathname.split('/').filter(Boolean)[1] || ''\n }\n\n set recordKey(v: string) {\n const parts = this.pathname.split('/').filter(Boolean)\n if (!parts[0]) parts[0] = 'undefined'\n parts[1] = v\n this.pathname = parts.join('/')\n }\n\n get href() {\n return this.toString()\n }\n\n toString() {\n let path = this.pathname || '/'\n if (!path.startsWith('/')) {\n path = `/${path}`\n }\n let qs = this.searchParams.toString()\n if (qs && !qs.startsWith('?')) {\n qs = `?${qs}`\n }\n let hash = this.hash\n if (hash && !hash.startsWith('#')) {\n hash = `#${hash}`\n }\n return `adx://${this.host}${path}${qs}${hash}`\n }\n}\n\nfunction parse(str: string) {\n const match = ADX_URI_REGEX.exec(str)\n if (match) {\n return {\n hash: match[5] || '',\n host: match[2] || '',\n pathname: match[3] || '',\n searchParams: new URLSearchParams(match[4] || ''),\n }\n }\n return undefined\n}\n\nfunction parseRelative(str: string) {\n const match = RELATIVE_REGEX.exec(str)\n if (match) {\n return {\n hash: match[3] || '',\n pathname: match[1] || '',\n searchParams: new URLSearchParams(match[2] || ''),\n }\n }\n return undefined\n}\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,gBAEX;AAEF,IAAM,iBAAiB;AAEhB,IAAM,SAAN,MAAa;AAAA,EAMlB,YAAY,KAAa,MAAe;AACtC,QAAI;AACJ,QAAI,MAAM;AACR,eAAS,MAAM,IAAI;AACnB,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,oBAAoB,MAAM;AAAA,MAC5C;AACA,YAAM,YAAY,cAAc,GAAG;AACnC,UAAI,CAAC,WAAW;AACd,cAAM,IAAI,MAAM,iBAAiB,KAAK;AAAA,MACxC;AACA,aAAO,OAAO,QAAQ,SAAS;AAAA,IACjC,OAAO;AACL,eAAS,MAAM,GAAG;AAClB,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,oBAAoB,KAAK;AAAA,MAC3C;AAAA,IACF;AAEA,SAAK,OAAO,OAAO;AACnB,SAAK,OAAO,OAAO;AACnB,SAAK,WAAW,OAAO;AACvB,SAAK,eAAe,OAAO;AAAA,EAC7B;AAAA,EAEA,IAAI,WAAW;AACb,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EAEA,IAAI,WAAW;AACb,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAS,GAAW;AACtB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK,aAAa,SAAS;AAAA,EACpC;AAAA,EAEA,IAAI,OAAO,GAAW;AACpB,SAAK,eAAe,IAAI,gBAAgB,CAAC;AAAA,EAC3C;AAAA,EAEA,IAAI,aAAa;AACf,WAAO,KAAK,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,MAAM;AAAA,EACxD;AAAA,EAEA,IAAI,WAAW,GAAW;AACxB,UAAM,QAAQ,KAAK,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACrD,UAAM,KAAK;AACX,SAAK,WAAW,MAAM,KAAK,GAAG;AAAA,EAChC;AAAA,EAEA,IAAI,YAAY;AACd,WAAO,KAAK,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,MAAM;AAAA,EACxD;AAAA,EAEA,IAAI,UAAU,GAAW;AACvB,UAAM,QAAQ,KAAK,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACrD,QAAI,CAAC,MAAM;AAAI,YAAM,KAAK;AAC1B,UAAM,KAAK;AACX,SAAK,WAAW,MAAM,KAAK,GAAG;AAAA,EAChC;AAAA,EAEA,IAAI,OAAO;AACT,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,WAAW;AACT,QAAI,OAAO,KAAK,YAAY;AAC5B,QAAI,CAAC,KAAK,WAAW,GAAG,GAAG;AACzB,aAAO,IAAI;AAAA,IACb;AACA,QAAI,KAAK,KAAK,aAAa,SAAS;AACpC,QAAI,MAAM,CAAC,GAAG,WAAW,GAAG,GAAG;AAC7B,WAAK,IAAI;AAAA,IACX;AACA,QAAI,OAAO,KAAK;AAChB,QAAI,QAAQ,CAAC,KAAK,WAAW,GAAG,GAAG;AACjC,aAAO,IAAI;AAAA,IACb;AACA,WAAO,SAAS,KAAK,OAAO,OAAO,KAAK;AAAA,EAC1C;AACF;AAEA,SAAS,MAAM,KAAa;AAC1B,QAAM,QAAQ,cAAc,KAAK,GAAG;AACpC,MAAI,OAAO;AACT,WAAO;AAAA,MACL,MAAM,MAAM,MAAM;AAAA,MAClB,MAAM,MAAM,MAAM;AAAA,MAClB,UAAU,MAAM,MAAM;AAAA,MACtB,cAAc,IAAI,gBAAgB,MAAM,MAAM,EAAE;AAAA,IAClD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,cAAc,KAAa;AAClC,QAAM,QAAQ,eAAe,KAAK,GAAG;AACrC,MAAI,OAAO;AACT,WAAO;AAAA,MACL,MAAM,MAAM,MAAM;AAAA,MAClB,UAAU,MAAM,MAAM;AAAA,MACtB,cAAc,IAAI,gBAAgB,MAAM,MAAM,EAAE;AAAA,IAClD;AAAA,EACF;AACA,SAAO;AACT;",
"names": []
}

View File

@ -0,0 +1,20 @@
export declare const ADX_URI_REGEX: RegExp;
export declare class AdxUri {
hash: string;
host: string;
pathname: string;
searchParams: URLSearchParams;
constructor(uri: string, base?: string);
get protocol(): string;
get origin(): string;
get hostname(): string;
set hostname(v: string);
get search(): string;
set search(v: string);
get collection(): string;
set collection(v: string);
get recordKey(): string;
set recordKey(v: string);
get href(): string;
toString(): string;
}

File diff suppressed because one or more lines are too long

View File

@ -15,7 +15,7 @@ const WARNING_TEXT_LENGTH = 200
const DANGER_TEXT_LENGTH = 255
export const snapPoints = ['100%']
const DEBUG_USERNAMES = ['alice.com', 'bob.com', 'carla.com']
const DEBUG_USERNAMES = ['alice.test', 'bob.test', 'carol.test']
export function Component({replyTo}: {replyTo?: string}) {
const store = useStores()
@ -48,7 +48,7 @@ export function Component({replyTo}: {replyTo?: string}) {
return false
}
try {
await apilib.post(store.api, 'alice.com', text, replyTo)
await apilib.post(store.api, 'alice.test', text, replyTo)
} catch (e: any) {
console.error(`Failed to create post: ${e.toString()}`)
setError(

View File

@ -1,7 +1,7 @@
import React, {useMemo} from 'react'
import {observer} from 'mobx-react-lite'
import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native'
import {AdxUri} from '@adxp/mock-api'
import {Image, StyleSheet, Text, View} from 'react-native'
import {AdxUri} from '../../../third-party/uri'
import {FontAwesomeIcon, Props} from '@fortawesome/react-native-fontawesome'
import {NotificationsViewItemModel} from '../../../state/models/notifications-view'
import {s, colors} from '../../lib/styles'
@ -64,7 +64,7 @@ export const FeedItem = observer(function FeedItem({
<Link style={styles.layoutAvi} href={authorHref} title={authorTitle}>
<Image
style={styles.avi}
source={AVIS[item.author.name] || AVIS['alice.com']}
source={AVIS[item.author.name] || AVIS['alice.test']}
/>
</Link>
<View style={styles.layoutContent}>

View File

@ -80,7 +80,7 @@ const LikedByItem = ({item}: {item: LikedByViewItemModel}) => {
<View style={styles.layoutAvi}>
<Image
style={styles.avi}
source={AVIS[item.name] || AVIS['alice.com']}
source={AVIS[item.name] || AVIS['alice.test']}
/>
</View>
<View style={styles.layoutContent}>

View File

@ -86,7 +86,7 @@ const RepostedByItem = ({item}: {item: RepostedByViewItemModel}) => {
<View style={styles.layoutAvi}>
<Image
style={styles.avi}
source={AVIS[item.name] || AVIS['alice.com']}
source={AVIS[item.name] || AVIS['alice.test']}
/>
</View>
<View style={styles.layoutContent}>

View File

@ -1,7 +1,8 @@
import React, {useMemo} from 'react'
import {observer} from 'mobx-react-lite'
import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native'
import {bsky, AdxUri} from '@adxp/mock-api'
import {AdxUri} from '../../../third-party/uri'
import * as PostType from '../../../third-party/api/src/types/todo/social/post'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {PostThreadViewPostModel} from '../../../state/models/post-thread-view'
import {ComposePostModel} from '../../../state/models/shell'
@ -20,7 +21,7 @@ export const PostThreadItem = observer(function PostThreadItem({
onPressShare: (_uri: string) => void
}) {
const store = useStores()
const record = item.record as unknown as bsky.Post.Record
const record = item.record as unknown as PostType.Record
const hasEngagement = item.likeCount || item.repostCount
const itemHref = useMemo(() => {
@ -68,23 +69,22 @@ export const PostThreadItem = observer(function PostThreadItem({
<TouchableOpacity style={styles.ctrl} onPress={onPressToggleRepost}>
<FontAwesomeIcon
style={
item.myState.hasReposted ? styles.ctrlIconReposted : styles.ctrlIcon
item.myState.repost ? styles.ctrlIconReposted : styles.ctrlIcon
}
icon="retweet"
size={18}
/>
<Text
style={item.myState.hasReposted ? [s.bold, s.green3, s.f13] : s.f13}>
<Text style={item.myState.repost ? [s.bold, s.green3, s.f13] : s.f13}>
{item.repostCount}
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.ctrl} onPress={onPressToggleLike}>
<FontAwesomeIcon
style={item.myState.hasLiked ? styles.ctrlIconLiked : styles.ctrlIcon}
icon={[item.myState.hasLiked ? 'fas' : 'far', 'heart']}
style={item.myState.like ? styles.ctrlIconLiked : styles.ctrlIcon}
icon={[item.myState.like ? 'fas' : 'far', 'heart']}
size={14}
/>
<Text style={item.myState.hasLiked ? [s.bold, s.red3, s.f13] : s.f13}>
<Text style={item.myState.like ? [s.bold, s.red3, s.f13] : s.f13}>
{item.likeCount}
</Text>
</TouchableOpacity>
@ -107,7 +107,7 @@ export const PostThreadItem = observer(function PostThreadItem({
<Link style={styles.layoutAvi} href={authorHref} title={authorTitle}>
<Image
style={styles.avi}
source={AVIS[item.author.name] || AVIS['alice.com']}
source={AVIS[item.author.name] || AVIS['alice.test']}
/>
</Link>
<View style={styles.layoutContent}>
@ -192,7 +192,7 @@ export const PostThreadItem = observer(function PostThreadItem({
<Link style={styles.layoutAvi} href={authorHref} title={authorTitle}>
<Image
style={styles.avi}
source={AVIS[item.author.name] || AVIS['alice.com']}
source={AVIS[item.author.name] || AVIS['alice.test']}
/>
</Link>
<View style={styles.layoutContent}>

View File

@ -1,6 +1,7 @@
import React, {useState, useEffect} from 'react'
import React, {useState, useEffect, useMemo} from 'react'
import {observer} from 'mobx-react-lite'
import {bsky, AdxUri} from '@adxp/mock-api'
import {AdxUri} from '../../../third-party/uri'
import * as PostType from '../../../third-party/api/src/types/todo/social/post'
import {
ActivityIndicator,
Image,
@ -54,7 +55,7 @@ export const Post = observer(function Post({uri}: {uri: string}) {
// loaded
// =
const item = view.thread
const record = view.thread?.record as unknown as bsky.Post.Record
const record = view.thread?.record as unknown as PostType.Record
const itemHref = useMemo(() => {
const urip = new AdxUri(item.uri)
@ -83,7 +84,7 @@ export const Post = observer(function Post({uri}: {uri: string}) {
<Link style={styles.layoutAvi} href={authorHref} title={authorTitle}>
<Image
style={styles.avi}
source={AVIS[item.author.name] || AVIS['alice.com']}
source={AVIS[item.author.name] || AVIS['alice.test']}
/>
</Link>
<View style={styles.layoutContent}>
@ -112,7 +113,7 @@ export const Post = observer(function Post({uri}: {uri: string}) {
<TouchableOpacity style={styles.ctrl} onPress={onPressToggleRepost}>
<FontAwesomeIcon
style={
item.myState.hasReposted
item.myState.repost
? styles.ctrlIconReposted
: styles.ctrlIcon
}
@ -120,21 +121,18 @@ export const Post = observer(function Post({uri}: {uri: string}) {
size={22}
/>
<Text
style={
item.myState.hasReposted ? [s.bold, s.green3] : undefined
}>
style={item.myState.repost ? [s.bold, s.green3] : undefined}>
{item.repostCount}
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.ctrl} onPress={onPressToggleLike}>
<FontAwesomeIcon
style={
item.myState.hasLiked ? styles.ctrlIconLiked : styles.ctrlIcon
item.myState.like ? styles.ctrlIconLiked : styles.ctrlIcon
}
icon={[item.myState.hasLiked ? 'fas' : 'far', 'heart']}
icon={[item.myState.like ? 'fas' : 'far', 'heart']}
/>
<Text
style={item.myState.hasLiked ? [s.bold, s.red3] : undefined}>
<Text style={item.myState.like ? [s.bold, s.red3] : undefined}>
{item.likeCount}
</Text>
</TouchableOpacity>

View File

@ -26,7 +26,7 @@ export const Feed = observer(function Feed({feed}: {feed: FeedViewModel}) {
{feed.isLoading && !feed.isRefreshing && !feed.hasContent && (
<Text>Loading...</Text>
)}
{feed.hasError && <Text>{feed.error}</Text>}
{feed.hasError && <Text>{feed.errorStr}</Text>}
{feed.hasContent && (
<FlatList
data={feed.feed.slice()}

View File

@ -1,7 +1,8 @@
import React, {useMemo} from 'react'
import {observer} from 'mobx-react-lite'
import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native'
import {bsky, AdxUri} from '@adxp/mock-api'
import {AdxUri} from '../../../third-party/uri'
import * as PostType from '../../../third-party/api/src/types/todo/social/post'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {FeedViewItemModel} from '../../../state/models/feed-view'
import {ComposePostModel, SharePostModel} from '../../../state/models/shell'
@ -18,7 +19,7 @@ export const FeedItem = observer(function FeedItem({
item: FeedViewItemModel
}) {
const store = useStores()
const record = item.record as unknown as bsky.Post.Record
const record = item.record as unknown as PostType.Record
const itemHref = useMemo(() => {
const urip = new AdxUri(item.uri)
return `/profile/${item.author.name}/post/${urip.recordKey}`
@ -60,7 +61,7 @@ export const FeedItem = observer(function FeedItem({
title={item.author.name}>
<Image
style={styles.avi}
source={AVIS[item.author.name] || AVIS['alice.com']}
source={AVIS[item.author.name] || AVIS['alice.test']}
/>
</Link>
<View style={styles.layoutContent}>
@ -107,7 +108,7 @@ export const FeedItem = observer(function FeedItem({
<TouchableOpacity style={styles.ctrl} onPress={onPressToggleRepost}>
<FontAwesomeIcon
style={
item.myState.hasReposted
item.myState.repost
? styles.ctrlIconReposted
: styles.ctrlIcon
}
@ -115,22 +116,19 @@ export const FeedItem = observer(function FeedItem({
size={18}
/>
<Text
style={
item.myState.hasReposted ? [s.bold, s.green3, s.f13] : s.f13
}>
style={item.myState.repost ? [s.bold, s.green3, s.f13] : s.f13}>
{item.repostCount}
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.ctrl} onPress={onPressToggleLike}>
<FontAwesomeIcon
style={
item.myState.hasLiked ? styles.ctrlIconLiked : styles.ctrlIcon
item.myState.like ? styles.ctrlIconLiked : styles.ctrlIcon
}
icon={[item.myState.hasLiked ? 'fas' : 'far', 'heart']}
icon={[item.myState.like ? 'fas' : 'far', 'heart']}
size={14}
/>
<Text
style={item.myState.hasLiked ? [s.bold, s.red3, s.f13] : s.f13}>
<Text style={item.myState.like ? [s.bold, s.red3, s.f13] : s.f13}>
{item.likeCount}
</Text>
</TouchableOpacity>

Some files were not shown because too many files have changed in this diff Show More