kopia lustrzana https://github.com/Tldraw/Tldraw
fixes
rodzic
2cae8463ac
commit
53a903b88c
|
@ -81,11 +81,10 @@ export class TLDrawDurableObject extends TLServer {
|
|||
this.analyticsPgClient = new PgClient({
|
||||
connectionString: env.ANALYTICS_DB_HYPERDRIVE.connectionString,
|
||||
})
|
||||
controller.blockConcurrencyWhile(async () => {
|
||||
await this.analyticsPgClient.connect()
|
||||
})
|
||||
|
||||
controller.blockConcurrencyWhile(async () => {
|
||||
await this.analyticsPgClient.connect()
|
||||
|
||||
const existingDocumentInfo = (await this.storage.get('documentInfo')) as DocumentInfo | null
|
||||
if (existingDocumentInfo?.version !== CURRENT_DOCUMENT_INFO_VERSION) {
|
||||
this._documentInfo = null
|
||||
|
@ -197,6 +196,7 @@ export class TLDrawDurableObject extends TLServer {
|
|||
|
||||
const newRoom = new TLSyncRoom(
|
||||
roomState.room.schema,
|
||||
(point) => report(this.analyticsPgClient, this.env.TLDRAW_ENV ?? 'undefined', point),
|
||||
{
|
||||
clock: oldRoom.clock + 1,
|
||||
documents: snapshot.documents.map((d) => ({
|
||||
|
@ -205,8 +205,7 @@ export class TLDrawDurableObject extends TLServer {
|
|||
})),
|
||||
schema: snapshot.schema,
|
||||
tombstones,
|
||||
},
|
||||
(point) => report(this.analyticsPgClient, this.env.TLDRAW_ENV ?? 'undefined', point)
|
||||
}
|
||||
)
|
||||
|
||||
// replace room with new one and kick out all the clients
|
||||
|
@ -248,6 +247,8 @@ export class TLDrawDurableObject extends TLServer {
|
|||
persistenceKey: this.documentInfo.slug!,
|
||||
sessionKey,
|
||||
storeId,
|
||||
reportTLAnalytics: (point) =>
|
||||
report(this.analyticsPgClient, this.env.TLDRAW_ENV ?? 'undefined', point),
|
||||
})
|
||||
)
|
||||
} catch (e: any) {
|
||||
|
|
|
@ -5,10 +5,8 @@ import { Client as PgClient } from 'pg'
|
|||
const SAMPLE_RATE = 0.05
|
||||
|
||||
export function report(client: PgClient, tldraw_env: string, point: TLAnalyticsPoint) {
|
||||
console.log('reporting')
|
||||
try {
|
||||
if (shouldSample()) {
|
||||
console.log('shouldSample')
|
||||
let promise = null
|
||||
|
||||
switch (point.type) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export { type TLAnalyticsPoint } from './lib/TLAnalytics'
|
||||
export { NO_TL_ANALYTICS, type TLAnalyticsPoint } from './lib/TLAnalytics'
|
||||
export { TLServer, type DBLoadResult } from './lib/TLServer'
|
||||
export {
|
||||
TLSyncClient,
|
||||
|
|
|
@ -3,3 +3,7 @@ export type TLAnalyticsPoint = {
|
|||
length: number
|
||||
num_clients: number
|
||||
}
|
||||
|
||||
export const NO_TL_ANALYTICS = (_: TLAnalyticsPoint) => {
|
||||
// noop
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { nanoid } from 'nanoid'
|
||||
import * as WebSocket from 'ws'
|
||||
import { ServerSocketAdapter } from './ServerSocketAdapter'
|
||||
import { TLAnalyticsPoint } from './TLAnalytics'
|
||||
import { RoomSnapshot, TLSyncRoom } from './TLSyncRoom'
|
||||
import { JsonChunkAssembler } from './chunk'
|
||||
import { schema } from './schema'
|
||||
|
@ -28,7 +29,10 @@ export type DBLoadResult =
|
|||
export abstract class TLServer {
|
||||
schema = schema
|
||||
|
||||
async getInitialRoomState(persistenceKey: string): Promise<[RoomState, LoadKind]> {
|
||||
async getInitialRoomState(
|
||||
persistenceKey: string,
|
||||
reportTLAnaytics: (point: TLAnalyticsPoint) => void
|
||||
): Promise<[RoomState, LoadKind]> {
|
||||
let roomState = this.getRoomForPersistenceKey(persistenceKey)
|
||||
|
||||
let roomOpenKind = 'open' as 'open' | 'reopen' | 'new'
|
||||
|
@ -47,7 +51,7 @@ export abstract class TLServer {
|
|||
|
||||
roomState = {
|
||||
persistenceKey,
|
||||
room: new TLSyncRoom(this.schema, data.snapshot),
|
||||
room: new TLSyncRoom(this.schema, reportTLAnaytics, data.snapshot),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +62,7 @@ export abstract class TLServer {
|
|||
|
||||
roomState = {
|
||||
persistenceKey,
|
||||
room: new TLSyncRoom(this.schema),
|
||||
room: new TLSyncRoom(this.schema, reportTLAnaytics),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,14 +111,19 @@ export abstract class TLServer {
|
|||
persistenceKey,
|
||||
sessionKey,
|
||||
storeId,
|
||||
reportTLAnalytics,
|
||||
}: {
|
||||
socket: WebSocket.WebSocket
|
||||
persistenceKey: string
|
||||
sessionKey: string
|
||||
storeId: string
|
||||
reportTLAnalytics: (point: TLAnalyticsPoint) => void
|
||||
}) => {
|
||||
const clientId = nanoid()
|
||||
const [roomState, roomOpenKind] = await this.getInitialRoomState(persistenceKey)
|
||||
const [roomState, roomOpenKind] = await this.getInitialRoomState(
|
||||
persistenceKey,
|
||||
reportTLAnalytics
|
||||
)
|
||||
|
||||
roomState.room.handleNewSession(sessionKey, new ServerSocketAdapter(socket))
|
||||
|
||||
|
|
|
@ -209,8 +209,8 @@ export class TLSyncRoom<R extends UnknownRecord> {
|
|||
|
||||
constructor(
|
||||
public readonly schema: StoreSchema<R, any>,
|
||||
snapshot?: RoomSnapshot,
|
||||
readonly reportTLAnalytics?: (point: TLAnalyticsPoint) => void
|
||||
readonly reportTLAnalytics: (point: TLAnalyticsPoint) => void,
|
||||
snapshot?: RoomSnapshot
|
||||
) {
|
||||
assert(
|
||||
isNativeStructuredClone,
|
||||
|
@ -451,7 +451,7 @@ export class TLSyncRoom<R extends UnknownRecord> {
|
|||
|
||||
session.debounceTimer = null
|
||||
|
||||
this.reportTLAnalytics?.({
|
||||
this.reportTLAnalytics({
|
||||
type: 'outstanding_data_messages',
|
||||
length: session.outstandingDataMessages.length,
|
||||
num_clients: this.sessions.size,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { TLRecord, createTLStore, defaultShapeUtils } from 'tldraw'
|
||||
import { type WebSocket } from 'ws'
|
||||
import { RoomSessionState } from '../lib/RoomSession'
|
||||
import { NO_TL_ANALYTICS } from '../lib/TLAnalytics'
|
||||
import { DBLoadResult, TLServer } from '../lib/TLServer'
|
||||
import { chunk } from '../lib/chunk'
|
||||
import { RecordOpType } from '../lib/diff'
|
||||
|
@ -92,6 +93,7 @@ const openConnection = async () => {
|
|||
sessionKey: 'test-session-key',
|
||||
socket: sockets.server,
|
||||
storeId: 'test-store-id',
|
||||
reportTLAnalytics: NO_TL_ANALYTICS,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
createTLSchema,
|
||||
} from '@tldraw/tlschema'
|
||||
import { ZERO_INDEX_KEY, sortById } from '@tldraw/utils'
|
||||
import { NO_TL_ANALYTICS } from '../lib/TLAnalytics'
|
||||
import {
|
||||
MAX_TOMBSTONES,
|
||||
RoomSnapshot,
|
||||
|
@ -63,14 +64,14 @@ const oldArrow: TLBaseShape<'arrow', Omit<TLArrowShapeProps, 'labelColor'>> = {
|
|||
|
||||
describe('TLSyncRoom', () => {
|
||||
it('can be constructed with a schema alone', () => {
|
||||
const room = new TLSyncRoom<any>(schema)
|
||||
const room = new TLSyncRoom<any>(schema, NO_TL_ANALYTICS)
|
||||
|
||||
// we populate the store with a default document if none is given
|
||||
expect(room.getSnapshot().documents.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('can be constructed with a snapshot', () => {
|
||||
const room = new TLSyncRoom<TLRecord>(schema, makeSnapshot(records))
|
||||
const room = new TLSyncRoom<TLRecord>(schema, NO_TL_ANALYTICS, makeSnapshot(records))
|
||||
|
||||
expect(
|
||||
room
|
||||
|
@ -83,7 +84,7 @@ describe('TLSyncRoom', () => {
|
|||
})
|
||||
|
||||
it('trims tombstones down if you pass too many in the snapshot', () => {
|
||||
const room = new TLSyncRoom(schema, {
|
||||
const room = new TLSyncRoom(schema, NO_TL_ANALYTICS, {
|
||||
documents: [],
|
||||
clock: MAX_TOMBSTONES + 100,
|
||||
tombstones: Object.fromEntries(
|
||||
|
@ -117,6 +118,7 @@ describe('TLSyncRoom', () => {
|
|||
|
||||
const room = new TLSyncRoom(
|
||||
schema,
|
||||
NO_TL_ANALYTICS,
|
||||
makeSnapshot([...records, oldArrow], {
|
||||
schema: oldSerializedSchema,
|
||||
})
|
||||
|
@ -131,6 +133,7 @@ describe('TLSyncRoom', () => {
|
|||
const schema = createTLSchema({ shapes: {} })
|
||||
const room = new TLSyncRoom(
|
||||
schema,
|
||||
NO_TL_ANALYTICS,
|
||||
makeSnapshot([
|
||||
...records,
|
||||
schema.types.instance.create({
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { StoreSchema, UnknownRecord } from '@tldraw/store'
|
||||
import { NO_TL_ANALYTICS } from '../lib/TLAnalytics'
|
||||
import { RoomSnapshot, TLSyncRoom } from '../lib/TLSyncRoom'
|
||||
import { TestSocketPair } from './TestSocketPair'
|
||||
|
||||
export class TestServer<R extends UnknownRecord, P = unknown> {
|
||||
room: TLSyncRoom<R>
|
||||
constructor(schema: StoreSchema<R, P>, snapshot?: RoomSnapshot) {
|
||||
this.room = new TLSyncRoom<R>(schema, snapshot)
|
||||
this.room = new TLSyncRoom<R>(schema, NO_TL_ANALYTICS, snapshot)
|
||||
}
|
||||
|
||||
connect(socketPair: TestSocketPair<R>): void {
|
||||
|
|
Ładowanie…
Reference in New Issue