···11+{
22+ "$type": "com.atproto.lexicon.schema",
33+ "lexicon": 1,
44+ "id": "place.stream.live.teleport",
55+ "defs": {
66+ "main": {
77+ "type": "record",
88+ "key": "tid",
99+ "description": "Record defining a 'teleport', that is active during a certain time.",
1010+ "record": {
1111+ "type": "object",
1212+ "required": ["streamer", "startsAt"],
1313+ "properties": {
1414+ "streamer": {
1515+ "type": "string",
1616+ "format": "did",
1717+ "description": "The DID of the streamer to teleport to."
1818+ },
1919+ "startsAt": {
2020+ "type": "string",
2121+ "format": "datetime",
2222+ "description": "The time the teleport becomes active."
2323+ },
2424+ "durationSeconds": {
2525+ "type": "integer",
2626+ "description": "The time limit in seconds for the teleport. If not set, the teleport is permanent. Must be at least 60 seconds, and no more than 32,400 seconds (9 hours).",
2727+ "minimum": 60,
2828+ "maximum": 32400
2929+ }
3030+ }
3131+ }
3232+ }
3333+ }
3434+}
+173
lexicons/place/stream/stream/livestream.json
···11+{
22+ "$type": "com.atproto.lexicon.schema",
33+ "lexicon": 1,
44+ "id": "place.stream.livestream",
55+ "defs": {
66+ "main": {
77+ "type": "record",
88+ "description": "Record announcing a livestream is happening",
99+ "key": "tid",
1010+ "record": {
1111+ "type": "object",
1212+ "required": ["title", "createdAt"],
1313+ "properties": {
1414+ "title": {
1515+ "type": "string",
1616+ "maxLength": 1400,
1717+ "maxGraphemes": 140,
1818+ "description": "The title of the livestream, as it will be announced to followers."
1919+ },
2020+ "url": {
2121+ "type": "string",
2222+ "format": "uri",
2323+ "description": "The URL where this stream can be found. This is primarily a hint for other Streamplace nodes to locate and replicate the stream."
2424+ },
2525+ "createdAt": {
2626+ "type": "string",
2727+ "format": "datetime",
2828+ "description": "Client-declared timestamp when this livestream started."
2929+ },
3030+ "lastSeenAt": {
3131+ "type": "string",
3232+ "format": "datetime",
3333+ "description": "Client-declared timestamp when this livestream was last seen by the Streamplace station."
3434+ },
3535+ "endedAt": {
3636+ "type": "string",
3737+ "format": "datetime",
3838+ "description": "Client-declared timestamp when this livestream ended. Ended livestreams are not supposed to start up again."
3939+ },
4040+ "idleTimeoutSeconds": {
4141+ "type": "integer",
4242+ "description": "Time in seconds after which this livestream should be automatically ended if idle. Zero means no timeout."
4343+ },
4444+ "post": {
4545+ "type": "ref",
4646+ "ref": "com.atproto.repo.strongRef",
4747+ "description": "The post that announced this livestream."
4848+ },
4949+ "agent": {
5050+ "type": "string",
5151+ "description": "The source of the livestream, if available, in a User Agent format: `<product> / <product-version> <comment>` e.g. Streamplace/0.7.5 iOS"
5252+ },
5353+ "canonicalUrl": {
5454+ "type": "string",
5555+ "format": "uri",
5656+ "description": "The primary URL where this livestream can be viewed, if available."
5757+ },
5858+ "thumb": {
5959+ "type": "blob",
6060+ "accept": ["image/*"],
6161+ "maxSize": 1000000
6262+ },
6363+ "notificationSettings": {
6464+ "type": "ref",
6565+ "ref": "place.stream.livestream#notificationSettings"
6666+ }
6767+ }
6868+ }
6969+ },
7070+ "notificationSettings": {
7171+ "type": "object",
7272+ "required": [],
7373+ "properties": {
7474+ "pushNotification": {
7575+ "type": "boolean",
7676+ "description": "Whether this livestream should trigger a push notification to followers."
7777+ }
7878+ }
7979+ },
8080+ "livestreamView": {
8181+ "type": "object",
8282+ "required": ["uri", "cid", "author", "record", "indexedAt"],
8383+ "properties": {
8484+ "uri": { "type": "string", "format": "at-uri" },
8585+ "cid": { "type": "string", "format": "cid" },
8686+ "author": {
8787+ "type": "ref",
8888+ "ref": "app.bsky.actor.defs#profileViewBasic"
8989+ },
9090+ "record": { "type": "unknown" },
9191+ "indexedAt": { "type": "string", "format": "datetime" },
9292+ "viewerCount": {
9393+ "type": "ref",
9494+ "description": "The number of viewers watching this livestream. Use when you can't reasonably use #viewerCount directly.",
9595+ "ref": "#viewerCount"
9696+ }
9797+ }
9898+ },
9999+ "viewerCount": {
100100+ "type": "object",
101101+ "required": ["count"],
102102+ "properties": {
103103+ "count": { "type": "integer" }
104104+ }
105105+ },
106106+ "teleportArrival": {
107107+ "type": "object",
108108+ "required": ["teleportUri", "source", "viewerCount", "startsAt"],
109109+ "properties": {
110110+ "teleportUri": {
111111+ "type": "string",
112112+ "format": "at-uri",
113113+ "description": "The URI of the teleport record"
114114+ },
115115+ "source": {
116116+ "type": "ref",
117117+ "ref": "app.bsky.actor.defs#profileViewBasic",
118118+ "description": "The streamer who is teleporting their viewers here"
119119+ },
120120+ "chatProfile": {
121121+ "type": "ref",
122122+ "ref": "place.stream.chat.profile",
123123+ "description": "The chat profile of the source streamer"
124124+ },
125125+ "viewerCount": {
126126+ "type": "integer",
127127+ "description": "How many viewers are arriving from this teleport"
128128+ },
129129+ "startsAt": {
130130+ "type": "string",
131131+ "format": "datetime",
132132+ "description": "When this teleport started"
133133+ }
134134+ }
135135+ },
136136+ "teleportCanceled": {
137137+ "type": "object",
138138+ "required": ["teleportUri", "reason"],
139139+ "properties": {
140140+ "teleportUri": {
141141+ "type": "string",
142142+ "format": "at-uri",
143143+ "description": "The URI of the teleport record that was canceled"
144144+ },
145145+ "reason": {
146146+ "type": "string",
147147+ "enum": ["deleted", "denied", "expired"],
148148+ "description": "Why this teleport was canceled"
149149+ }
150150+ }
151151+ },
152152+ "streamplaceAnything": {
153153+ "type": "object",
154154+ "required": ["livestream"],
155155+ "properties": {
156156+ "livestream": {
157157+ "type": "union",
158158+ "refs": [
159159+ "#livestreamView",
160160+ "#viewerCount",
161161+ "#teleportArrival",
162162+ "#teleportCanceled",
163163+ "place.stream.defs#blockView",
164164+ "place.stream.defs#renditions",
165165+ "place.stream.defs#rendition",
166166+ "place.stream.chat.defs#messageView",
167167+ "place.stream.chat.defs#pinnedRecordView"
168168+ ]
169169+ }
170170+ }
171171+ }
172172+ }
173173+}
+4
utils/lexicons/index.ts
···11export * as OnlineTimtinkersBotCommand from "./types/online/timtinkers/bot/command.ts";
22+export * as OnlineTimtinkersBotShoutout from "./types/online/timtinkers/bot/shoutout.ts";
23export * as PlaceStreamBadgeDefs from "./types/place/stream/badge/defs.ts";
34export * as PlaceStreamChatDefs from "./types/place/stream/chat/defs.ts";
45export * as PlaceStreamChatMessage from "./types/place/stream/chat/message.ts";
56export * as PlaceStreamChatPinnedRecord from "./types/place/stream/chat/pinnedRecord.ts";
67export * as PlaceStreamChatProfile from "./types/place/stream/chat/profile.ts";
88+export * as PlaceStreamDefs from "./types/place/stream/defs.ts";
79export * as PlaceStreamEmoteDefs from "./types/place/stream/emote/defs.ts";
1010+export * as PlaceStreamLiveTeleport from "./types/place/stream/live/teleport.ts";
1111+export * as PlaceStreamLivestream from "./types/place/stream/livestream.ts";
812export * as PlaceStreamRichtextFacet from "./types/place/stream/richtext/facet.ts";
···11+import type {} from "@atcute/lexicons";
22+import * as v from "@atcute/lexicons/validations";
33+import type {} from "@atcute/lexicons/ambient";
44+55+const _mainSchema = /*#__PURE__*/ v.record(
66+ /*#__PURE__*/ v.tidString(),
77+ /*#__PURE__*/ v.object({
88+ $type: /*#__PURE__*/ v.literal("place.stream.live.teleport"),
99+ /**
1010+ * The time limit in seconds for the teleport. If not set, the teleport is permanent. Must be at least 60 seconds, and no more than 32,400 seconds (9 hours).
1111+ * @minimum 60
1212+ * @maximum 32400
1313+ */
1414+ durationSeconds: /*#__PURE__*/ v.optional(
1515+ /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [
1616+ /*#__PURE__*/ v.integerRange(60, 32400),
1717+ ]),
1818+ ),
1919+ /**
2020+ * The time the teleport becomes active.
2121+ */
2222+ startsAt: /*#__PURE__*/ v.datetimeString(),
2323+ /**
2424+ * The DID of the streamer to teleport to.
2525+ */
2626+ streamer: /*#__PURE__*/ v.didString(),
2727+ }),
2828+);
2929+3030+type main$schematype = typeof _mainSchema;
3131+3232+export interface mainSchema extends main$schematype {}
3333+3434+export const mainSchema = _mainSchema as mainSchema;
3535+3636+export interface Main extends v.InferInput<typeof mainSchema> {}
3737+3838+declare module "@atcute/lexicons/ambient" {
3939+ interface Records {
4040+ "place.stream.live.teleport": mainSchema;
4141+ }
4242+}
+212
utils/lexicons/types/place/stream/livestream.ts
···11+import type {} from "@atcute/lexicons";
22+import * as v from "@atcute/lexicons/validations";
33+import type {} from "@atcute/lexicons/ambient";
44+import * as AppBskyActorDefs from "@atcute/bluesky/types/app/actor/defs";
55+import * as ComAtprotoRepoStrongRef from "@atcute/atproto/types/repo/strongRef";
66+import * as PlaceStreamChatDefs from "./chat/defs.ts";
77+import * as PlaceStreamChatProfile from "./chat/profile.ts";
88+import * as PlaceStreamDefs from "./defs.ts";
99+1010+const _livestreamViewSchema = /*#__PURE__*/ v.object({
1111+ $type: /*#__PURE__*/ v.optional(
1212+ /*#__PURE__*/ v.literal("place.stream.livestream#livestreamView"),
1313+ ),
1414+ get author() {
1515+ return AppBskyActorDefs.profileViewBasicSchema;
1616+ },
1717+ cid: /*#__PURE__*/ v.cidString(),
1818+ indexedAt: /*#__PURE__*/ v.datetimeString(),
1919+ record: /*#__PURE__*/ v.unknown(),
2020+ uri: /*#__PURE__*/ v.resourceUriString(),
2121+ /**
2222+ * The number of viewers watching this livestream. Use when you can't reasonably use #viewerCount directly.
2323+ */
2424+ get viewerCount() {
2525+ return /*#__PURE__*/ v.optional(viewerCountSchema);
2626+ },
2727+});
2828+const _mainSchema = /*#__PURE__*/ v.record(
2929+ /*#__PURE__*/ v.tidString(),
3030+ /*#__PURE__*/ v.object({
3131+ $type: /*#__PURE__*/ v.literal("place.stream.livestream"),
3232+ /**
3333+ * The source of the livestream, if available, in a User Agent format: `<product> / <product-version> <comment>` e.g. Streamplace/0.7.5 iOS
3434+ */
3535+ agent: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
3636+ /**
3737+ * The primary URL where this livestream can be viewed, if available.
3838+ */
3939+ canonicalUrl: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.genericUriString()),
4040+ /**
4141+ * Client-declared timestamp when this livestream started.
4242+ */
4343+ createdAt: /*#__PURE__*/ v.datetimeString(),
4444+ /**
4545+ * Client-declared timestamp when this livestream ended. Ended livestreams are not supposed to start up again.
4646+ */
4747+ endedAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()),
4848+ /**
4949+ * Time in seconds after which this livestream should be automatically ended if idle. Zero means no timeout.
5050+ */
5151+ idleTimeoutSeconds: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()),
5252+ /**
5353+ * Client-declared timestamp when this livestream was last seen by the Streamplace station.
5454+ */
5555+ lastSeenAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()),
5656+ get notificationSettings() {
5757+ return /*#__PURE__*/ v.optional(notificationSettingsSchema);
5858+ },
5959+ /**
6060+ * The post that announced this livestream.
6161+ */
6262+ get post() {
6363+ return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema);
6464+ },
6565+ /**
6666+ * @accept image/*
6767+ * @maxSize 1000000
6868+ */
6969+ thumb: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()),
7070+ /**
7171+ * The title of the livestream, as it will be announced to followers.
7272+ * @maxLength 1400
7373+ * @maxGraphemes 140
7474+ */
7575+ title: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
7676+ /*#__PURE__*/ v.stringLength(0, 1400),
7777+ /*#__PURE__*/ v.stringGraphemes(0, 140),
7878+ ]),
7979+ /**
8080+ * The URL where this stream can be found. This is primarily a hint for other Streamplace nodes to locate and replicate the stream.
8181+ */
8282+ url: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.genericUriString()),
8383+ }),
8484+);
8585+const _notificationSettingsSchema = /*#__PURE__*/ v.object({
8686+ $type: /*#__PURE__*/ v.optional(
8787+ /*#__PURE__*/ v.literal("place.stream.livestream#notificationSettings"),
8888+ ),
8989+ /**
9090+ * Whether this livestream should trigger a push notification to followers.
9191+ */
9292+ pushNotification: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()),
9393+});
9494+const _streamplaceAnythingSchema = /*#__PURE__*/ v.object({
9595+ $type: /*#__PURE__*/ v.optional(
9696+ /*#__PURE__*/ v.literal("place.stream.livestream#streamplaceAnything"),
9797+ ),
9898+ get livestream() {
9999+ return /*#__PURE__*/ v.variant([
100100+ PlaceStreamChatDefs.messageViewSchema,
101101+ PlaceStreamChatDefs.pinnedRecordViewSchema,
102102+ PlaceStreamDefs.blockViewSchema,
103103+ PlaceStreamDefs.renditionSchema,
104104+ PlaceStreamDefs.renditionsSchema,
105105+ livestreamViewSchema,
106106+ teleportArrivalSchema,
107107+ teleportCanceledSchema,
108108+ viewerCountSchema,
109109+ ]);
110110+ },
111111+});
112112+const _teleportArrivalSchema = /*#__PURE__*/ v.object({
113113+ $type: /*#__PURE__*/ v.optional(
114114+ /*#__PURE__*/ v.literal("place.stream.livestream#teleportArrival"),
115115+ ),
116116+ /**
117117+ * The chat profile of the source streamer
118118+ */
119119+ get chatProfile() {
120120+ return /*#__PURE__*/ v.optional(PlaceStreamChatProfile.mainSchema);
121121+ },
122122+ /**
123123+ * The streamer who is teleporting their viewers here
124124+ */
125125+ get source() {
126126+ return AppBskyActorDefs.profileViewBasicSchema;
127127+ },
128128+ /**
129129+ * When this teleport started
130130+ */
131131+ startsAt: /*#__PURE__*/ v.datetimeString(),
132132+ /**
133133+ * The URI of the teleport record
134134+ */
135135+ teleportUri: /*#__PURE__*/ v.resourceUriString(),
136136+ /**
137137+ * How many viewers are arriving from this teleport
138138+ */
139139+ viewerCount: /*#__PURE__*/ v.integer(),
140140+});
141141+const _teleportCanceledSchema = /*#__PURE__*/ v.object({
142142+ $type: /*#__PURE__*/ v.optional(
143143+ /*#__PURE__*/ v.literal("place.stream.livestream#teleportCanceled"),
144144+ ),
145145+ /**
146146+ * Why this teleport was canceled
147147+ */
148148+ reason: /*#__PURE__*/ v.literalEnum(["deleted", "denied", "expired"]),
149149+ /**
150150+ * The URI of the teleport record that was canceled
151151+ */
152152+ teleportUri: /*#__PURE__*/ v.resourceUriString(),
153153+});
154154+const _viewerCountSchema = /*#__PURE__*/ v.object({
155155+ $type: /*#__PURE__*/ v.optional(
156156+ /*#__PURE__*/ v.literal("place.stream.livestream#viewerCount"),
157157+ ),
158158+ count: /*#__PURE__*/ v.integer(),
159159+});
160160+161161+type livestreamView$schematype = typeof _livestreamViewSchema;
162162+type main$schematype = typeof _mainSchema;
163163+type notificationSettings$schematype = typeof _notificationSettingsSchema;
164164+type streamplaceAnything$schematype = typeof _streamplaceAnythingSchema;
165165+type teleportArrival$schematype = typeof _teleportArrivalSchema;
166166+type teleportCanceled$schematype = typeof _teleportCanceledSchema;
167167+type viewerCount$schematype = typeof _viewerCountSchema;
168168+169169+export interface livestreamViewSchema extends livestreamView$schematype {}
170170+export interface mainSchema extends main$schematype {}
171171+export interface notificationSettingsSchema extends notificationSettings$schematype {}
172172+export interface streamplaceAnythingSchema extends streamplaceAnything$schematype {}
173173+export interface teleportArrivalSchema extends teleportArrival$schematype {}
174174+export interface teleportCanceledSchema extends teleportCanceled$schematype {}
175175+export interface viewerCountSchema extends viewerCount$schematype {}
176176+177177+export const livestreamViewSchema =
178178+ _livestreamViewSchema as livestreamViewSchema;
179179+export const mainSchema = _mainSchema as mainSchema;
180180+export const notificationSettingsSchema =
181181+ _notificationSettingsSchema as notificationSettingsSchema;
182182+export const streamplaceAnythingSchema =
183183+ _streamplaceAnythingSchema as streamplaceAnythingSchema;
184184+export const teleportArrivalSchema =
185185+ _teleportArrivalSchema as teleportArrivalSchema;
186186+export const teleportCanceledSchema =
187187+ _teleportCanceledSchema as teleportCanceledSchema;
188188+export const viewerCountSchema = _viewerCountSchema as viewerCountSchema;
189189+190190+export interface LivestreamView extends v.InferInput<
191191+ typeof livestreamViewSchema
192192+> {}
193193+export interface Main extends v.InferInput<typeof mainSchema> {}
194194+export interface NotificationSettings extends v.InferInput<
195195+ typeof notificationSettingsSchema
196196+> {}
197197+export interface StreamplaceAnything extends v.InferInput<
198198+ typeof streamplaceAnythingSchema
199199+> {}
200200+export interface TeleportArrival extends v.InferInput<
201201+ typeof teleportArrivalSchema
202202+> {}
203203+export interface TeleportCanceled extends v.InferInput<
204204+ typeof teleportCanceledSchema
205205+> {}
206206+export interface ViewerCount extends v.InferInput<typeof viewerCountSchema> {}
207207+208208+declare module "@atcute/lexicons/ambient" {
209209+ interface Records {
210210+ "place.stream.livestream": mainSchema;
211211+ }
212212+}