@y-sweet/sdk
A JavaScript/TypeScript library for NodeJS-like environments. It allows you to create ClientToken
s for authenticating clients, enabling them to read and write Y-Sweet documents. Additionally, it provides functionality to create and update Y-Sweet documents.
Installation
npm install @y-sweet/sdk
The auth endpoint
The Y-Sweet SDK is primarily used when implementing the auth endpoint for your application. This endpoint is used by the YSweetProvider
on the client to refresh ClientToken
s which authorize the client to read and write to a shared document. If you are using a meta-framework like NextJS or Remix, you can implement this auth endpoint as an API route, or you can use a server framework like ExpressJS or Hono.
Here’s an example of how the auth endpoint might be implemented using NextJS’s Route Handlers:
import { DocumentManager } from '@y-sweet/sdk'
const manager = new DocumentManager(process.env.CONNECTION_STRING)
export async function POST(request: Request) {
// In a production app, this is where you'd authenticate the user
// and check that they are authorized to access the doc.
const { docId } = await request.json()
const clientToken = await manager.getOrCreateDocAndToken(docId)
return Response.json(clientToken)
}
DocumentManager
You’ll use the DocumentManager
class to create ClientTokens
and perform other types of actions like reading and writing documents from the server. The DocumentManager
must be instantiated with a connection string (starting with ys://
or yss://
).
import { DocumentManager } from '@y-sweet/sdk'
const manager = new DocumentManager(process.env.CONNECTION_STRING)
manager.getOrCreateDocAndToken(docId)
The getOrCreateDocAndToken
function is a convenience method that creates a doc if it doesn’t exist and, when await
ed, returns a ClientToken
that the client can use to sync its local document with others. You will typically call this method as part of your auth endpoint implementation and return the client token as the auth endpoint’s response body.
import { DocumentManager } from '@y-sweet/sdk'
const manager = new DocumentManager(process.env.CONNECTION_STRING)
export async function POST(request: Request) {
// In a production app, this is where you'd authenticate the user
// and check that they are authorized to access the doc.
const { docId } = await request.json()
const clientToken = await manager.getOrCreateDocAndToken(docId)
return Response.json(clientToken)
}
manager.createDoc([docId])
The createDoc
function creates a Y-Sweet doc. If no docId
is provided, it will generate one and, when await
ed, return it in the DocCreationResult
. It is typically recommended to use getOrCreateDocAndToken()
instead of this function.
manager.getClientToken(docId)
The getClientToken
function returns a Promise which, when await
ed, returns a ClientToken
that authorizes a client to read and write to a shared Y-Sweet document. It is typically recommended to use getOrCreateDocAndToken()
instead of this function.
manager.getDocAsUpdate(docId)
The getDocAsUpdate
function, when await
ed, returns an entire Y-Sweet document, represented as a Yjs update byte string (in the form of a Uint8Array
). This Yjs update byte string can then be turned back into a Yjs document as follows:
import * as Y from 'yjs'
let update = await manager.getDocAsUpdate(docId)
let doc = new Y.Doc()
doc.transact(() => {
Y.applyUpdate(doc, update)
})
manager.updateDoc(docId, updateByteString)
The updateDoc
function updates a Y-Sweet document with the given Yjs update byte string (in the form of a Uint8Array
). This Yjs update byte string can be generated from a Yjs document as follows:
import * as Y from 'yjs'
let doc = new Y.Doc()
// Modify the document...
let update = Y.encodeStateAsUpdate(doc)
await manager.updateDoc(docId, update)
Types
type ClientToken = {
url: string
baseUrl: string
docId: string
token?: string
}
type DocCreationResult = {
docId: string
}
type YSweetErrorPayload = {
address: string
code: "ServerRefused"
port: number
url: string
} | {
code: "ServerError"
message: string
status: number
url: string
} | {
code: "NoAuthProvided"
} | {
code: "InvalidAuthProvided"
} | {
code: "Unknown"
message: string
}