Work on structures

This commit is contained in:
Jesse Wierzbinski 2024-03-18 15:28:51 -10:00
parent b5b163e141
commit 3a1dcde965
No known key found for this signature in database
4 changed files with 106 additions and 116 deletions

View file

@ -1,5 +1,8 @@
# Introduction # Introduction
> [!NOTE]
> You are looking at the documentation for `Lysand 1.1`, released in March 2024 after revision of the original `Lysand 1.0` specification published in September 2023.
The Lysand Protocol is designed as a communication medium for federated applications, leveraging the HTTP stack. Its simplicity ensures ease of implementation and comprehension. The Lysand Protocol is designed as a communication medium for federated applications, leveraging the HTTP stack. Its simplicity ensures ease of implementation and comprehension.
Distinct from ActivityPub, Lysand incorporates an extensive range of built-in features tailored for social media applications. It prioritizes security and privacy by default. Distinct from ActivityPub, Lysand incorporates an extensive range of built-in features tailored for social media applications. It prioritizes security and privacy by default.

View file

@ -1,14 +1,14 @@
# Collections # Collections
Collections are JSON objects that contain a list of other objects. They are used to represent a list of objects, such as a list of publications or a list of users. Collections are structured JSON objects that encapsulate a group of related items. They are typically used to represent a set of similar objects, such as a series of publications or a group of users.
Collections can be represented as such in TypeScript: Here's how a Collections can be represented in TypeScript:
```ts ```ts
interface Collection<T> { interface Collections<T> {
first: string; first: string;
last: string; last: string;
total_items: number; totalCount: number;
author: string; author: string;
next?: string; next?: string;
prev?: string; prev?: string;
@ -16,16 +16,18 @@ interface Collection<T> {
} }
``` ```
Collections **MUST** contain a `first` field that contains the URI of the first item in the collection, and a `last` field that contains the URI of the last item in the collection. Collections are intended to be served in a paginated format, with a set of items and links to the next and previous sets of items. For example, if a user has a collection of Notes that is several thousand items long, the server can serve the first 50 items when requested and provide a link to the next 50 items.
Collections **MUST** contain a `total_items` field that contains the total number of items in the collection. Collections **MUST** include:
- A `first` field that holds the URI of the first page of collection items, and a `last` field that holds the URI of the last page of collection items. In the case that there is only one page, `first` and `last` should be the same.
- A `totalCount` field that holds the total number of items in the set, across all pages.
- A `next` field that holds the URI of the next set of items, and a `prev` field that holds the URI of the previous set of items. These fields are optional if the user is on the first or last set of items.
- An `items` field that holds a paginated array of items in the set. (for example, a series of publications or a group of users)
- An `author` field that holds the URI of the entity that created the set (such as the [Actor](../objects/actors) that creates posts). This is used to identify the creator of the set for signing. If the set is generated by the server and not by a specific user (such as the Endorsement set with the [ServerEndorsement Extension](/extensions/server-endorsement)), the `author` should be the server actor's URI.
Collections **MUST** contain a `next` field that contains the URI of the next page of items in the collection, and a `prev` field that contains the URI of the previous page of items in the collection, unless the user is on the first or last page of the collection. `first`, `last`, `prev` and `next` URIs may use query strings to specify the range of items to be returned. For example, a `first` URI may look like `https://example.com/users/uuid/notes?start=0&end=50`.
Collections **MUST** contain an `items` field that contains an array of items in the collection. (for example, a list of publications or a list of users) It is recommended that pages are limited to a hundred elements at most, but also at least twenty elements, so as to not overload federation with large payloads.
## Properties > [!WARNING]
> Like any other payload, Collections are to be signed using the author's private key. Unsigned collections are not valid.
### Author
Collections **MUST** contain an `author` field that contains the URI of the user that created the collection. It is used to identify the author of the collection. If this collection is made by the server and not by a specific user (such as the Endorserment collection with the [ServerEndorsement Extension](/extensions/server-endorsement)), it must be the server actor's URI.

View file

@ -1,11 +1,11 @@
# ContentFormat # ContentFormat Protocol
A `ContentFormat` structure can be represented as such in TypeScript: The `ContentFormat` structure, as represented below in TypeScript, is a flexible and robust way to handle various types of content. It is designed to accommodate a wide range of content types and provide additional metadata about the content.
```ts ```ts
interface ContentFormat { interface ContentFormat {
[contentType: string]: {
content: string; content: string;
content_type: string;
description?: string; description?: string;
size?: number; size?: number;
hash?: { hash?: {
@ -21,84 +21,82 @@ interface ContentFormat {
height?: number; height?: number;
duration?: number; duration?: number;
} }
```
An example value would be:
```json
{
"content": "Hello, world!",
"content_type": "text/plain"
} }
``` ```
Another example: Here's an example of how this structure can be used:
```json ```json
{ {
"text/plain": {
"content": "Hello, world!"
}
}
```
And another example:
```json
{
"image/png": {
"content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.png", "content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.png",
"content_type": "image/png", "description": "A jolly horse running through mountains",
"description": "A jolly horse running in the mountains",
"size": 123456, "size": 123456,
"hash": { "hash": {
"sha256": "91714fc336210d459d4f9d9233de663be2b87ffe923f1cfd76ece9d06f7c965d" "sha256": "91714fc336210d459d4f9d9233de663be2b87ffe923f1cfd76ece9d06f7c965d"
} }
} }
}
``` ```
The `contents` field is a string that contains the actual content of the object. The `content_type` field is a string that contains the MIME type of the content. The `content` field holds the actual content of the object. This content can be either a string containing plaintext, or a URI to the actual content when it cannot be encoded as this format.
The `content` and `content_type` fields are required on all `ContentFormat` objects, but other fields are optional. The `description` field provides a brief summary of the content. This is particularly useful for accessibility purposes, such as for visually impaired users, or when the content fails to load. It's an optional field, and if not provided, it's assumed that the content doesn't have a description.
The `description` field is a string that contains a description of the content. It is used to describe the content to users that cannot see the content, such as users that are blind, or when the content does not load properly. It is not required on all `ContentFormat` objects. If it is not provided, it is assumed that the content does not have a description. The `size` field, also optional, indicates the size of the content in bytes. While it's not necessary for text content, it's recommended for binary content like images, videos, and audio. This information helps clients decide whether to download the content based on its size.
The `size` field is a number that contains the size of the content in bytes. It is not required on all `ContentFormat` objects. If it is not provided, it is assumed that the content size is not specified. The `ContentFormat` structure is designed to handle multiple formats of the same file. For instance, a PNG image and a WebP image. However, it's not intended for formats that can't be converted to others, like PDFs. These should only be stored once.
It is generally not needed to provide content size for text content, but it is recommended to provide content size for binary content, such as images, videos, and audio. This is useful for clients to determine if they should download the content or not. Here's an acceptable use case:
It is expected that files in an array of `ContentFormat` objects (when used to store URLs to files) are the same file, but in different formats. For example, a PNG image and a WebP image. Files in formats such as PDF that cannot be converted to other formats should only be stored once.
For example, this is acceptable:
```json ```json
[
{ {
"image/png": {
"content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.png", "content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.png",
"content_type": "image/png", "description": "A jolly horse running through mountains",
"description": "A jolly horse running in the mountains",
"hash": { "hash": {
"sha256": "91714fc336210d459d4f9d9233de663be2b87ffe923f1cfd76ece9d06f7c965d" "sha256": "91714fc336210d459d4f9d9233de663be2b87ffe923f1cfd76ece9d06f7c965d"
} }
}, },
{ "image/webp": {
"content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.webp", "content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.webp",
"content_type": "image/webp", "description": "A jolly horse running through mountains",
"description": "A jolly horse running in the mountains",
"hash": { "hash": {
"sha256": "b493d48364afe44d11c0165cf470a4164d1e2609911ef998be868d46ade3de4e" "sha256": "b493d48364afe44d11c0165cf470a4164d1e2609911ef998be868d46ade3de4e"
},
} }
] }
}
``` ```
But this is not: However, this is not:
```json ```json
[
{ {
"image/png": {
"content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.png", "content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.png",
"content_type": "image/png", "description": "A jolly horse running through mountains"
"description": "A jolly horse running in the mountains"
}, },
{ "image/webp": {
"content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.webp", "content": "https://cdn.example.com/attachments/ece2f9d9-27d7-457d-b657-4ce9172bdcf8.webp",
"content_type": "image/webp", "description": "A jolly horse running through mountains"
"description": "A jolly horse running in the mountains",
}, },
{ "application/pdf": {
"content": "https://cdn.example.com/attachments/anotherfile.pdf", "content": "https://cdn.example.com/attachments/anotherfile.pdf",
"content_type": "application/pdf", "description": "An informative PDF document on macroeconomics"
"description": "A PDF file about macroeconomics" }
} }
]
``` ```
Each array of ContentFormat objects should be considered as a SINGLE FILE, and not multiple files. The multiple formats are only meant to save bandwidth. Each `ContentFormat` object should be treated as a **single file in multiple optional formats**, not as multiple files. The multiple formats are intended to optimize bandwidth usage.
If optional fields are provided on one object in the array, they should be provided on all objects in the array. For example, if the `description` field is provided on one object, it should be provided on all objects (since they are the same file). If optional fields are provided for one object in the `ContentFormat`, they should be provided for all objects in the `ContentFormat`. For instance, if the `description` field is provided for one object, it should be provided for all objects, as they represent the same file.

View file

@ -1,55 +1,42 @@
# Custom Emojis # Custom Emojis in Lysand
Lysand supports custom emojis. They are represented as such in TypeScript: Lysand supports the use of custom emojis. Here's how they are represented in TypeScript:
```ts ```ts
interface Emoji { interface Emoji {
name: string; name: string;
alt?: string; alt?: string;
url: ContentFormat[]; url: ContentFormat;
} }
``` ```
Lysand custom emojis are implemented as part of an official optional extension to the protocol. See [Protocol Extensions](#protocol-extensions) for more information. Custom emojis in Lysand are part of an optional extension to the protocol. For more details, refer to the [Protocol Extensions](../extensions) section.
Servers **MAY** choose not to implement custom emojis, but it is recommended that they do so. While servers have the discretion to implement custom emojis, it is highly recommended for a richer user interaction.
Here's an example of a custom emoji representation:
An example value would be:
```json ```json
{ {
"name": "happy_face", "name": "happy_face",
"alt": "A happy face emoji.", "alt": "A happy face emoji.",
"url": [ "url": {
{ "image/webp": {
"content": "https://cdn.example.com/emojis/happy_face.webp", "content": "https://cdn.example.com/emojis/happy_face.webp",
"content_type": "image/webp"
} }
] }
} }
``` ```
The `name` field **MUST** be a string that contains only alphanumeric characters, underscores, and dashes. It **MUST NOT** contain any spaces or other special characters. The `name` field is a string that should only contain alphanumeric characters, underscores, and dashes. Spaces or other special characters are not allowed. It should match the following regex: `/^[a-zA-Z0-9_-]+$/`.
It **MUST** match this regex: `/^[a-zA-Z0-9_-]+$/` The `url` field is a [ContentFormat](./content-format), serving as a list of URLs where the emoji can be accessed. It is mandatory for all emojis and should contain at least one URL. The `url` field should be a binary image format, such as `image/png` or `image/jpeg`. Text formats like `text/plain` or `text/html` are not acceptable.
--- The `alt` field is an optional string that provides the alt text for the emoji. This is particularly useful for visually impaired users or when the emoji fails to load. If not provided, it's assumed that the emoji doesn't have an alt text.
The `url` field is an array that contains a list of `ContentFormat` objects. It is meant to serve as a list of URLs that the emoji can be accessed at. It is required on all emojis, and **MUST** contain at least one URL. While emojis are typically small and don't consume much bandwidth, servers may choose to transcode emojis into more modern formats like WebP, AVIF, JXL, or HEIF for optimization. Clients should display the most modern format they support. If they don't support any modern formats, they should display the original format.
The `url` field **MUST** be a binary image format, such as `image/png` or `image/jpeg`. The `url` field **MUST NOT** be a text format, such as `text/plain` or `text/html`. > [!NOTE]
> Servers might find it beneficial to use a CDN like Cloudflare that can automatically convert images to modern formats. This approach offloads image processing from the server and enhances performance for clients.
--- The size of emojis is not standardized and is left to the server's discretion. Servers may choose to limit the size of emojis, but it's not mandatory. As a general guideline, an upper limit of a few hundred kilobytes is recommended to avoid excessive bandwidth usage.
The `alt` field is a string that contains the alt text for the emoji. It is used to describe the emoji to users that cannot see the emoji, such as users that are blind, or when the emoji does not load properly.
The `alt` field is not required on all emojis. If it is not provided, it is assumed that the emoji does not have an alt text.
---
Emojis normally do not need to be transcoded into more modern formats, as they are typically small and do not take up much bandwidth. However, servers **MAY** choose to transcode emojis into more modern formats, such as WebP, AVIF, JXL, or HEIF.
Clients should display the most modern format that they support, such as WebP, AVIF, JXL, or HEIF. If the client does not support any modern formats, it should display the original format.
> **Note:** Servers may find it useful to use a CDN that can automatically convert images to modern formats, such as Cloudflare. This will offload image processing from the server, and improve performance for clients.
Emoji size is not standardized, and is up to the server to decide. Servers **MAY** choose to limit the size of emojis, but it is not required. Generally, an upper limit of a few hundred kilobytes is recommended so as to not take up too much bandwidth.