diff --git a/js/app/.env b/js/app/.env
index 8d95a5e50..e69de29bb 100644
--- a/js/app/.env
+++ b/js/app/.env
@@ -1 +0,0 @@
-EXPO_USE_METRO_WORKSPACE_ROOT=1
diff --git a/js/app/.env.development b/js/app/.env.development
index 9d84e2733..fa76d7d8b 100644
--- a/js/app/.env.development
+++ b/js/app/.env.development
@@ -1,3 +1,2 @@
EXPO_PUBLIC_STREAMPLACE_URL=http://127.0.0.1:38080
-EXPO_PUBLIC_WEB_TRY_LOCAL=true
-EXPO_USE_METRO_WORKSPACE_ROOT=1
\ No newline at end of file
+EXPO_PUBLIC_WEB_TRY_LOCAL=true
\ No newline at end of file
diff --git a/js/app/.env.production b/js/app/.env.production
index 10b6b71c8..511b7dcb4 100644
--- a/js/app/.env.production
+++ b/js/app/.env.production
@@ -1,3 +1,2 @@
EXPO_PUBLIC_STREAMPLACE_URL=https://stream.place
-EXPO_PUBLIC_WEB_TRY_LOCAL=true
-EXPO_USE_METRO_WORKSPACE_ROOT=0
\ No newline at end of file
+EXPO_PUBLIC_WEB_TRY_LOCAL=true
\ No newline at end of file
diff --git a/js/app/components/chat/chat.tsx b/js/app/components/chat/chat.tsx
index 2f25f9a88..b8421541a 100644
--- a/js/app/components/chat/chat.tsx
+++ b/js/app/components/chat/chat.tsx
@@ -17,6 +17,7 @@ import usePlatform from "hooks/usePlatform";
import { Button, ScrollView, Sheet, Text, useMedia, View } from "tamagui";
import { RichText } from "@atproto/api";
import { ReactElement } from "react";
+import { isMention } from "@atproto/api/dist/client/types/app/bsky/richtext/facet";
export default function Chat({
isChatVisible,
@@ -343,7 +344,7 @@ const ChatMessageText = ({
// Process facets to add DID information for mentions
rt.facets?.forEach((facet) => {
facet.features.forEach((feature) => {
- if (feature.$type === "app.bsky.richtext.facet#mention") {
+ if (isMention(feature)) {
const mentionText = message.record.text.slice(
facet.index.byteStart,
facet.index.byteEnd,
diff --git a/js/app/features/bluesky/agent.tsx b/js/app/features/bluesky/agent.tsx
new file mode 100644
index 000000000..6570fcc48
--- /dev/null
+++ b/js/app/features/bluesky/agent.tsx
@@ -0,0 +1,20 @@
+import { Agent } from "@atproto/api";
+import { SessionManager } from "@atproto/api/dist/session-manager";
+import { PlaceNS } from "lexicons";
+import { schemas as parentSchemas } from "@atproto/api/dist/client/lexicons";
+import { schemas as appSchemas } from "../../lexicons/lexicons";
+import { Lexicons } from "@atproto/lexicon";
+export class StreamplaceAgent extends Agent {
+ place = new PlaceNS(this);
+ lex: Lexicons;
+
+ constructor(options: string | URL | SessionManager) {
+ super(options);
+
+ const streamplaceSchemas = appSchemas.filter((x) =>
+ x.id.startsWith("place.stream"),
+ );
+
+ this.lex = new Lexicons([...parentSchemas, ...streamplaceSchemas]);
+ }
+}
diff --git a/js/app/features/bluesky/blueskySlice.tsx b/js/app/features/bluesky/blueskySlice.tsx
index c5dea03d7..cb2d47933 100644
--- a/js/app/features/bluesky/blueskySlice.tsx
+++ b/js/app/features/bluesky/blueskySlice.tsx
@@ -5,7 +5,7 @@ import {
BlobRef,
RichText,
} from "@atproto/api";
-import { ProfileViewDetailed } from "@atproto/api/src/client/types/app/bsky/actor/defs";
+import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs";
import { bytesToMultibase, Secp256k1Keypair } from "@atproto/crypto";
import { hydrate, STORED_KEY_KEY } from "features/base/baseSlice";
import { openLoginLink } from "features/platform/platformSlice";
@@ -26,6 +26,11 @@ import { privateKeyToAccount } from "viem/accounts";
import { createAppSlice } from "../../hooks/createSlice";
import { BlueskyState } from "./blueskyTypes";
import createOAuthClient from "./oauthClient";
+import { StreamplaceAgent } from "./agent";
+import {
+ isLink,
+ isMention,
+} from "@atproto/api/dist/client/types/app/bsky/richtext/facet";
const initialState: BlueskyState = {
status: "start",
@@ -125,7 +130,7 @@ export const blueskySlice = createAppSlice({
...state,
client: client,
oauthSession: initResult.session as any,
- pdsAgent: new Agent(initResult.session),
+ pdsAgent: new StreamplaceAgent(initResult.session),
};
}
return {
@@ -429,6 +434,7 @@ export const blueskySlice = createAppSlice({
},
];
const record: AppBskyFeedPost.Record = {
+ $type: "app.bsky.feed.post",
text: content,
"place.stream.livestream": {
url: linkUrl,
@@ -490,6 +496,7 @@ export const blueskySlice = createAppSlice({
throw new Error("No post");
}
const record: AppBskyFeedPost.Record = {
+ $type: "app.bsky.feed.post",
text: text,
createdAt: new Date().toISOString(),
reply: {
@@ -537,6 +544,7 @@ export const blueskySlice = createAppSlice({
throw new Error("No profile");
}
const record: AppBskyGraphBlock.Record = {
+ $type: "app.bsky.graph.block",
subject: subjectDID,
createdAt: new Date().toISOString(),
};
@@ -621,16 +629,18 @@ export const blueskySlice = createAppSlice({
feature.$type === "app.bsky.richtext.facet#mention",
)
.map((feature) => {
- if (feature.$type === "app.bsky.richtext.facet#link") {
+ if (isLink(feature)) {
return {
$type: "app.bsky.richtext.facet#link",
uri: feature.uri,
};
- } else {
+ } else if (isMention(feature)) {
return {
$type: "app.bsky.richtext.facet#mention",
did: feature.did,
};
+ } else {
+ throw new Error("invalid code path");
}
}),
})),
@@ -960,10 +970,7 @@ export const blueskySlice = createAppSlice({
if (!res.success) {
throw new Error("Failed to create chat profile record");
}
- if (PlaceStreamChatProfile.isRecord(res.data.value)) {
- return res.data.value;
- }
- return null;
+ return chatProfile;
},
{
pending: (state) => {
diff --git a/js/app/features/bluesky/blueskyTypes.tsx b/js/app/features/bluesky/blueskyTypes.tsx
index 2d98037a4..3662d1d1b 100644
--- a/js/app/features/bluesky/blueskyTypes.tsx
+++ b/js/app/features/bluesky/blueskyTypes.tsx
@@ -1,9 +1,9 @@
import { OAuthSession } from "@streamplace/atproto-oauth-client-react-native";
-import { Agent } from "@atproto/api";
import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs";
import { StreamKey } from "features/base/baseSlice";
import { PlaceStreamChatProfile, PlaceStreamLivestream } from "lexicons";
import { StreamplaceOAuthClient } from "./oauthClient";
+import { StreamplaceAgent } from "./agent";
type NewLivestream = {
loading: boolean;
@@ -15,7 +15,7 @@ export interface BlueskyState {
status: "start" | "loggedIn" | "loggedOut";
oauthState: null | string;
oauthSession: null | OAuthSession;
- pdsAgent: null | Agent;
+ pdsAgent: null | StreamplaceAgent;
profiles: { [key: string]: ProfileViewDetailed };
client: null | StreamplaceOAuthClient;
login: {
diff --git a/js/app/features/streamplace/streamplaceSlice.tsx b/js/app/features/streamplace/streamplaceSlice.tsx
index 317b4e5c9..e979f591d 100644
--- a/js/app/features/streamplace/streamplaceSlice.tsx
+++ b/js/app/features/streamplace/streamplaceSlice.tsx
@@ -1,6 +1,8 @@
import { isWeb } from "tamagui";
import { createAppSlice } from "../../hooks/createSlice";
import Storage from "../../storage";
+import { BlueskyState } from "features/bluesky/blueskyTypes";
+import { SegmentView } from "lexicons/types/place/stream/segment";
let DEFAULT_URL = process.env.EXPO_PUBLIC_STREAMPLACE_URL as string;
if (isWeb && process.env.EXPO_PUBLIC_WEB_TRY_LOCAL === "true") {
@@ -45,6 +47,7 @@ export interface StreamplaceState {
loading: boolean;
firstRequest: boolean;
};
+ mySegments: SegmentView[];
telemetry: boolean | null;
userMuted: boolean | null;
chatWarned: boolean;
@@ -60,6 +63,7 @@ const initialState: StreamplaceState = {
loading: false,
firstRequest: true,
},
+ mySegments: [],
telemetry: null,
userMuted: null,
chatWarned: false,
@@ -237,6 +241,7 @@ export const streamplaceSlice = createAppSlice({
};
},
rejected: (state, err) => {
+ console.error("pollSegments rejected", err);
return {
...state,
recentSegments: {
@@ -248,12 +253,50 @@ export const streamplaceSlice = createAppSlice({
},
},
),
+
+ pollMySegments: create.asyncThunk(
+ async (_, { getState, dispatch }) => {
+ const { streamplace } = getState() as {
+ streamplace: StreamplaceState;
+ };
+ const { bluesky } = getState() as {
+ bluesky: BlueskyState;
+ };
+
+ if (!bluesky.pdsAgent) {
+ throw new Error("no pdsAgent");
+ }
+ return await bluesky.pdsAgent.place.stream.live.getSegments({
+ userDID: bluesky.oauthSession?.did,
+ });
+ },
+ {
+ pending: (state) => {
+ return {
+ ...state,
+ };
+ },
+ fulfilled: (state, action) => {
+ return {
+ ...state,
+ mySegments: action.payload.data.segments ?? [],
+ };
+ },
+ rejected: (state, err) => {
+ console.error("pollMySegments rejected", err);
+ return {
+ ...state,
+ };
+ },
+ },
+ ),
}),
selectors: {
selectStreamplace: (streamplace) => streamplace,
selectUrl: (streamplace) => streamplace.url,
selectRecentSegments: (streamplace) => streamplace.recentSegments,
+ selectMySegments: (streamplace) => streamplace.mySegments,
selectTelemetry: (streamplace) => streamplace.telemetry,
selectUserMuted: (streamplace) => streamplace.userMuted,
selectChatWarned: (streamplace) => streamplace.chatWarned,
@@ -266,6 +309,7 @@ export const {
setURL,
initialize,
pollSegments,
+ pollMySegments,
telemetryOpt,
userMute,
chatWarn,
@@ -273,6 +317,7 @@ export const {
export const {
selectStreamplace,
selectRecentSegments,
+ selectMySegments,
selectTelemetry,
selectUserMuted,
selectChatWarned,
diff --git a/js/app/hooks/useLiveUser.tsx b/js/app/hooks/useLiveUser.tsx
index 2c8815cc0..5dd310e91 100644
--- a/js/app/hooks/useLiveUser.tsx
+++ b/js/app/hooks/useLiveUser.tsx
@@ -1,16 +1,20 @@
-import { selectUserProfile } from "features/bluesky/blueskySlice";
-import { selectRecentSegments } from "features/streamplace/streamplaceSlice";
+import { selectMySegments } from "features/streamplace/streamplaceSlice";
+import { isRecord } from "lexicons/types/place/stream/segment";
import { useAppSelector } from "store/hooks";
+import { PlaceStreamSegment } from "lexicons";
// composite selector that tells us when the current user is live
export const useLiveUser = (): boolean => {
- const profile = useAppSelector(selectUserProfile);
- const { segments } = useAppSelector(selectRecentSegments);
- if (!profile) {
+ const mySegments = useAppSelector(selectMySegments);
+ if (mySegments.length === 0) {
return false;
}
- const isLive = segments.some(
- (segment) => segment.repo && segment.repo.did === profile.did,
- );
- return isLive;
+ if (!isRecord(mySegments[0].record)) {
+ return false;
+ }
+ const record = mySegments[0].record as PlaceStreamSegment.Record;
+ if (Date.now() - new Date(record.startTime).getTime() < 1000 * 10) {
+ return true;
+ }
+ return false;
};
diff --git a/js/app/package.json b/js/app/package.json
index 56fb63906..21cb890ea 100644
--- a/js/app/package.json
+++ b/js/app/package.json
@@ -26,9 +26,12 @@
},
"dependencies": {
"@atproto-labs/pipe": "^0.1.0",
- "@atproto/crypto": "^0.4.2",
- "@atproto/jwk-jose": "^0.1.2",
- "@atproto/oauth-client": "^0.3.1",
+ "@atproto/api": "^0.15.7",
+ "@atproto/crypto": "^0.4.4",
+ "@atproto/jwk-jose": "^0.1.6",
+ "@atproto/jwk-webcrypto": "^0.1.6",
+ "@atproto/oauth-client": "^0.3.16",
+ "@atproto/oauth-client-browser": "^0.3.16",
"@bacons/text-decoder": "^0.0.0",
"@emoji-mart/react": "^1.1.1",
"@rainbow-me/rainbowkit": "2.2.0",
diff --git a/js/app/src/router.tsx b/js/app/src/router.tsx
index 9e2b2f6d1..4d3b7f84c 100644
--- a/js/app/src/router.tsx
+++ b/js/app/src/router.tsx
@@ -32,7 +32,6 @@ import {
import { Provider, Settings } from "components";
import AQLink from "components/aqlink";
import Login from "components/login/login";
-import StreamList from "components/stream-list/stream-list";
import { selectUserProfile } from "features/bluesky/blueskySlice";
import usePlatform from "hooks/usePlatform";
import { ReactElement, useEffect, useState } from "react";
@@ -45,7 +44,7 @@ import {
StatusBar,
} from "react-native";
import { useAppDispatch, useAppSelector } from "store/hooks";
-import { useTheme, Text, View, H3, useWindowDimensions } from "tamagui";
+import { useTheme, Text, View, H3 } from "tamagui";
import AppReturnScreen from "./screens/app-return";
import MultiScreen from "./screens/multi";
import StreamScreen from "./screens/stream";
@@ -61,7 +60,10 @@ import {
selectNotificationDestination,
selectNotificationToken,
} from "features/platform/platformSlice.native";
-import { pollSegments } from "features/streamplace/streamplaceSlice";
+import {
+ pollMySegments,
+ pollSegments,
+} from "features/streamplace/streamplaceSlice";
import { useLiveUser } from "hooks/useLiveUser";
import { useToastController } from "@tamagui/toast";
import LiveDashboard from "./screens/live-dashboard";
@@ -74,6 +76,7 @@ import Sidebar, { ExternalDrawerItem } from "components/sidebar/sidebar";
// probabl should move this
import { store } from "store/store";
import { loadStateFromStorage } from "features/base/sidebarSlice";
+import StreamList from "components/stream-list/stream-list";
store.dispatch(loadStateFromStorage());
@@ -311,8 +314,10 @@ export function StreamplaceDrawer() {
// Top-level stuff to handle polling for live streamers
useEffect(() => {
dispatch(pollSegments());
+ dispatch(pollMySegments());
const interval = setInterval(() => {
dispatch(pollSegments());
+ dispatch(pollMySegments());
}, 5000);
return () => clearInterval(interval);
}, []);
diff --git a/js/atproto-oauth-client-react-native/package.json b/js/atproto-oauth-client-react-native/package.json
index 63619c3be..da1f31bfb 100644
--- a/js/atproto-oauth-client-react-native/package.json
+++ b/js/atproto-oauth-client-react-native/package.json
@@ -28,17 +28,17 @@
"dist"
],
"dependencies": {
- "@atproto-labs/did-resolver": "0.1.5",
- "@atproto-labs/handle-resolver-node": "0.1.7",
- "@atproto-labs/simple-store": "0.1.1",
- "@atproto-labs/simple-store-memory": "0.1.1",
- "@atproto/did": "0.1.3",
- "@atproto/jwk": "0.1.1",
- "@atproto/jwk-jose": "0.1.2",
- "@atproto/jwk-webcrypto": "0.1.2",
- "@atproto/oauth-client": "0.3.2",
- "@atproto/oauth-client-browser": "0.3.2",
- "@atproto/oauth-types": "0.2.1",
+ "@atproto-labs/did-resolver": "0.1.12",
+ "@atproto-labs/handle-resolver-node": "0.1.15",
+ "@atproto-labs/simple-store": "0.2.0",
+ "@atproto-labs/simple-store-memory": "0.1.3",
+ "@atproto/did": "0.1.5",
+ "@atproto/jwk": "0.1.5",
+ "@atproto/jwk-jose": "0.1.6",
+ "@atproto/jwk-webcrypto": "0.1.6",
+ "@atproto/oauth-client": "0.3.16",
+ "@atproto/oauth-client-browser": "0.3.16",
+ "@atproto/oauth-types": "0.2.7",
"abortcontroller-polyfill": "^1.7.6",
"event-target-shim": "^6.0.2",
"expo-sqlite": "^15.0.3",
diff --git a/js/desktop/package.json b/js/desktop/package.json
index 1506882b4..89c695e64 100644
--- a/js/desktop/package.json
+++ b/js/desktop/package.json
@@ -48,7 +48,7 @@
},
"license": "MIT",
"dependencies": {
- "@atproto/crypto": "^0.4.3",
+ "@atproto/crypto": "^0.4.4",
"electron-squirrel-startup": "^1.0.1",
"source-map-support": "^0.5.21",
"update-electron-app": "^3.0.0",
diff --git a/js/docs/src/content/docs/lex-reference/live/place-stream-live-getsegments.md b/js/docs/src/content/docs/lex-reference/live/place-stream-live-getsegments.md
new file mode 100644
index 000000000..33d6e456e
--- /dev/null
+++ b/js/docs/src/content/docs/lex-reference/live/place-stream-live-getsegments.md
@@ -0,0 +1,88 @@
+---
+title: place.stream.live.getSegments
+description: Reference for the place.stream.live.getSegments lexicon
+---
+
+**Lexicon Version:** 1
+
+## Definitions
+
+
+
+### `main`
+
+**Type:** `query`
+
+Get a list of livestream segments for a user
+
+**Parameters:**
+
+| Name | Type | Req'd | Description | Constraints |
+| --------- | --------- | ----- | ----------------------------------------- | ------------------------------------- |
+| `userDID` | `string` | ✅ | The DID of the potentially-following user | Format: `did` |
+| `limit` | `integer` | ❌ | | Min: 1
Max: 100
Default: `50` |
+| `before` | `string` | ❌ | | Format: `datetime` |
+
+**Output:**
+
+- **Encoding:** `application/json`
+- **Schema:**
+
+**Schema Type:** `object`
+
+| Name | Type | Req'd | Description | Constraints |
+| ---------- | ---------------------------------------------------------------------------------------------- | ----- | ----------- | ----------- |
+| `segments` | Array of [`place.stream.segment#segmentView`](/lex-reference/place-stream-segment#segmentview) | ❌ | | |
+
+---
+
+## Lexicon Source
+
+```json
+{
+ "lexicon": 1,
+ "id": "place.stream.live.getSegments",
+ "defs": {
+ "main": {
+ "type": "query",
+ "description": "Get a list of livestream segments for a user",
+ "parameters": {
+ "type": "params",
+ "required": ["userDID"],
+ "properties": {
+ "userDID": {
+ "type": "string",
+ "format": "did",
+ "description": "The DID of the potentially-following user"
+ },
+ "limit": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "default": 50
+ },
+ "before": {
+ "type": "string",
+ "format": "datetime"
+ }
+ }
+ },
+ "output": {
+ "encoding": "application/json",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "segments": {
+ "type": "array",
+ "items": {
+ "type": "ref",
+ "ref": "place.stream.segment#segmentView"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
diff --git a/js/docs/src/content/docs/lex-reference/place-stream-segment.md b/js/docs/src/content/docs/lex-reference/place-stream-segment.md
index 7a192fc44..27eb66b33 100644
--- a/js/docs/src/content/docs/lex-reference/place-stream-segment.md
+++ b/js/docs/src/content/docs/lex-reference/place-stream-segment.md
@@ -79,6 +79,21 @@ Media file representing a segment of a livestream
---
+
+
+### `segmentView`
+
+**Type:** `object`
+
+**Properties:**
+
+| Name | Type | Req'd | Description | Constraints |
+| -------- | --------- | ----- | ----------- | ------------- |
+| `cid` | `string` | ✅ | | Format: `cid` |
+| `record` | `unknown` | ✅ | | |
+
+---
+
## Lexicon Source
```json
@@ -179,6 +194,19 @@ Media file representing a segment of a livestream
"type": "integer"
}
}
+ },
+ "segmentView": {
+ "type": "object",
+ "required": ["cid", "record"],
+ "properties": {
+ "cid": {
+ "type": "string",
+ "format": "cid"
+ },
+ "record": {
+ "type": "unknown"
+ }
+ }
}
}
}
diff --git a/lexicons/place/stream/live/getSegments.json b/lexicons/place/stream/live/getSegments.json
new file mode 100644
index 000000000..ebcb3cd07
--- /dev/null
+++ b/lexicons/place/stream/live/getSegments.json
@@ -0,0 +1,43 @@
+{
+ "lexicon": 1,
+ "id": "place.stream.live.getSegments",
+ "defs": {
+ "main": {
+ "type": "query",
+ "description": "Get a list of livestream segments for a user",
+ "parameters": {
+ "type": "params",
+ "required": ["userDID"],
+ "properties": {
+ "userDID": {
+ "type": "string",
+ "format": "did",
+ "description": "The DID of the potentially-following user"
+ },
+ "limit": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "default": 50
+ },
+ "before": { "type": "string", "format": "datetime" }
+ }
+ },
+ "output": {
+ "encoding": "application/json",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "segments": {
+ "type": "array",
+ "items": {
+ "type": "ref",
+ "ref": "place.stream.segment#segmentView"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lexicons/place/stream/segment.json b/lexicons/place/stream/segment.json
index 3e2f991c0..6dac39033 100644
--- a/lexicons/place/stream/segment.json
+++ b/lexicons/place/stream/segment.json
@@ -77,6 +77,14 @@
"num": { "type": "integer" },
"den": { "type": "integer" }
}
+ },
+ "segmentView": {
+ "type": "object",
+ "required": ["cid", "record"],
+ "properties": {
+ "cid": { "type": "string", "format": "cid" },
+ "record": { "type": "unknown" }
+ }
}
}
}
diff --git a/package.json b/package.json
index 18c32ee0a..3183c1f96 100644
--- a/package.json
+++ b/package.json
@@ -36,9 +36,6 @@
],
"packageManager": "yarn@4.3.0",
"dependencies": {
- "@atproto/api": "^0.13.16",
- "@atproto/jwk-webcrypto": "^0.1.2",
- "@atproto/oauth-client-browser": "^0.3.1",
"firebase-admin": "^12.7.0",
"lex-md": "^0.0.3"
}
diff --git a/pkg/model/model.go b/pkg/model/model.go
index 04e0b303c..029e3f46d 100644
--- a/pkg/model/model.go
+++ b/pkg/model/model.go
@@ -36,6 +36,7 @@ type Model interface {
CreateSegment(segment *Segment) error
MostRecentSegments() ([]Segment, error)
LatestSegmentForUser(user string) (*Segment, error)
+ LatestSegmentsForUser(user string, limit int, before *time.Time) ([]Segment, error)
CreateThumbnail(thumb *Thumbnail) error
LatestThumbnailForUser(user string) (*Thumbnail, error)
GetSegment(id string) (*Segment, error)
diff --git a/pkg/model/segment.go b/pkg/model/segment.go
index 3f4539a78..035820b18 100644
--- a/pkg/model/segment.go
+++ b/pkg/model/segment.go
@@ -155,6 +155,19 @@ func (m *DBModel) LatestSegmentForUser(user string) (*Segment, error) {
return &seg, nil
}
+func (m *DBModel) LatestSegmentsForUser(user string, limit int, before *time.Time) ([]Segment, error) {
+ var segs []Segment
+ if before == nil {
+ later := time.Now().Add(1000 * time.Hour)
+ before = &later
+ }
+ err := m.DB.Model(Segment{}).Where("repo_did = ? AND start_time < ?", user, before.UTC()).Order("start_time DESC").Limit(limit).Find(&segs).Error
+ if err != nil {
+ return nil, err
+ }
+ return segs, nil
+}
+
func (m *DBModel) GetLiveUsers() ([]Segment, error) {
var liveUsers []Segment
thirtySecondsAgo := aqtime.FromTime(time.Now().Add(-30 * time.Second)).Time()
diff --git a/pkg/spxrpc/place_stream_live.go b/pkg/spxrpc/place_stream_live.go
new file mode 100644
index 000000000..e167c3623
--- /dev/null
+++ b/pkg/spxrpc/place_stream_live.go
@@ -0,0 +1,73 @@
+package spxrpc
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "net/http"
+ "time"
+
+ "github.com/bluesky-social/indigo/lex/util"
+ "github.com/bluesky-social/indigo/repo"
+ "github.com/ipfs/go-cid"
+ "github.com/labstack/echo/v4"
+ "github.com/multiformats/go-multihash"
+ placestreamtypes "stream.place/streamplace/pkg/streamplace"
+)
+
+func (s *Server) handlePlaceStreamLiveGetSegments(ctx context.Context, before string, limit int, userDID string) (*placestreamtypes.LiveGetSegments_Output, error) {
+ if userDID == "" {
+ return nil, echo.NewHTTPError(http.StatusBadRequest, "User DID is required")
+ }
+ var beforeTime *time.Time
+ if before != "" {
+ parsedTime, err := time.Parse(time.RFC3339, before)
+ if err != nil {
+ return nil, echo.NewHTTPError(http.StatusBadRequest, "Invalid 'before' parameter: must be RFC3339 format")
+ }
+ beforeTime = &parsedTime
+ }
+
+ segments, err := s.model.LatestSegmentsForUser(userDID, limit, beforeTime)
+ if err != nil {
+ return nil, echo.NewHTTPError(http.StatusInternalServerError, "Failed to fetch segments")
+ }
+
+ // Convert segments to the expected output format
+ output := &placestreamtypes.LiveGetSegments_Output{
+ Segments: make([]*placestreamtypes.Segment_SegmentView, len(segments)),
+ }
+
+ for i, segment := range segments {
+ record, err := segment.ToStreamplaceSegment()
+ if err != nil {
+ return nil, echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to convert segment to streamplace segment: %s", err))
+ }
+ c, err := getCID(record)
+ if err != nil {
+ return nil, echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to get CID: %s", err))
+ }
+ ltd := &util.LexiconTypeDecoder{Val: record}
+
+ output.Segments[i] = &placestreamtypes.Segment_SegmentView{
+ Record: ltd,
+ Cid: c.String(),
+ }
+ }
+
+ return output, nil
+}
+
+func getCID(record repo.CborMarshaler) (*cid.Cid, error) {
+ builder := cid.NewPrefixV1(cid.DagCBOR, multihash.SHA2_256)
+ buf := bytes.NewBuffer(nil)
+ err := record.MarshalCBOR(buf)
+ if err != nil {
+ return nil, err
+ }
+ c, err := builder.Sum(buf.Bytes())
+ if err != nil {
+ return nil, err
+ }
+ return &c, nil
+}
diff --git a/pkg/spxrpc/stubs.go b/pkg/spxrpc/stubs.go
index ac333728b..e9c6a0a58 100644
--- a/pkg/spxrpc/stubs.go
+++ b/pkg/spxrpc/stubs.go
@@ -97,6 +97,7 @@ func (s *Server) HandleComAtprotoRepoUploadBlob(c echo.Context) error {
func (s *Server) RegisterHandlersPlaceStream(e *echo.Echo) error {
e.GET("/xrpc/place.stream.graph.getFollowingUser", s.HandlePlaceStreamGraphGetFollowingUser)
+ e.GET("/xrpc/place.stream.live.getSegments", s.HandlePlaceStreamLiveGetSegments)
return nil
}
@@ -115,6 +116,32 @@ func (s *Server) HandlePlaceStreamGraphGetFollowingUser(c echo.Context) error {
return c.JSON(200, out)
}
+func (s *Server) HandlePlaceStreamLiveGetSegments(c echo.Context) error {
+ ctx, span := otel.Tracer("server").Start(c.Request().Context(), "HandlePlaceStreamLiveGetSegments")
+ defer span.End()
+ before := c.QueryParam("before")
+
+ var limit int
+ if p := c.QueryParam("limit"); p != "" {
+ var err error
+ limit, err = strconv.Atoi(p)
+ if err != nil {
+ return err
+ }
+ } else {
+ limit = 50
+ }
+ userDID := c.QueryParam("userDID")
+ var out *placestreamtypes.LiveGetSegments_Output
+ var handleErr error
+ // func (s *Server) handlePlaceStreamLiveGetSegments(ctx context.Context,before string,limit int,userDID string) (*placestreamtypes.LiveGetSegments_Output, error)
+ out, handleErr = s.handlePlaceStreamLiveGetSegments(ctx, before, limit, userDID)
+ if handleErr != nil {
+ return handleErr
+ }
+ return c.JSON(200, out)
+}
+
func (s *Server) RegisterHandlersToolsOzone(e *echo.Echo) error {
return nil
}
diff --git a/pkg/streamplace/livegetSegments.go b/pkg/streamplace/livegetSegments.go
new file mode 100644
index 000000000..9ed56df74
--- /dev/null
+++ b/pkg/streamplace/livegetSegments.go
@@ -0,0 +1,34 @@
+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
+
+package streamplace
+
+// schema: place.stream.live.getSegments
+
+import (
+ "context"
+
+ "github.com/bluesky-social/indigo/xrpc"
+)
+
+// LiveGetSegments_Output is the output of a place.stream.live.getSegments call.
+type LiveGetSegments_Output struct {
+ Segments []*Segment_SegmentView `json:"segments,omitempty" cborgen:"segments,omitempty"`
+}
+
+// LiveGetSegments calls the XRPC method "place.stream.live.getSegments".
+//
+// userDID: The DID of the potentially-following user
+func LiveGetSegments(ctx context.Context, c *xrpc.Client, before string, limit int64, userDID string) (*LiveGetSegments_Output, error) {
+ var out LiveGetSegments_Output
+
+ params := map[string]interface{}{
+ "before": before,
+ "limit": limit,
+ "userDID": userDID,
+ }
+ if err := c.Do(ctx, xrpc.Query, "", "place.stream.live.getSegments", params, nil, &out); err != nil {
+ return nil, err
+ }
+
+ return &out, nil
+}
diff --git a/pkg/streamplace/streamsegment.go b/pkg/streamplace/streamsegment.go
index f956fab6b..eecb6b367 100644
--- a/pkg/streamplace/streamsegment.go
+++ b/pkg/streamplace/streamsegment.go
@@ -40,6 +40,12 @@ type Segment_Framerate struct {
Num int64 `json:"num" cborgen:"num"`
}
+// Segment_SegmentView is a "segmentView" in the place.stream.segment schema.
+type Segment_SegmentView struct {
+ Cid string `json:"cid" cborgen:"cid"`
+ Record *util.LexiconTypeDecoder `json:"record" cborgen:"record"`
+}
+
// Segment_Video is a "video" in the place.stream.segment schema.
type Segment_Video struct {
Codec string `json:"codec" cborgen:"codec"`
diff --git a/yarn.lock b/yarn.lock
index 256c43389..eb927d573 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -191,57 +191,30 @@ __metadata:
languageName: node
linkType: hard
-"@atproto-labs/did-resolver@npm:0.1.11":
- version: 0.1.11
- resolution: "@atproto-labs/did-resolver@npm:0.1.11"
+"@atproto-labs/did-resolver@npm:0.1.12":
+ version: 0.1.12
+ resolution: "@atproto-labs/did-resolver@npm:0.1.12"
dependencies:
"@atproto-labs/fetch": "npm:0.2.2"
"@atproto-labs/pipe": "npm:0.1.0"
- "@atproto-labs/simple-store": "npm:0.1.2"
- "@atproto-labs/simple-store-memory": "npm:0.1.2"
+ "@atproto-labs/simple-store": "npm:0.2.0"
+ "@atproto-labs/simple-store-memory": "npm:0.1.3"
"@atproto/did": "npm:0.1.5"
zod: "npm:^3.23.8"
- checksum: 10/9c5edbf7814046926fa7aec9783196d40edd9e8c3a3c1cd553146749794ed3c54f668d11e0582f49656c27c596acee541ae8f24993221800958706122e412749
+ checksum: 10/f5a3ef64734e4a7432ee7ccf34b7e53b5fc2966d64c831b16fbda8f95e0161c9bc60655ddb103529842b8deb19f735f94f8a535671c3950be38ba903743cd8d4
languageName: node
linkType: hard
-"@atproto-labs/did-resolver@npm:0.1.5":
- version: 0.1.5
- resolution: "@atproto-labs/did-resolver@npm:0.1.5"
- dependencies:
- "@atproto-labs/fetch": "npm:0.1.1"
- "@atproto-labs/pipe": "npm:0.1.0"
- "@atproto-labs/simple-store": "npm:0.1.1"
- "@atproto-labs/simple-store-memory": "npm:0.1.1"
- "@atproto/did": "npm:0.1.3"
- zod: "npm:^3.23.8"
- checksum: 10/a1fccf30df2eb2e9f2c9df2e22e78fd63ccfc8024085b7783876d6914b7f1acd664e5b298ab744ca71f22ea70a44a5478fa8af3b4648c40649082ecca7d37c85
- languageName: node
- linkType: hard
-
-"@atproto-labs/fetch-node@npm:0.1.3":
- version: 0.1.3
- resolution: "@atproto-labs/fetch-node@npm:0.1.3"
+"@atproto-labs/fetch-node@npm:0.1.8":
+ version: 0.1.8
+ resolution: "@atproto-labs/fetch-node@npm:0.1.8"
dependencies:
- "@atproto-labs/fetch": "npm:0.1.1"
+ "@atproto-labs/fetch": "npm:0.2.2"
"@atproto-labs/pipe": "npm:0.1.0"
ipaddr.js: "npm:^2.1.0"
psl: "npm:^1.9.0"
undici: "npm:^6.14.1"
- checksum: 10/7d8e13bd42998be7ece29e9418cf10b0ebf2b90967ca009b5e03e767153f4e3025ac0c67f9cdfe3e02561c8dfc9a961d407b3613b7c8302465526e7233ff9d2b
- languageName: node
- linkType: hard
-
-"@atproto-labs/fetch@npm:0.1.1":
- version: 0.1.1
- resolution: "@atproto-labs/fetch@npm:0.1.1"
- dependencies:
- "@atproto-labs/pipe": "npm:0.1.0"
- zod: "npm:^3.23.8"
- dependenciesMeta:
- zod:
- optional: true
- checksum: 10/557f290e1a0078f022e74b1b663b782979d9a378e6f7575d50cd2eafd1cf20aa52986544b01b586c30505704ec5624630e8718826c7d08768ac775a3b059bae0
+ checksum: 10/b8291294d029a99a6c931c27de59a6a46fd4ad8af842548a3687b2b0a8de50dbefef1752bc3677973550e712279467ad22ac8617ed06833b442225184398e5de
languageName: node
linkType: hard
@@ -254,60 +227,37 @@ __metadata:
languageName: node
linkType: hard
-"@atproto-labs/handle-resolver-node@npm:0.1.7":
- version: 0.1.7
- resolution: "@atproto-labs/handle-resolver-node@npm:0.1.7"
+"@atproto-labs/handle-resolver-node@npm:0.1.15":
+ version: 0.1.15
+ resolution: "@atproto-labs/handle-resolver-node@npm:0.1.15"
dependencies:
- "@atproto-labs/fetch-node": "npm:0.1.3"
- "@atproto-labs/handle-resolver": "npm:0.1.4"
- "@atproto/did": "npm:0.1.3"
- checksum: 10/d7f1896a7154978a8037a443ae8c1d6786febcfebb77f2e1a09eca6083ecc51f5a4473a49779b9720cc9e17bbd335111339b139b2e6112e3d1403e5af3f2f986
- languageName: node
- linkType: hard
-
-"@atproto-labs/handle-resolver@npm:0.1.4":
- version: 0.1.4
- resolution: "@atproto-labs/handle-resolver@npm:0.1.4"
- dependencies:
- "@atproto-labs/simple-store": "npm:0.1.1"
- "@atproto-labs/simple-store-memory": "npm:0.1.1"
- "@atproto/did": "npm:0.1.3"
- zod: "npm:^3.23.8"
- checksum: 10/5679823cd0b4656e9d4345bbd4245493c314799712302066837a07e58d48d673dd0725dea5f37c12b6af14f08435585a9316c706fcbd42e376ae1a5c8a175f13
+ "@atproto-labs/fetch-node": "npm:0.1.8"
+ "@atproto-labs/handle-resolver": "npm:0.1.8"
+ "@atproto/did": "npm:0.1.5"
+ checksum: 10/937fdb42e4ee05120247fdf5f756f4e994fab660e6731998302a8a7f2ee06aaf8c49500bb352a68aa258b0a540369318619e0ed43f84046b536bdc6ad1ea5e3a
languageName: node
linkType: hard
-"@atproto-labs/handle-resolver@npm:0.1.7":
- version: 0.1.7
- resolution: "@atproto-labs/handle-resolver@npm:0.1.7"
+"@atproto-labs/handle-resolver@npm:0.1.8":
+ version: 0.1.8
+ resolution: "@atproto-labs/handle-resolver@npm:0.1.8"
dependencies:
- "@atproto-labs/simple-store": "npm:0.1.2"
- "@atproto-labs/simple-store-memory": "npm:0.1.2"
+ "@atproto-labs/simple-store": "npm:0.2.0"
+ "@atproto-labs/simple-store-memory": "npm:0.1.3"
"@atproto/did": "npm:0.1.5"
zod: "npm:^3.23.8"
- checksum: 10/9ce9bb7d9cd4613f6d37ee6ed2846ee8646557280691c0ff69dc0ce3e5ed96ceb7ed1e89c0e22fad2748e056402ebea0e3caff799f24d69ea462f9a2cf7b30ad
+ checksum: 10/b62cc4e2c8beefcfe2083bd29a3a4280df7d132ad325910c3eecc405a8024d5c7ca229d08bda5d7fa3f456fd241d26922bb7553d0b6c03f9c4b71f72a972ea98
languageName: node
linkType: hard
-"@atproto-labs/identity-resolver@npm:0.1.14":
- version: 0.1.14
- resolution: "@atproto-labs/identity-resolver@npm:0.1.14"
+"@atproto-labs/identity-resolver@npm:0.1.16":
+ version: 0.1.16
+ resolution: "@atproto-labs/identity-resolver@npm:0.1.16"
dependencies:
- "@atproto-labs/did-resolver": "npm:0.1.11"
- "@atproto-labs/handle-resolver": "npm:0.1.7"
- "@atproto/syntax": "npm:0.3.4"
- checksum: 10/2849ac884109c3e1ed83b5f29092a3517d74e51673ca3d7c8b0d153ba007d30d89e86b5f29eb76c2538dbc3183fdcadd5cd1aa046066b6c46baa1109eea444dd
- languageName: node
- linkType: hard
-
-"@atproto-labs/identity-resolver@npm:0.1.6":
- version: 0.1.6
- resolution: "@atproto-labs/identity-resolver@npm:0.1.6"
- dependencies:
- "@atproto-labs/did-resolver": "npm:0.1.5"
- "@atproto-labs/handle-resolver": "npm:0.1.4"
- "@atproto/syntax": "npm:0.3.1"
- checksum: 10/23edc253bb7a2b5989ad8fb12afb047e55a0f646879d934d8a2619d70d2e8be7d68a95bc3376c175026d3f0e5392abd220a4972aa27621098bce241f7897f475
+ "@atproto-labs/did-resolver": "npm:0.1.12"
+ "@atproto-labs/handle-resolver": "npm:0.1.8"
+ "@atproto/syntax": "npm:0.4.0"
+ checksum: 10/32c4bc845c1ceaf1ae5c71a18f989ff529fedad7acc8342e40f07560ec35ba650e622aa37ab39be87acbb7d794db391351ff3f10d8f4221ee1b1c45af0a981f3
languageName: node
linkType: hard
@@ -318,81 +268,64 @@ __metadata:
languageName: node
linkType: hard
-"@atproto-labs/simple-store-memory@npm:0.1.1":
- version: 0.1.1
- resolution: "@atproto-labs/simple-store-memory@npm:0.1.1"
- dependencies:
- "@atproto-labs/simple-store": "npm:0.1.1"
- lru-cache: "npm:^10.2.0"
- checksum: 10/b9dfc23c7bcef6b7049015385d5cf611df27d5c4eb4b5c331a1eec7ec77391a12993a984474d6f39e6c907d5f86659e4defc35b62e73e3acf3874255077896f7
- languageName: node
- linkType: hard
-
-"@atproto-labs/simple-store-memory@npm:0.1.2":
- version: 0.1.2
- resolution: "@atproto-labs/simple-store-memory@npm:0.1.2"
+"@atproto-labs/simple-store-memory@npm:0.1.3":
+ version: 0.1.3
+ resolution: "@atproto-labs/simple-store-memory@npm:0.1.3"
dependencies:
- "@atproto-labs/simple-store": "npm:0.1.2"
+ "@atproto-labs/simple-store": "npm:0.2.0"
lru-cache: "npm:^10.2.0"
- checksum: 10/7bc79e4a496b47677740175c8fb4010790dceff02056399fa4d871db1c8292667a4011f5a4743e77277377e1f4d692286e06440d23cdfd568dcc738bc6d4c9bd
+ checksum: 10/87f2650b613ddec5aa1b31fc9a1ca6321d6ccacc3bda8c6d5de0974de78c0f7b06078b1bee5a25e58cd03bcc5b7437f4533ff355c29e762820e31ee1c6f9d82f
languageName: node
linkType: hard
-"@atproto-labs/simple-store@npm:0.1.1":
- version: 0.1.1
- resolution: "@atproto-labs/simple-store@npm:0.1.1"
- checksum: 10/6251663e6ee07fc59e77cf3aeebcd4f980a18f83e9bfc20be12dae0fbcdaaecc7a88a2d558e625ff2f0db7176b75f44d61b37cb892ae67241248655a9a4d1615
- languageName: node
- linkType: hard
-
-"@atproto-labs/simple-store@npm:0.1.2":
- version: 0.1.2
- resolution: "@atproto-labs/simple-store@npm:0.1.2"
- checksum: 10/61b0aa1375ce4a46233c53d24b9c3950cc27ed95dd917b48d3188baa1d892d1cb17cacaeade37945cb93425a30db1200564cc0641e808765d5026deb43e7aacf
+"@atproto-labs/simple-store@npm:0.2.0":
+ version: 0.2.0
+ resolution: "@atproto-labs/simple-store@npm:0.2.0"
+ checksum: 10/5873af563b491deb047b2d794837ad3f66574b1a437a73eebe413434505e88014e857baebcf5bdad4d45c7bb5094c8d7019cc537618b3479f7545cf6131c4f17
languageName: node
linkType: hard
-"@atproto/api@npm:^0.13.16":
- version: 0.13.16
- resolution: "@atproto/api@npm:0.13.16"
+"@atproto/api@npm:^0.15.7":
+ version: 0.15.7
+ resolution: "@atproto/api@npm:0.15.7"
dependencies:
- "@atproto/common-web": "npm:^0.3.1"
- "@atproto/lexicon": "npm:^0.4.3"
- "@atproto/syntax": "npm:^0.3.1"
- "@atproto/xrpc": "npm:^0.6.4"
+ "@atproto/common-web": "npm:^0.4.2"
+ "@atproto/lexicon": "npm:^0.4.11"
+ "@atproto/syntax": "npm:^0.4.0"
+ "@atproto/xrpc": "npm:^0.7.0"
await-lock: "npm:^2.2.2"
multiformats: "npm:^9.9.0"
tlds: "npm:^1.234.0"
zod: "npm:^3.23.8"
- checksum: 10/0b959ba17d7453955442a8aa771951f27d35a0606d1105408f25b9b3829d4e87d0860e6c3f1af35178c2acf0deb7219452fed648847da18b25fa5b6414167127
+ checksum: 10/42071e470dd1354128fe2062933706444ea4305f0a5856d8b17e363bafcd91c4294952369820da51584784ea64b2fa95e31322b1a5b89c772c65e8915d0eb0cd
languageName: node
linkType: hard
-"@atproto/common-web@npm:^0.3.1":
- version: 0.3.1
- resolution: "@atproto/common-web@npm:0.3.1"
+"@atproto/common-web@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "@atproto/common-web@npm:0.4.0"
dependencies:
graphemer: "npm:^1.4.0"
multiformats: "npm:^9.9.0"
uint8arrays: "npm:3.0.0"
zod: "npm:^3.23.8"
- checksum: 10/185ddf35df2138eb5143380e8b2e3fa2d7517db5297251ef735163e97f710fba19a3e3af99e11d40b825ff5cefa271e1763714574b2ed4a2a5beb8305cf48687
+ checksum: 10/1d0f5245ab953eb7e226c088d5c29a171a36eefe5d898f3a6277a90888ac44be8ddbfd3dbcb1bb97b988b29cfc74136a8ee1c3b9a2cf1a667a22264a418bbdb9
languageName: node
linkType: hard
-"@atproto/common-web@npm:^0.4.0":
- version: 0.4.0
- resolution: "@atproto/common-web@npm:0.4.0"
+"@atproto/common-web@npm:^0.4.2":
+ version: 0.4.2
+ resolution: "@atproto/common-web@npm:0.4.2"
dependencies:
graphemer: "npm:^1.4.0"
multiformats: "npm:^9.9.0"
uint8arrays: "npm:3.0.0"
zod: "npm:^3.23.8"
- checksum: 10/1d0f5245ab953eb7e226c088d5c29a171a36eefe5d898f3a6277a90888ac44be8ddbfd3dbcb1bb97b988b29cfc74136a8ee1c3b9a2cf1a667a22264a418bbdb9
+ checksum: 10/a883155e4b36252c16e17ba055536f095dc096d1e9828e1d56de6aee5c537e141f34719bd639aa572538b5152b7d9c73780b14a252470a11e70a14a455eb3d4d
languageName: node
linkType: hard
-"@atproto/crypto@npm:^0.4.2, @atproto/crypto@npm:^0.4.3":
+"@atproto/crypto@npm:^0.4.4":
version: 0.4.4
resolution: "@atproto/crypto@npm:0.4.4"
dependencies:
@@ -403,15 +336,6 @@ __metadata:
languageName: node
linkType: hard
-"@atproto/did@npm:0.1.3":
- version: 0.1.3
- resolution: "@atproto/did@npm:0.1.3"
- dependencies:
- zod: "npm:^3.23.8"
- checksum: 10/e5a985e1b3149a97c0000134607eedbcb9d6514750ebd9bb36635bcea135e7332adf79d1ecc5d214a04599d1e6c7ec24296c4ad333d007b4fddb0b369f835ba8
- languageName: node
- linkType: hard
-
"@atproto/did@npm:0.1.5":
version: 0.1.5
resolution: "@atproto/did@npm:0.1.5"
@@ -421,53 +345,34 @@ __metadata:
languageName: node
linkType: hard
-"@atproto/jwk-jose@npm:0.1.2":
- version: 0.1.2
- resolution: "@atproto/jwk-jose@npm:0.1.2"
- dependencies:
- "@atproto/jwk": "npm:0.1.1"
- jose: "npm:^5.2.0"
- checksum: 10/0096bc19be294ba0a5ee550565ff27fec397e1121d622dd6921b8ec0080e9756a313c0ae1c970c1ea9e623bbfd071678f16eeb0b4f7c18ef4927c55e38ba5a19
- languageName: node
- linkType: hard
-
-"@atproto/jwk-jose@npm:^0.1.2":
- version: 0.1.5
- resolution: "@atproto/jwk-jose@npm:0.1.5"
+"@atproto/jwk-jose@npm:0.1.6, @atproto/jwk-jose@npm:^0.1.6":
+ version: 0.1.6
+ resolution: "@atproto/jwk-jose@npm:0.1.6"
dependencies:
- "@atproto/jwk": "npm:0.1.4"
+ "@atproto/jwk": "npm:0.1.5"
jose: "npm:^5.2.0"
- checksum: 10/1e7b9d4cde31e47fae9225a12e384ff7f5b8537fead62c41809aabcb4c022b03e283c19c93f6205a6beb23e4c60ef577c32723102eb0fa7f9b85d14fdcc92266
+ checksum: 10/fc3926d1eca2aaea9ac2022cdf3340a94fa9d172520463cdb108352077d48ffac498b164506d4667f7d38a76a6511c06b654eacc6749e8af5df0ce5f4527ec28
languageName: node
linkType: hard
-"@atproto/jwk-webcrypto@npm:0.1.2, @atproto/jwk-webcrypto@npm:^0.1.2":
- version: 0.1.2
- resolution: "@atproto/jwk-webcrypto@npm:0.1.2"
- dependencies:
- "@atproto/jwk": "npm:0.1.1"
- "@atproto/jwk-jose": "npm:0.1.2"
- checksum: 10/94ef0e4b2dcf87f7e9cb795386dbaee01d87fc17b1317b7872af127098ab16b190f2d1f85af1f08eaf946a76b4197c27f35ed86ec7444992deac0cc6a64be63a
- languageName: node
- linkType: hard
-
-"@atproto/jwk@npm:0.1.1":
- version: 0.1.1
- resolution: "@atproto/jwk@npm:0.1.1"
+"@atproto/jwk-webcrypto@npm:0.1.6, @atproto/jwk-webcrypto@npm:^0.1.6":
+ version: 0.1.6
+ resolution: "@atproto/jwk-webcrypto@npm:0.1.6"
dependencies:
- multiformats: "npm:^9.9.0"
+ "@atproto/jwk": "npm:0.1.5"
+ "@atproto/jwk-jose": "npm:0.1.6"
zod: "npm:^3.23.8"
- checksum: 10/583532fbc41edd1c51bfe257fec7966e397ac2dac9acae93fde470fd178e1b706e4fd5b138d06161868707bce72f3647973996140d76d59f7e74a685a0dcdc06
+ checksum: 10/e212510dec62403533e6288f56b3976a27bcc81b67af61bd070db46f151767785fa4e907c48bf85eb2a0bc4ff6c776bea29629221acaaa5bb9675873b7d912c3
languageName: node
linkType: hard
-"@atproto/jwk@npm:0.1.4":
- version: 0.1.4
- resolution: "@atproto/jwk@npm:0.1.4"
+"@atproto/jwk@npm:0.1.5":
+ version: 0.1.5
+ resolution: "@atproto/jwk@npm:0.1.5"
dependencies:
multiformats: "npm:^9.9.0"
zod: "npm:^3.23.8"
- checksum: 10/cdf0b7cb707ae8d12d1a0ea1453cb82059fe32c7fde7d1551efab910d1a45a1247e7506c3fd69d4c53519311725fa2ee043980e9dc83fa2a7a9d7213c5bbccbb
+ checksum: 10/df14d332fcad094a58dfe401f4b75169b04d8c25fef7ac90d9fdcf0b75f5c9336581358d638f48267ee95a55deeab5dd24d1be885ce12556bad6a34980c3ccb9
languageName: node
linkType: hard
@@ -489,20 +394,20 @@ __metadata:
languageName: node
linkType: hard
-"@atproto/lexicon@npm:^0.4.3":
- version: 0.4.3
- resolution: "@atproto/lexicon@npm:0.4.3"
+"@atproto/lexicon@npm:^0.4.11":
+ version: 0.4.11
+ resolution: "@atproto/lexicon@npm:0.4.11"
dependencies:
- "@atproto/common-web": "npm:^0.3.1"
- "@atproto/syntax": "npm:^0.3.1"
+ "@atproto/common-web": "npm:^0.4.2"
+ "@atproto/syntax": "npm:^0.4.0"
iso-datestring-validator: "npm:^2.2.2"
multiformats: "npm:^9.9.0"
zod: "npm:^3.23.8"
- checksum: 10/c7b0616ffcd85eb77315b4a15bf17acfc2c9de6b4112321a8dad5f0723453c8a5464418a332f0e387e999ed863fb954ccb511097e9c733efacc9b3aacc0c611c
+ checksum: 10/7c5ff1bed85cd976dbe1435c968c75ddcb305a51e5718373376ad65d2a65945a9936e9d7bcda51c7e2bf4e5da9078bb943d953415c56f0a93495a3078a8b2cfe
languageName: node
linkType: hard
-"@atproto/lexicon@npm:^0.4.6, @atproto/lexicon@npm:^0.4.8":
+"@atproto/lexicon@npm:^0.4.6":
version: 0.4.8
resolution: "@atproto/lexicon@npm:0.4.8"
dependencies:
@@ -515,166 +420,73 @@ __metadata:
languageName: node
linkType: hard
-"@atproto/oauth-client-browser@npm:0.3.2":
- version: 0.3.2
- resolution: "@atproto/oauth-client-browser@npm:0.3.2"
+"@atproto/oauth-client-browser@npm:0.3.16, @atproto/oauth-client-browser@npm:^0.3.16":
+ version: 0.3.16
+ resolution: "@atproto/oauth-client-browser@npm:0.3.16"
dependencies:
- "@atproto-labs/did-resolver": "npm:0.1.5"
- "@atproto-labs/handle-resolver": "npm:0.1.4"
- "@atproto-labs/simple-store": "npm:0.1.1"
- "@atproto/did": "npm:0.1.3"
- "@atproto/jwk": "npm:0.1.1"
- "@atproto/jwk-webcrypto": "npm:0.1.2"
- "@atproto/oauth-client": "npm:0.3.2"
- "@atproto/oauth-types": "npm:0.2.1"
- checksum: 10/4d588524ebfd58d84f2b0c48fc65d8b834190d149f27e453915e9f608d1464b88255e224128fff3a7ba64506d5d47224ed07bd86f1edc0d8def6c1a882027c5e
- languageName: node
- linkType: hard
-
-"@atproto/oauth-client-browser@npm:^0.3.1":
- version: 0.3.1
- resolution: "@atproto/oauth-client-browser@npm:0.3.1"
- dependencies:
- "@atproto-labs/did-resolver": "npm:0.1.5"
- "@atproto-labs/handle-resolver": "npm:0.1.4"
- "@atproto-labs/simple-store": "npm:0.1.1"
- "@atproto/did": "npm:0.1.3"
- "@atproto/jwk": "npm:0.1.1"
- "@atproto/jwk-webcrypto": "npm:0.1.2"
- "@atproto/oauth-client": "npm:0.3.1"
- "@atproto/oauth-types": "npm:0.2.0"
- checksum: 10/e8aa99f68c382884b082ab60473045b8f38d1c8a8fb247ad5cda831d7d6fce4ece4fca7d25e8c2cccce6738e7a4dc810e640a559dde0375d39d3df6e92b8f5c3
- languageName: node
- linkType: hard
-
-"@atproto/oauth-client@npm:0.3.1":
- version: 0.3.1
- resolution: "@atproto/oauth-client@npm:0.3.1"
- dependencies:
- "@atproto-labs/did-resolver": "npm:0.1.5"
- "@atproto-labs/fetch": "npm:0.1.1"
- "@atproto-labs/handle-resolver": "npm:0.1.4"
- "@atproto-labs/identity-resolver": "npm:0.1.6"
- "@atproto-labs/simple-store": "npm:0.1.1"
- "@atproto-labs/simple-store-memory": "npm:0.1.1"
- "@atproto/did": "npm:0.1.3"
- "@atproto/jwk": "npm:0.1.1"
- "@atproto/oauth-types": "npm:0.2.0"
- "@atproto/xrpc": "npm:0.6.4"
- multiformats: "npm:^9.9.0"
- zod: "npm:^3.23.8"
- checksum: 10/26eb22d9b1d0c59a79a297c0a265a5e92e1b704570bb2bf93c0b3822d3d16e9276195805112f940606d643345f7a0e1f72c57972b6c5f551dd436200ea78e461
- languageName: node
- linkType: hard
-
-"@atproto/oauth-client@npm:0.3.2":
- version: 0.3.2
- resolution: "@atproto/oauth-client@npm:0.3.2"
- dependencies:
- "@atproto-labs/did-resolver": "npm:0.1.5"
- "@atproto-labs/fetch": "npm:0.1.1"
- "@atproto-labs/handle-resolver": "npm:0.1.4"
- "@atproto-labs/identity-resolver": "npm:0.1.6"
- "@atproto-labs/simple-store": "npm:0.1.1"
- "@atproto-labs/simple-store-memory": "npm:0.1.1"
- "@atproto/did": "npm:0.1.3"
- "@atproto/jwk": "npm:0.1.1"
- "@atproto/oauth-types": "npm:0.2.1"
- "@atproto/xrpc": "npm:0.6.4"
- multiformats: "npm:^9.9.0"
- zod: "npm:^3.23.8"
- checksum: 10/0c24457411f69b036cd0c553eaa9853d459b124b48396da6561896ab693766187bfc8b5c48aa552d0085802abaac39a3020d7ce905961e999bd9d3df699a78e1
+ "@atproto-labs/did-resolver": "npm:0.1.12"
+ "@atproto-labs/handle-resolver": "npm:0.1.8"
+ "@atproto-labs/simple-store": "npm:0.2.0"
+ "@atproto/did": "npm:0.1.5"
+ "@atproto/jwk": "npm:0.1.5"
+ "@atproto/jwk-webcrypto": "npm:0.1.6"
+ "@atproto/oauth-client": "npm:0.3.16"
+ "@atproto/oauth-types": "npm:0.2.7"
+ checksum: 10/7e108d5827d9b4dd0592abb9cbd2919591bd1ef2b95f08f91b5924fdc3967e4a3b6372388c7142b2e45347dbd3fd93b114121e6ac2da78663ec5c23b9c4e16b4
languageName: node
linkType: hard
-"@atproto/oauth-client@npm:^0.3.1":
- version: 0.3.11
- resolution: "@atproto/oauth-client@npm:0.3.11"
+"@atproto/oauth-client@npm:0.3.16, @atproto/oauth-client@npm:^0.3.16":
+ version: 0.3.16
+ resolution: "@atproto/oauth-client@npm:0.3.16"
dependencies:
- "@atproto-labs/did-resolver": "npm:0.1.11"
+ "@atproto-labs/did-resolver": "npm:0.1.12"
"@atproto-labs/fetch": "npm:0.2.2"
- "@atproto-labs/handle-resolver": "npm:0.1.7"
- "@atproto-labs/identity-resolver": "npm:0.1.14"
- "@atproto-labs/simple-store": "npm:0.1.2"
- "@atproto-labs/simple-store-memory": "npm:0.1.2"
+ "@atproto-labs/handle-resolver": "npm:0.1.8"
+ "@atproto-labs/identity-resolver": "npm:0.1.16"
+ "@atproto-labs/simple-store": "npm:0.2.0"
+ "@atproto-labs/simple-store-memory": "npm:0.1.3"
"@atproto/did": "npm:0.1.5"
- "@atproto/jwk": "npm:0.1.4"
- "@atproto/oauth-types": "npm:0.2.4"
- "@atproto/xrpc": "npm:0.6.10"
+ "@atproto/jwk": "npm:0.1.5"
+ "@atproto/oauth-types": "npm:0.2.7"
+ "@atproto/xrpc": "npm:0.7.0"
multiformats: "npm:^9.9.0"
zod: "npm:^3.23.8"
- checksum: 10/4e4c6b34badad6abd8901384e67bb468ed01b8d64a839ff05c13edf99e2dd0b1f443fd036ad6d4617615982537596145613c02851696fc1515c930df8284404e
- languageName: node
- linkType: hard
-
-"@atproto/oauth-types@npm:0.2.0":
- version: 0.2.0
- resolution: "@atproto/oauth-types@npm:0.2.0"
- dependencies:
- "@atproto/jwk": "npm:0.1.1"
- zod: "npm:^3.23.8"
- checksum: 10/e526a936f66c7c7dc6bdb3792ffac7fa168c9908a39f28a89ff5183b3e13961b264dcee9dbf3dfcbaa5ec67aedbc8c08f9d4b0b061c99badb6055ae8e491cadb
+ checksum: 10/dc26a79966eefbc114bd7f45954b3d3921afe1a8cf3e95cdc2682b5275283c7511bdfff4ab66fce929879bb98733589f0a2ad5c9c6f500edd63396ec360d2b62
languageName: node
linkType: hard
-"@atproto/oauth-types@npm:0.2.1":
- version: 0.2.1
- resolution: "@atproto/oauth-types@npm:0.2.1"
- dependencies:
- "@atproto/jwk": "npm:0.1.1"
- zod: "npm:^3.23.8"
- checksum: 10/24a9955a51582301ddf1fdc470d8dac73b13cdecf4d5739419401e5d30b0d840a01f1d06988c25851bff350a5c00caf8f9e19b3e20bfc7033ba2971e26c27277
- languageName: node
- linkType: hard
-
-"@atproto/oauth-types@npm:0.2.4":
- version: 0.2.4
- resolution: "@atproto/oauth-types@npm:0.2.4"
+"@atproto/oauth-types@npm:0.2.7":
+ version: 0.2.7
+ resolution: "@atproto/oauth-types@npm:0.2.7"
dependencies:
- "@atproto/jwk": "npm:0.1.4"
+ "@atproto/jwk": "npm:0.1.5"
zod: "npm:^3.23.8"
- checksum: 10/8d054e6db5ee25d2236d759b4fa4ca8187ae390decafff07d607a226a272775433c8a088fc2546e684e44a17d535271669196e03cb939e78741b26b5dc20ac6d
+ checksum: 10/eeae51b6ded48a33bd14ff69f2daf00b1b5d8c23c8f1fa6e2ecc31559e7d3baa8511f7daefe2539fcc91a50ffb4606c39f92c155548756a37bee52fc8c9bb232
languageName: node
linkType: hard
-"@atproto/syntax@npm:0.3.1, @atproto/syntax@npm:^0.3.1":
- version: 0.3.1
- resolution: "@atproto/syntax@npm:0.3.1"
- checksum: 10/f5a7509b74d48d0b7be7cee82c8b93861a79671e617864c022147099fa1f87ee91da7c9b2b8688c8ae405fd465eb4e2b012eed04bf5aaadc4233c03f1badb9ed
- languageName: node
- linkType: hard
-
-"@atproto/syntax@npm:0.3.4, @atproto/syntax@npm:^0.3.2, @atproto/syntax@npm:^0.3.4":
- version: 0.3.4
- resolution: "@atproto/syntax@npm:0.3.4"
- checksum: 10/3f9b8462b8e7b194bf8580bdd672e215a87812075854e959327498b4958cc2437d3694c453e918d67e43fd42dc404669663fbe85ece8cc21094d98ee63bf5fbd
- languageName: node
- linkType: hard
-
-"@atproto/syntax@npm:^0.4.0":
+"@atproto/syntax@npm:0.4.0, @atproto/syntax@npm:^0.4.0":
version: 0.4.0
resolution: "@atproto/syntax@npm:0.4.0"
checksum: 10/f4a1987bf6a3e0ed63df660a1543049ef023c7ecd4c394efbd247acd1e562a9dfb2beb228e26f806e0a5b56bd5c706345dfdfa804e901e2091100b4c82653556
languageName: node
linkType: hard
-"@atproto/xrpc@npm:0.6.10":
- version: 0.6.10
- resolution: "@atproto/xrpc@npm:0.6.10"
- dependencies:
- "@atproto/lexicon": "npm:^0.4.8"
- zod: "npm:^3.23.8"
- checksum: 10/a229bd851fbc5673dcb21154baea53d7817f7be74b52f76e09c966ae3426e49ee5f0289a83326e398b958871208dbfd7cd31e47efaf982a3ae251a733dc8babc
+"@atproto/syntax@npm:^0.3.2, @atproto/syntax@npm:^0.3.4":
+ version: 0.3.4
+ resolution: "@atproto/syntax@npm:0.3.4"
+ checksum: 10/3f9b8462b8e7b194bf8580bdd672e215a87812075854e959327498b4958cc2437d3694c453e918d67e43fd42dc404669663fbe85ece8cc21094d98ee63bf5fbd
languageName: node
linkType: hard
-"@atproto/xrpc@npm:0.6.4, @atproto/xrpc@npm:^0.6.4":
- version: 0.6.4
- resolution: "@atproto/xrpc@npm:0.6.4"
+"@atproto/xrpc@npm:0.7.0, @atproto/xrpc@npm:^0.7.0":
+ version: 0.7.0
+ resolution: "@atproto/xrpc@npm:0.7.0"
dependencies:
- "@atproto/lexicon": "npm:^0.4.3"
+ "@atproto/lexicon": "npm:^0.4.11"
zod: "npm:^3.23.8"
- checksum: 10/de610ce225218722399bb2612085dbbe001dc7531d56a8be9e01151797938b480698c2e790d2a3dbf5ef778dcf0d3452c9ede4963a1d108bf43b0f2f805441cf
+ checksum: 10/0038b697f66e1e730dee16faf5347834a6a76b9e978a42be330f1caeee6d00abae82a45a54d13887e84ede47bbe71ce95e81b81e75370f0e6194923c2747618e
languageName: node
linkType: hard
@@ -8787,17 +8599,17 @@ __metadata:
version: 0.0.0-use.local
resolution: "@streamplace/atproto-oauth-client-react-native@workspace:js/atproto-oauth-client-react-native"
dependencies:
- "@atproto-labs/did-resolver": "npm:0.1.5"
- "@atproto-labs/handle-resolver-node": "npm:0.1.7"
- "@atproto-labs/simple-store": "npm:0.1.1"
- "@atproto-labs/simple-store-memory": "npm:0.1.1"
- "@atproto/did": "npm:0.1.3"
- "@atproto/jwk": "npm:0.1.1"
- "@atproto/jwk-jose": "npm:0.1.2"
- "@atproto/jwk-webcrypto": "npm:0.1.2"
- "@atproto/oauth-client": "npm:0.3.2"
- "@atproto/oauth-client-browser": "npm:0.3.2"
- "@atproto/oauth-types": "npm:0.2.1"
+ "@atproto-labs/did-resolver": "npm:0.1.12"
+ "@atproto-labs/handle-resolver-node": "npm:0.1.15"
+ "@atproto-labs/simple-store": "npm:0.2.0"
+ "@atproto-labs/simple-store-memory": "npm:0.1.3"
+ "@atproto/did": "npm:0.1.5"
+ "@atproto/jwk": "npm:0.1.5"
+ "@atproto/jwk-jose": "npm:0.1.6"
+ "@atproto/jwk-webcrypto": "npm:0.1.6"
+ "@atproto/oauth-client": "npm:0.3.16"
+ "@atproto/oauth-client-browser": "npm:0.3.16"
+ "@atproto/oauth-types": "npm:0.2.7"
"@types/node": "npm:^22.10.1"
abortcontroller-polyfill: "npm:^1.7.6"
event-target-shim: "npm:^6.0.2"
@@ -29500,7 +29312,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "streamplace-desktop@workspace:js/desktop"
dependencies:
- "@atproto/crypto": "npm:^0.4.3"
+ "@atproto/crypto": "npm:^0.4.4"
"@electron-forge/cli": "npm:^7.5.0"
"@electron-forge/maker-deb": "npm:^7.5.0"
"@electron-forge/maker-dmg": "npm:^7.5.0"
@@ -29550,10 +29362,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "streamplace-monorepo@workspace:."
dependencies:
- "@atproto/api": "npm:^0.13.16"
- "@atproto/jwk-webcrypto": "npm:^0.1.2"
"@atproto/lex-cli": "npm:^0.5.6"
- "@atproto/oauth-client-browser": "npm:^0.3.1"
firebase-admin: "npm:^12.7.0"
husky: "npm:^9.1.6"
lerna: "npm:^8.1.9"
@@ -29568,9 +29377,12 @@ __metadata:
resolution: "streamplace@workspace:js/app"
dependencies:
"@atproto-labs/pipe": "npm:^0.1.0"
- "@atproto/crypto": "npm:^0.4.2"
- "@atproto/jwk-jose": "npm:^0.1.2"
- "@atproto/oauth-client": "npm:^0.3.1"
+ "@atproto/api": "npm:^0.15.7"
+ "@atproto/crypto": "npm:^0.4.4"
+ "@atproto/jwk-jose": "npm:^0.1.6"
+ "@atproto/jwk-webcrypto": "npm:^0.1.6"
+ "@atproto/oauth-client": "npm:^0.3.16"
+ "@atproto/oauth-client-browser": "npm:^0.3.16"
"@babel/core": "npm:^7.26.0"
"@babel/plugin-proposal-export-default-from": "npm:^7.25.9"
"@babel/plugin-syntax-export-default-from": "npm:^7.25.9"