Skip to content

Commit

Permalink
[y sweet] support optional initialClientToken for YSweetProvider (#319)
Browse files Browse the repository at this point in the history
This updates the `YSweetProvider` (and the React `<YDocProvider>`) to
take an optional `initialClientToken`. This can be used to cut out one
server roundtrip if the client token is obtained at render time.
  • Loading branch information
rolyatmax authored Oct 15, 2024
1 parent 17779f7 commit d098663
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 7 deletions.
7 changes: 5 additions & 2 deletions js-pkg/client/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export type YSweetProviderParams = {
resyncInterval?: number
maxBackoffTime?: number
disableBc?: boolean
initialClientToken?: ClientToken
}

/**
Expand Down Expand Up @@ -526,8 +527,10 @@ export async function ySweetProviderWrapper(
authEndpoint: AuthEndpoint,
roomname: string,
doc: Y.Doc,
providerParams: YSweetProviderParams = {},
wrapperParams: YSweetProviderParams = {},
): Promise<YSweetProviderWithClientToken> {
let { initialClientToken, ...providerParams } = wrapperParams

// we use an observable that lives outside the provider to store event listeners
// so that we can re-subscribe to events when the provider is re-created
const observable = new Observable<string>()
Expand All @@ -538,7 +541,7 @@ export async function ySweetProviderWrapper(
const awareness = providerParams.awareness ?? new awarenessProtocol.Awareness(doc)
providerParams = { ...providerParams, awareness }

let _clientToken = await getClientToken(authEndpoint, roomname)
let _clientToken = initialClientToken ?? (await getClientToken(authEndpoint, roomname))
let _provider = new YSweetProvider(_clientToken.url, roomname, doc, {
...updateProviderParams(providerParams, _clientToken),
})
Expand Down
14 changes: 10 additions & 4 deletions js-pkg/react/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
debuggerUrl,
} from '@y-sweet/client'
import type { AuthEndpoint, YSweetProviderWithClientToken } from '@y-sweet/client'
import type { ClientToken } from '@y-sweet/sdk'
import type { ReactNode } from 'react'
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import type { Awareness } from 'y-protocols/awareness'
Expand Down Expand Up @@ -171,22 +172,26 @@ export type YDocProviderProps = {
/** The children to render. */
children: ReactNode

/** Response of a `getConnectionKey` call, passed from server to client. */
/** The doc id to use for the Y.Doc. */
docId: string

/** The endpoint to use for authentication. */
/** The endpoint to use for authentication or an async function that returns a client token. */
authEndpoint: AuthEndpoint

/** An optional initial client token to use for the Y.Doc. This will be used initially, and if
* the client token expires, the `authEndpoint` will be called to get a new client token. */
initialClientToken?: ClientToken

/** If set to a string, the URL query parameter with this name
* will be set to the doc id from connectionKey. */
* will be set to the doc id provided. */
setQueryParam?: string
}

/**
* A React component that provides a Y.Doc instance to its children given an auth endpoint and a doc id.
*/
export function YDocProvider(props: YDocProviderProps) {
const { children, docId, authEndpoint } = props
const { children, docId, authEndpoint, initialClientToken } = props

const [ctx, setCtx] = useState<YjsContextType | null>(null)

Expand All @@ -197,6 +202,7 @@ export function YDocProvider(props: YDocProviderProps) {

;(async () => {
provider = await createYjsProvider(doc, docId, authEndpoint, {
initialClientToken,
// TODO: this disables local cross-tab communication, which makes
// debugging easier, but should be re-enabled eventually
disableBc: true,
Expand Down
218 changes: 217 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d098663

Please sign in to comment.