···11+{
22+ "lexicon": 1,
33+ "id": "place.stream.broadcast.origin",
44+ "defs": {
55+ "main": {
66+ "type": "record",
77+ "description": "Record indicating a livestream is published and available for replication at a given address. By convention, the record key is streamer::server",
88+ "key": "any",
99+ "record": {
1010+ "type": "object",
1111+ "required": [
1212+ "streamer",
1313+ "server",
1414+ "updatedAt"
1515+ ],
1616+ "properties": {
1717+ "irohTicket": {
1818+ "type": "string",
1919+ "description": "Iroh ticket that can be used to access the livestream from the server",
2020+ "maxLength": 2048
2121+ },
2222+ "server": {
2323+ "type": "string",
2424+ "description": "did:web of the server that's currently rebroadcasting the livestream",
2525+ "format": "did"
2626+ },
2727+ "streamer": {
2828+ "type": "string",
2929+ "description": "DID of the streamer whose livestream is being published",
3030+ "format": "did"
3131+ },
3232+ "updatedAt": {
3333+ "type": "string",
3434+ "description": "Periodically updated timestamp when this origin last saw a livestream",
3535+ "format": "datetime"
3636+ }
3737+ }
3838+ }
3939+ }
4040+ }
4141+}
···11+{
22+ "lexicon": 1,
33+ "id": "place.stream.metadata.contentRights",
44+ "defs": {
55+ "all-rights-reserved": {
66+ "type": "token",
77+ "description": "All rights reserved to the creator — others cannot use, modify, or share without explicit authorization."
88+ },
99+ "cc-by-nc-nd_4__0": {
1010+ "type": "token",
1111+ "description": "Attribution + non-commercial + no derivatives. Others may download and share your work with credit, but cannot change it or use it commercially."
1212+ },
1313+ "cc-by-nc-sa_4__0": {
1414+ "type": "token",
1515+ "description": "Attribution + non-commercial + share-alike. Others may adapt and build upon your work for non-commercial purposes only, must credit you, and must license their new creations under identical terms."
1616+ },
1717+ "cc-by-nc_4__0": {
1818+ "type": "token",
1919+ "description": "Attribution + non-commercial. Others may adapt and build upon your work for non-commercial purposes only, and must credit you."
2020+ },
2121+ "cc-by-nd_4__0": {
2222+ "type": "token",
2323+ "description": "Attribution + no derivatives. Others may reuse your work, even commercially, but it must remain unchanged and you must be credited."
2424+ },
2525+ "cc-by-sa_4__0": {
2626+ "type": "token",
2727+ "description": "Attribution + share-alike. Others may adapt and build upon your work, even commercially, if they credit you and license their new creations under identical terms."
2828+ },
2929+ "cc-by_4__0": {
3030+ "type": "token",
3131+ "description": "Attribution required. Others may copy, distribute, remix, and build upon your work, even commercially, if they credit you."
3232+ },
3333+ "cc0_1__0": {
3434+ "type": "token",
3535+ "description": "Public domain dedication. You waive all copyright and related rights where possible. Others may copy, modify, distribute, or perform your work for any purpose without attribution."
3636+ },
3737+ "main": {
3838+ "type": "object",
3939+ "description": "Content rights and attribution information.",
4040+ "properties": {
4141+ "copyrightNotice": {
4242+ "type": "string",
4343+ "description": "Copyright notice for the work."
4444+ },
4545+ "copyrightYear": {
4646+ "type": "integer",
4747+ "description": "Year of creation or publication."
4848+ },
4949+ "creator": {
5050+ "type": "string",
5151+ "description": "Name of the creator of the work."
5252+ },
5353+ "creditLine": {
5454+ "type": "string",
5555+ "description": "Credit line for the work."
5656+ },
5757+ "license": {
5858+ "type": "string",
5959+ "description": "License URL or identifier.",
6060+ "knownValues": [
6161+ "place.stream.metadata.contentRights#all-rights-reserved",
6262+ "place.stream.metadata.contentRights#cc0_1__0",
6363+ "place.stream.metadata.contentRights#cc-by_4__0",
6464+ "place.stream.metadata.contentRights#cc-by-sa_4__0",
6565+ "place.stream.metadata.contentRights#cc-by-nc_4__0",
6666+ "place.stream.metadata.contentRights#cc-by-nc-sa_4__0",
6767+ "place.stream.metadata.contentRights#cc-by-nd_4__0",
6868+ "place.stream.metadata.contentRights#cc-by-nc-nd_4__0"
6969+ ]
7070+ }
7171+ }
7272+ }
7373+ }
7474+}
···11+{
22+ "lexicon": 1,
33+ "id": "place.stream.metadata.contentWarnings",
44+ "defs": {
55+ "PII": {
66+ "type": "token",
77+ "description": "The content contains information that can be used to identify a particular individual, such as a name, phone number, email address, physical address, or IP address."
88+ },
99+ "death": {
1010+ "type": "token",
1111+ "description": "The content could be perceived as offensive due to the discussion or display of death."
1212+ },
1313+ "drugUse": {
1414+ "type": "token",
1515+ "description": "The content contains a portrayal of the use or abuse of mind altering substances."
1616+ },
1717+ "fantasyViolence": {
1818+ "type": "token",
1919+ "description": "The content contains violent actions of a fantasy nature, involving human or non-human characters in situations easily distinguishable from real life."
2020+ },
2121+ "flashingLights": {
2222+ "type": "token",
2323+ "description": "The content contains flashing lights that could be harmful to viewers with seizure disorders such as photosensitive epilepsy."
2424+ },
2525+ "language": {
2626+ "type": "token",
2727+ "description": "The content could be perceived as offensive due to the language used."
2828+ },
2929+ "main": {
3030+ "type": "object",
3131+ "description": "Content warnings for a stream.",
3232+ "properties": {
3333+ "warnings": {
3434+ "type": "array",
3535+ "items": {
3636+ "type": "string",
3737+ "knownValues": [
3838+ "place.stream.metadata.contentWarnings#death",
3939+ "place.stream.metadata.contentWarnings#drugUse",
4040+ "place.stream.metadata.contentWarnings#fantasyViolence",
4141+ "place.stream.metadata.contentWarnings#flashingLights",
4242+ "place.stream.metadata.contentWarnings#language",
4343+ "place.stream.metadata.contentWarnings#nudity",
4444+ "place.stream.metadata.contentWarnings#PII",
4545+ "place.stream.metadata.contentWarnings#sexuality",
4646+ "place.stream.metadata.contentWarnings#suffering",
4747+ "place.stream.metadata.contentWarnings#violence"
4848+ ]
4949+ }
5050+ }
5151+ }
5252+ },
5353+ "nudity": {
5454+ "type": "token",
5555+ "description": "The content could be perceived as offensive due to nudity."
5656+ },
5757+ "sexuality": {
5858+ "type": "token",
5959+ "description": "The content could be perceived as offensive due to the discussion or display of sexuality."
6060+ },
6161+ "suffering": {
6262+ "type": "token",
6363+ "description": "The content could be perceived as distressing due to the discussion or display of suffering or triggering topics, including suicide, eating disorders or self harm."
6464+ },
6565+ "violence": {
6666+ "type": "token",
6767+ "description": "The content could be perceived as offensive due to the discussion or display of violence."
6868+ }
6969+ }
7070+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// This file was automatically generated from Lexicon schemas.
44+// Any manual changes will be overwritten on the next regeneration.
55+66+pub mod feed;
77+pub mod richtext;
+8
crates/jacquard-api/src/fyi_frontpage/feed.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// This file was automatically generated from Lexicon schemas.
44+// Any manual changes will be overwritten on the next regeneration.
55+66+pub mod comment;
77+pub mod post;
88+pub mod vote;
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: fyi.frontpage.feed.vote
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+/// Record containing a Frontpage vote.
99+#[jacquard_derive::lexicon]
1010+#[derive(
1111+ serde::Serialize,
1212+ serde::Deserialize,
1313+ Debug,
1414+ Clone,
1515+ PartialEq,
1616+ Eq,
1717+ jacquard_derive::IntoStatic,
1818+ bon::Builder
1919+)]
2020+#[serde(rename_all = "camelCase")]
2121+pub struct Vote<'a> {
2222+ /// Client-declared timestamp when this vote was originally created.
2323+ pub created_at: jacquard_common::types::string::Datetime,
2424+ /// The post or comment that this Frontpage vote is for.
2525+ #[serde(borrow)]
2626+ pub subject: crate::com_atproto::repo::strong_ref::StrongRef<'a>,
2727+}
2828+2929+impl<'a> Vote<'a> {
3030+ pub fn uri(
3131+ uri: impl Into<jacquard_common::CowStr<'a>>,
3232+ ) -> Result<
3333+ jacquard_common::types::uri::RecordUri<'a, VoteRecord>,
3434+ jacquard_common::types::uri::UriError,
3535+ > {
3636+ jacquard_common::types::uri::RecordUri::try_from_uri(
3737+ jacquard_common::types::string::AtUri::new_cow(uri.into())?,
3838+ )
3939+ }
4040+}
4141+4242+/// Typed wrapper for GetRecord response with this collection's record type.
4343+#[derive(
4444+ serde::Serialize,
4545+ serde::Deserialize,
4646+ Debug,
4747+ Clone,
4848+ PartialEq,
4949+ Eq,
5050+ jacquard_derive::IntoStatic
5151+)]
5252+#[serde(rename_all = "camelCase")]
5353+pub struct VoteGetRecordOutput<'a> {
5454+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5555+ #[serde(borrow)]
5656+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
5757+ #[serde(borrow)]
5858+ pub uri: jacquard_common::types::string::AtUri<'a>,
5959+ #[serde(borrow)]
6060+ pub value: Vote<'a>,
6161+}
6262+6363+impl From<VoteGetRecordOutput<'_>> for Vote<'_> {
6464+ fn from(output: VoteGetRecordOutput<'_>) -> Self {
6565+ use jacquard_common::IntoStatic;
6666+ output.value.into_static()
6767+ }
6868+}
6969+7070+impl jacquard_common::types::collection::Collection for Vote<'_> {
7171+ const NSID: &'static str = "fyi.frontpage.feed.vote";
7272+ type Record = VoteRecord;
7373+}
7474+7575+/// Marker type for deserializing records from this collection.
7676+#[derive(Debug, serde::Serialize, serde::Deserialize)]
7777+pub struct VoteRecord;
7878+impl jacquard_common::xrpc::XrpcResp for VoteRecord {
7979+ const NSID: &'static str = "fyi.frontpage.feed.vote";
8080+ const ENCODING: &'static str = "application/json";
8181+ type Output<'de> = VoteGetRecordOutput<'de>;
8282+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
8383+}
8484+8585+impl jacquard_common::types::collection::Collection for VoteRecord {
8686+ const NSID: &'static str = "fyi.frontpage.feed.vote";
8787+ type Record = VoteRecord;
8888+}
+6
crates/jacquard-api/src/fyi_frontpage/richtext.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// This file was automatically generated from Lexicon schemas.
44+// Any manual changes will be overwritten on the next regeneration.
55+66+pub mod block;
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: fyi.frontpage.richtext.block
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[jacquard_derive::lexicon]
99+#[derive(
1010+ serde::Serialize,
1111+ serde::Deserialize,
1212+ Debug,
1313+ Clone,
1414+ PartialEq,
1515+ Eq,
1616+ jacquard_derive::IntoStatic,
1717+ bon::Builder
1818+)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct Block<'a> {
2121+ #[serde(borrow)]
2222+ pub content: crate::fyi_frontpage::richtext::block::PlaintextParagraph<'a>,
2323+}
2424+2525+#[jacquard_derive::lexicon]
2626+#[derive(
2727+ serde::Serialize,
2828+ serde::Deserialize,
2929+ Debug,
3030+ Clone,
3131+ PartialEq,
3232+ Eq,
3333+ jacquard_derive::IntoStatic,
3434+ Default
3535+)]
3636+#[serde(rename_all = "camelCase")]
3737+pub struct PlaintextParagraph<'a> {
3838+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3939+ #[serde(borrow)]
4040+ pub text: std::option::Option<jacquard_common::CowStr<'a>>,
4141+}
+3
crates/jacquard-api/src/lib.rs
···7575#[cfg(feature = "events_smokesignal")]
7676pub mod events_smokesignal;
77777878+#[cfg(feature = "fyi_frontpage")]
7979+pub mod fyi_frontpage;
8080+7881#[cfg(feature = "fyi_unravel")]
7982pub mod fyi_unravel;
8083
+2
crates/jacquard-api/src/place_stream.rs
···55// This file was automatically generated from Lexicon schemas.
66// Any manual changes will be overwritten on the next regeneration.
7788+pub mod broadcast;
89pub mod chat;
910pub mod graph;
1011pub mod key;
1112pub mod live;
1213pub mod livestream;
1414+pub mod metadata;
1315pub mod richtext;
1416pub mod segment;
1517pub mod server;
+32
crates/jacquard-api/src/place_stream/broadcast.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: place.stream.broadcast.defs
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+pub mod origin;
99+pub mod syndication;
1010+1111+#[jacquard_derive::lexicon]
1212+#[derive(
1313+ serde::Serialize,
1414+ serde::Deserialize,
1515+ Debug,
1616+ Clone,
1717+ PartialEq,
1818+ Eq,
1919+ jacquard_derive::IntoStatic,
2020+ bon::Builder
2121+)]
2222+#[serde(rename_all = "camelCase")]
2323+pub struct BroadcastOriginView<'a> {
2424+ #[serde(borrow)]
2525+ pub author: crate::app_bsky::actor::ProfileViewBasic<'a>,
2626+ #[serde(borrow)]
2727+ pub cid: jacquard_common::types::string::Cid<'a>,
2828+ #[serde(borrow)]
2929+ pub record: jacquard_common::types::value::Data<'a>,
3030+ #[serde(borrow)]
3131+ pub uri: jacquard_common::types::string::AtUri<'a>,
3232+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: place.stream.broadcast.origin
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+/// Record indicating a livestream is published and available for replication at a given address. By convention, the record key is streamer::server
99+#[jacquard_derive::lexicon]
1010+#[derive(
1111+ serde::Serialize,
1212+ serde::Deserialize,
1313+ Debug,
1414+ Clone,
1515+ PartialEq,
1616+ Eq,
1717+ jacquard_derive::IntoStatic,
1818+ bon::Builder
1919+)]
2020+#[serde(rename_all = "camelCase")]
2121+pub struct Origin<'a> {
2222+ /// Iroh ticket that can be used to access the livestream from the server
2323+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2424+ #[builder(into)]
2525+ #[serde(borrow)]
2626+ pub iroh_ticket: Option<jacquard_common::CowStr<'a>>,
2727+ /// did:web of the server that's currently rebroadcasting the livestream
2828+ #[serde(borrow)]
2929+ pub server: jacquard_common::types::string::Did<'a>,
3030+ /// DID of the streamer whose livestream is being published
3131+ #[serde(borrow)]
3232+ pub streamer: jacquard_common::types::string::Did<'a>,
3333+ /// Periodically updated timestamp when this origin last saw a livestream
3434+ pub updated_at: jacquard_common::types::string::Datetime,
3535+}
3636+3737+impl<'a> Origin<'a> {
3838+ pub fn uri(
3939+ uri: impl Into<jacquard_common::CowStr<'a>>,
4040+ ) -> Result<
4141+ jacquard_common::types::uri::RecordUri<'a, OriginRecord>,
4242+ jacquard_common::types::uri::UriError,
4343+ > {
4444+ jacquard_common::types::uri::RecordUri::try_from_uri(
4545+ jacquard_common::types::string::AtUri::new_cow(uri.into())?,
4646+ )
4747+ }
4848+}
4949+5050+/// Typed wrapper for GetRecord response with this collection's record type.
5151+#[derive(
5252+ serde::Serialize,
5353+ serde::Deserialize,
5454+ Debug,
5555+ Clone,
5656+ PartialEq,
5757+ Eq,
5858+ jacquard_derive::IntoStatic
5959+)]
6060+#[serde(rename_all = "camelCase")]
6161+pub struct OriginGetRecordOutput<'a> {
6262+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6363+ #[serde(borrow)]
6464+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
6565+ #[serde(borrow)]
6666+ pub uri: jacquard_common::types::string::AtUri<'a>,
6767+ #[serde(borrow)]
6868+ pub value: Origin<'a>,
6969+}
7070+7171+impl From<OriginGetRecordOutput<'_>> for Origin<'_> {
7272+ fn from(output: OriginGetRecordOutput<'_>) -> Self {
7373+ use jacquard_common::IntoStatic;
7474+ output.value.into_static()
7575+ }
7676+}
7777+7878+impl jacquard_common::types::collection::Collection for Origin<'_> {
7979+ const NSID: &'static str = "place.stream.broadcast.origin";
8080+ type Record = OriginRecord;
8181+}
8282+8383+/// Marker type for deserializing records from this collection.
8484+#[derive(Debug, serde::Serialize, serde::Deserialize)]
8585+pub struct OriginRecord;
8686+impl jacquard_common::xrpc::XrpcResp for OriginRecord {
8787+ const NSID: &'static str = "place.stream.broadcast.origin";
8888+ const ENCODING: &'static str = "application/json";
8989+ type Output<'de> = OriginGetRecordOutput<'de>;
9090+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
9191+}
9292+9393+impl jacquard_common::types::collection::Collection for OriginRecord {
9494+ const NSID: &'static str = "place.stream.broadcast.origin";
9595+ type Record = OriginRecord;
9696+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: place.stream.broadcast.syndication
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+/// Record created by a Streamplace broadcaster to indicate that they will be replicating a livestream
99+#[jacquard_derive::lexicon]
1010+#[derive(
1111+ serde::Serialize,
1212+ serde::Deserialize,
1313+ Debug,
1414+ Clone,
1515+ PartialEq,
1616+ Eq,
1717+ jacquard_derive::IntoStatic,
1818+ bon::Builder
1919+)]
2020+#[serde(rename_all = "camelCase")]
2121+pub struct Syndication<'a> {
2222+ /// DID of the Streamplace broadcaster that will be replicating the livestream
2323+ #[serde(borrow)]
2424+ pub broadcaster: jacquard_common::types::string::Did<'a>,
2525+ /// Client-declared timestamp when this syndication was created.
2626+ pub created_at: jacquard_common::types::string::Datetime,
2727+ /// DID of the streamer whose livestream is being replicated
2828+ #[serde(borrow)]
2929+ pub streamer: jacquard_common::types::string::Did<'a>,
3030+}
3131+3232+impl<'a> Syndication<'a> {
3333+ pub fn uri(
3434+ uri: impl Into<jacquard_common::CowStr<'a>>,
3535+ ) -> Result<
3636+ jacquard_common::types::uri::RecordUri<'a, SyndicationRecord>,
3737+ jacquard_common::types::uri::UriError,
3838+ > {
3939+ jacquard_common::types::uri::RecordUri::try_from_uri(
4040+ jacquard_common::types::string::AtUri::new_cow(uri.into())?,
4141+ )
4242+ }
4343+}
4444+4545+/// Typed wrapper for GetRecord response with this collection's record type.
4646+#[derive(
4747+ serde::Serialize,
4848+ serde::Deserialize,
4949+ Debug,
5050+ Clone,
5151+ PartialEq,
5252+ Eq,
5353+ jacquard_derive::IntoStatic
5454+)]
5555+#[serde(rename_all = "camelCase")]
5656+pub struct SyndicationGetRecordOutput<'a> {
5757+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5858+ #[serde(borrow)]
5959+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
6060+ #[serde(borrow)]
6161+ pub uri: jacquard_common::types::string::AtUri<'a>,
6262+ #[serde(borrow)]
6363+ pub value: Syndication<'a>,
6464+}
6565+6666+impl From<SyndicationGetRecordOutput<'_>> for Syndication<'_> {
6767+ fn from(output: SyndicationGetRecordOutput<'_>) -> Self {
6868+ use jacquard_common::IntoStatic;
6969+ output.value.into_static()
7070+ }
7171+}
7272+7373+impl jacquard_common::types::collection::Collection for Syndication<'_> {
7474+ const NSID: &'static str = "place.stream.broadcast.syndication";
7575+ type Record = SyndicationRecord;
7676+}
7777+7878+/// Marker type for deserializing records from this collection.
7979+#[derive(Debug, serde::Serialize, serde::Deserialize)]
8080+pub struct SyndicationRecord;
8181+impl jacquard_common::xrpc::XrpcResp for SyndicationRecord {
8282+ const NSID: &'static str = "place.stream.broadcast.syndication";
8383+ const ENCODING: &'static str = "application/json";
8484+ type Output<'de> = SyndicationGetRecordOutput<'de>;
8585+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
8686+}
8787+8888+impl jacquard_common::types::collection::Collection for SyndicationRecord {
8989+ const NSID: &'static str = "place.stream.broadcast.syndication";
9090+ type Record = SyndicationRecord;
9191+}
+9
crates/jacquard-api/src/place_stream/metadata.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// This file was automatically generated from Lexicon schemas.
44+// Any manual changes will be overwritten on the next regeneration.
55+66+pub mod configuration;
77+pub mod content_rights;
88+pub mod content_warnings;
99+pub mod distribution_policy;
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: place.stream.metadata.distributionPolicy
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+/// Distribution and rebroadcast policy.
99+#[jacquard_derive::lexicon]
1010+#[derive(
1111+ serde::Serialize,
1212+ serde::Deserialize,
1313+ Debug,
1414+ Clone,
1515+ PartialEq,
1616+ Eq,
1717+ jacquard_derive::IntoStatic,
1818+ Default
1919+)]
2020+#[serde(rename_all = "camelCase")]
2121+pub struct DistributionPolicy<'a> {
2222+ /// Duration in seconds after which segments should be deleted. Each segment will expire N seconds after its creation time.
2323+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2424+ pub delete_after: std::option::Option<i64>,
2525+}