@tabula-md/tabula 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -0
- package/dist/activeDocumentRuntime.d.ts +50 -0
- package/dist/activeDocumentRuntime.d.ts.map +1 -0
- package/dist/collabCollaborators.d.ts +16 -0
- package/dist/collabCollaborators.d.ts.map +1 -0
- package/dist/collabConnectionModel.d.ts +11 -0
- package/dist/collabConnectionModel.d.ts.map +1 -0
- package/dist/collabSessionState.d.ts +24 -0
- package/dist/collabSessionState.d.ts.map +1 -0
- package/dist/collaboration.d.ts +8 -0
- package/dist/collaboration.d.ts.map +1 -0
- package/dist/collaboration.js +78 -0
- package/dist/collaboration.js.map +1 -0
- package/dist/collaborationPresence.d.ts +7 -0
- package/dist/collaborationPresence.d.ts.map +1 -0
- package/dist/collaborationTypes.d.ts +27 -0
- package/dist/collaborationTypes.d.ts.map +1 -0
- package/dist/commentRuntimeModel.d.ts +53 -0
- package/dist/commentRuntimeModel.d.ts.map +1 -0
- package/dist/data/base64Url.d.ts +3 -0
- package/dist/data/base64Url.d.ts.map +1 -0
- package/dist/data/encode.d.ts +20 -0
- package/dist/data/encode.d.ts.map +1 -0
- package/dist/data/encode.js +61 -0
- package/dist/data/encode.js.map +1 -0
- package/dist/data/encryption.d.ts +20 -0
- package/dist/data/encryption.d.ts.map +1 -0
- package/dist/data/encryption.js +13 -0
- package/dist/data/encryption.js.map +1 -0
- package/dist/data/json.d.ts +18 -0
- package/dist/data/json.d.ts.map +1 -0
- package/dist/data/json.js +18 -0
- package/dist/data/json.js.map +1 -0
- package/dist/data/restore.d.ts +3 -0
- package/dist/data/restore.d.ts.map +1 -0
- package/dist/data/restore.js +6 -0
- package/dist/data/restore.js.map +1 -0
- package/dist/documentBuffer.d.ts +68 -0
- package/dist/documentBuffer.d.ts.map +1 -0
- package/dist/documentControlsModel.d.ts +58 -0
- package/dist/documentControlsModel.d.ts.map +1 -0
- package/dist/documentMetrics.d.ts +2 -0
- package/dist/documentMetrics.d.ts.map +1 -0
- package/dist/documentPrimitives.d.ts +9 -0
- package/dist/documentPrimitives.d.ts.map +1 -0
- package/dist/documentSurfaceModel.d.ts +44 -0
- package/dist/documentSurfaceModel.d.ts.map +1 -0
- package/dist/encryption-B0xRVvlF.js +82 -0
- package/dist/encryption-B0xRVvlF.js.map +1 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2474 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonShareLinkModel.d.ts +36 -0
- package/dist/jsonShareLinkModel.d.ts.map +1 -0
- package/dist/lineSurfaceModel.d.ts +73 -0
- package/dist/lineSurfaceModel.d.ts.map +1 -0
- package/dist/markdown/editing.d.ts +12 -0
- package/dist/markdown/editing.d.ts.map +1 -0
- package/dist/markdown/links.d.ts +23 -0
- package/dist/markdown/links.d.ts.map +1 -0
- package/dist/markdown/tasks.d.ts +22 -0
- package/dist/markdown/tasks.d.ts.map +1 -0
- package/dist/markdown.d.ts +25 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdownEditing.d.ts +2 -0
- package/dist/markdownEditing.d.ts.map +1 -0
- package/dist/markdownFormatting.d.ts +11 -0
- package/dist/markdownFormatting.d.ts.map +1 -0
- package/dist/previewBlockModel.d.ts +66 -0
- package/dist/previewBlockModel.d.ts.map +1 -0
- package/dist/productPerformancePolicy.d.ts +14 -0
- package/dist/productPerformancePolicy.d.ts.map +1 -0
- package/dist/rightPanelCommentViewModel.d.ts +39 -0
- package/dist/rightPanelCommentViewModel.d.ts.map +1 -0
- package/dist/room/envelope.d.ts +27 -0
- package/dist/room/envelope.d.ts.map +1 -0
- package/dist/room/envelope.js +38 -0
- package/dist/room/envelope.js.map +1 -0
- package/dist/roomBinaryProtocol.d.ts +43 -0
- package/dist/roomBinaryProtocol.d.ts.map +1 -0
- package/dist/roomCollaboration.d.ts +39 -0
- package/dist/roomCollaboration.d.ts.map +1 -0
- package/dist/roomProtocol.d.ts +11 -0
- package/dist/roomProtocol.d.ts.map +1 -0
- package/dist/roomShareLinkModel.d.ts +20 -0
- package/dist/roomShareLinkModel.d.ts.map +1 -0
- package/dist/shareLinkViewModel.d.ts +8 -0
- package/dist/shareLinkViewModel.d.ts.map +1 -0
- package/dist/shareSnapshotPayload-CsTw9sRq.js +209 -0
- package/dist/shareSnapshotPayload-CsTw9sRq.js.map +1 -0
- package/dist/shareSnapshotPayload.d.ts +75 -0
- package/dist/shareSnapshotPayload.d.ts.map +1 -0
- package/dist/shareViewModel.d.ts +33 -0
- package/dist/shareViewModel.d.ts.map +1 -0
- package/dist/sourceScrollTransfer.d.ts +54 -0
- package/dist/sourceScrollTransfer.d.ts.map +1 -0
- package/dist/statusBarViewModel.d.ts +13 -0
- package/dist/statusBarViewModel.d.ts.map +1 -0
- package/dist/textPatches.d.ts +16 -0
- package/dist/textPatches.d.ts.map +1 -0
- package/dist/workspaceFileRuntimeModel.d.ts +11 -0
- package/dist/workspaceFileRuntimeModel.d.ts.map +1 -0
- package/dist/workspaceIoModel.d.ts +37 -0
- package/dist/workspaceIoModel.d.ts.map +1 -0
- package/dist/workspaceModel.d.ts +112 -0
- package/dist/workspaceModel.d.ts.map +1 -0
- package/dist/workspaceRoomCheckpoint.d.ts +46 -0
- package/dist/workspaceRoomCheckpoint.d.ts.map +1 -0
- package/dist/workspaceRoomCrdt.d.ts +55 -0
- package/dist/workspaceRoomCrdt.d.ts.map +1 -0
- package/dist/workspaceRoomModel-CO-5ZOpS.js +78 -0
- package/dist/workspaceRoomModel-CO-5ZOpS.js.map +1 -0
- package/dist/workspaceRoomModel.d.ts +69 -0
- package/dist/workspaceRoomModel.d.ts.map +1 -0
- package/dist/workspaceRoomSync-B3niC7cn.js +758 -0
- package/dist/workspaceRoomSync-B3niC7cn.js.map +1 -0
- package/dist/workspaceRoomSync.d.ts +98 -0
- package/dist/workspaceRoomSync.d.ts.map +1 -0
- package/dist/workspaceViewModel.d.ts +13 -0
- package/dist/workspaceViewModel.d.ts.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaceRoomSync-B3niC7cn.js","sources":["../src/roomBinaryProtocol.ts","../src/roomCollaboration.ts","../src/workspaceRoomCheckpoint.ts","../src/workspaceRoomCrdt.ts","../src/workspaceRoomSync.ts"],"sourcesContent":["import * as decoding from \"lib0/decoding\";\nimport * as encoding from \"lib0/encoding\";\n\nexport const ROOM_WIRE_PROTOCOL_VERSION = 2;\nexport const ROOM_WIRE_CHUNK_BYTES = 256 * 1024;\nexport const ROOM_WIRE_CHUNK_PAYLOAD_BYTES = ROOM_WIRE_CHUNK_BYTES - 1024;\nexport const ROOM_WIRE_MAX_MESSAGE_BYTES = 16 * 1024 * 1024;\nexport const ROOM_WIRE_MAX_CRDT_STATE_BYTES = 12 * 1024 * 1024;\nexport const ROOM_WIRE_MAX_CHUNKS = 64;\nexport const ROOM_WIRE_MAX_INFLIGHT_PER_ACTOR = 4;\nexport const ROOM_WIRE_CHUNK_TTL_MS = 10_000;\nexport const ROOM_WIRE_MAX_BUFFERED_BYTES = 64 * 1024 * 1024;\n\nexport type RoomWirePacketType = \"sync.message\" | \"awareness.updated\";\n\nexport type RoomWireDataPacket = {\n type: RoomWirePacketType;\n senderId: string;\n payload: Uint8Array;\n};\n\nexport type RoomWireChunkPacket = {\n type: \"sync.chunk\";\n senderId: string;\n messageId: string;\n chunkIndex: number;\n chunkCount: number;\n totalBytes: number;\n payload: Uint8Array;\n};\n\nexport type RoomWirePacket = RoomWireDataPacket | RoomWireChunkPacket;\n\nexport type RoomWirePacketDecodeResult =\n | { ok: true; packet: RoomWirePacket }\n | { ok: false; reason: \"invalid\" | \"unsupported\" | \"oversized\" };\n\nconst packetTypeCodes: Record<RoomWirePacket[\"type\"], number> = {\n \"sync.message\": 0,\n \"awareness.updated\": 1,\n \"sync.chunk\": 2,\n};\n\nconst packetTypesByCode = new Map<number, RoomWirePacket[\"type\"]>([\n [0, \"sync.message\"],\n [1, \"awareness.updated\"],\n [2, \"sync.chunk\"],\n]);\n\nconst validSenderId = (senderId: string) =>\n senderId.length > 0 && senderId.length <= 120 && !senderId.includes(\"\\0\") && !/[\\r\\n]/.test(senderId);\n\nexport const encodeRoomWirePacket = (packet: RoomWirePacket) => {\n if (!validSenderId(packet.senderId)) {\n throw new Error(\"Room packet sender is invalid.\");\n }\n if (packet.payload.byteLength > ROOM_WIRE_MAX_MESSAGE_BYTES) {\n throw new Error(\"Room packet exceeds the maximum message size.\");\n }\n\n const encoder = encoding.createEncoder();\n encoding.writeVarUint(encoder, ROOM_WIRE_PROTOCOL_VERSION);\n encoding.writeVarUint(encoder, packetTypeCodes[packet.type]);\n encoding.writeVarString(encoder, packet.senderId);\n if (packet.type === \"sync.chunk\") {\n encoding.writeVarString(encoder, packet.messageId);\n encoding.writeVarUint(encoder, packet.chunkIndex);\n encoding.writeVarUint(encoder, packet.chunkCount);\n encoding.writeVarUint(encoder, packet.totalBytes);\n }\n encoding.writeVarUint8Array(encoder, packet.payload);\n return encoding.toUint8Array(encoder);\n};\n\nexport const decodeRoomWirePacket = (bytes: Uint8Array): RoomWirePacketDecodeResult => {\n if (bytes.byteLength === 0 || bytes.byteLength > ROOM_WIRE_MAX_MESSAGE_BYTES + 1024) {\n return { ok: false, reason: bytes.byteLength === 0 ? \"invalid\" : \"oversized\" };\n }\n try {\n const decoder = decoding.createDecoder(bytes);\n const version = decoding.readVarUint(decoder);\n if (version !== ROOM_WIRE_PROTOCOL_VERSION) {\n return { ok: false, reason: \"unsupported\" };\n }\n const type = packetTypesByCode.get(decoding.readVarUint(decoder));\n const senderId = decoding.readVarString(decoder);\n if (!type || !validSenderId(senderId)) {\n return { ok: false, reason: \"invalid\" };\n }\n if (type !== \"sync.chunk\") {\n const payload = decoding.readVarUint8Array(decoder);\n return payload.byteLength <= ROOM_WIRE_MAX_MESSAGE_BYTES && !decoding.hasContent(decoder)\n ? { ok: true, packet: { type, senderId, payload } }\n : { ok: false, reason: payload.byteLength > ROOM_WIRE_MAX_MESSAGE_BYTES ? \"oversized\" : \"invalid\" };\n }\n\n const messageId = decoding.readVarString(decoder);\n const chunkIndex = decoding.readVarUint(decoder);\n const chunkCount = decoding.readVarUint(decoder);\n const totalBytes = decoding.readVarUint(decoder);\n const payload = decoding.readVarUint8Array(decoder);\n if (\n !messageId ||\n messageId.length > 120 ||\n chunkCount < 2 ||\n chunkCount > ROOM_WIRE_MAX_CHUNKS ||\n chunkIndex >= chunkCount ||\n totalBytes <= ROOM_WIRE_CHUNK_BYTES ||\n totalBytes > ROOM_WIRE_MAX_MESSAGE_BYTES ||\n payload.byteLength > ROOM_WIRE_CHUNK_PAYLOAD_BYTES ||\n decoding.hasContent(decoder)\n ) {\n return { ok: false, reason: totalBytes > ROOM_WIRE_MAX_MESSAGE_BYTES ? \"oversized\" : \"invalid\" };\n }\n return {\n ok: true,\n packet: {\n type,\n senderId,\n messageId,\n chunkIndex,\n chunkCount,\n totalBytes,\n payload,\n },\n };\n } catch {\n return { ok: false, reason: \"invalid\" };\n }\n};\n\nexport const encodeRoomWirePackets = (\n packet: RoomWireDataPacket,\n createMessageId: () => string,\n): Uint8Array[] => {\n const encoded = encodeRoomWirePacket(packet);\n if (encoded.byteLength <= ROOM_WIRE_CHUNK_BYTES) {\n return [encoded];\n }\n if (encoded.byteLength > ROOM_WIRE_MAX_MESSAGE_BYTES) {\n throw new Error(\"Room packet exceeds the maximum message size.\");\n }\n const chunkCount = Math.ceil(encoded.byteLength / ROOM_WIRE_CHUNK_PAYLOAD_BYTES);\n if (chunkCount > ROOM_WIRE_MAX_CHUNKS) {\n throw new Error(\"Room packet exceeds the maximum chunk count.\");\n }\n const messageId = createMessageId();\n return Array.from({ length: chunkCount }, (_, chunkIndex) => {\n const encodedChunk = encodeRoomWirePacket({\n type: \"sync.chunk\",\n senderId: packet.senderId,\n messageId,\n chunkIndex,\n chunkCount,\n totalBytes: encoded.byteLength,\n payload: encoded.subarray(\n chunkIndex * ROOM_WIRE_CHUNK_PAYLOAD_BYTES,\n Math.min(encoded.byteLength, (chunkIndex + 1) * ROOM_WIRE_CHUNK_PAYLOAD_BYTES),\n ),\n });\n if (encodedChunk.byteLength > ROOM_WIRE_CHUNK_BYTES) {\n throw new Error(\"Encoded room chunk exceeds the maximum chunk size.\");\n }\n return encodedChunk;\n });\n};\n\ntype PendingChunks = {\n senderId: string;\n messageId: string;\n chunkCount: number;\n totalBytes: number;\n createdAt: number;\n chunks: Map<number, Uint8Array>;\n};\n\nexport type RoomChunkAssembler = {\n push(packet: RoomWireChunkPacket, now?: number): RoomWireDataPacket | null;\n clear(): void;\n prune(now?: number): void;\n readonly pendingCount: number;\n};\n\nexport const createRoomChunkAssembler = (): RoomChunkAssembler => {\n const pending = new Map<string, PendingChunks>();\n\n const prune = (now = Date.now()) => {\n for (const [key, value] of pending) {\n if (now - value.createdAt >= ROOM_WIRE_CHUNK_TTL_MS) {\n pending.delete(key);\n }\n }\n };\n\n return {\n get pendingCount() {\n return pending.size;\n },\n clear() {\n pending.clear();\n },\n prune,\n push(packet, now = Date.now()) {\n prune(now);\n const key = `${packet.senderId}\\u0000${packet.messageId}`;\n let entry = pending.get(key);\n if (!entry) {\n const actorEntries = Array.from(pending.values())\n .filter((candidate) => candidate.senderId === packet.senderId)\n .sort((first, second) => first.createdAt - second.createdAt);\n while (actorEntries.length >= ROOM_WIRE_MAX_INFLIGHT_PER_ACTOR) {\n const oldest = actorEntries.shift();\n if (oldest) pending.delete(`${oldest.senderId}\\u0000${oldest.messageId}`);\n }\n const reservedBytes = Array.from(pending.values())\n .reduce((total, candidate) => total + candidate.totalBytes, 0);\n if (reservedBytes + packet.totalBytes > ROOM_WIRE_MAX_BUFFERED_BYTES) return null;\n entry = {\n senderId: packet.senderId,\n messageId: packet.messageId,\n chunkCount: packet.chunkCount,\n totalBytes: packet.totalBytes,\n createdAt: now,\n chunks: new Map(),\n };\n pending.set(key, entry);\n }\n if (entry.chunkCount !== packet.chunkCount || entry.totalBytes !== packet.totalBytes) {\n pending.delete(key);\n return null;\n }\n if (!entry.chunks.has(packet.chunkIndex)) {\n entry.chunks.set(packet.chunkIndex, packet.payload.slice());\n }\n if (entry.chunks.size !== entry.chunkCount) {\n return null;\n }\n const bytes = new Uint8Array(entry.totalBytes);\n let offset = 0;\n for (let index = 0; index < entry.chunkCount; index += 1) {\n const chunk = entry.chunks.get(index);\n if (!chunk || offset + chunk.byteLength > bytes.byteLength) {\n pending.delete(key);\n return null;\n }\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n pending.delete(key);\n if (offset !== bytes.byteLength) {\n return null;\n }\n const decoded = decodeRoomWirePacket(bytes);\n return decoded.ok && decoded.packet.type !== \"sync.chunk\" && decoded.packet.senderId === packet.senderId\n ? decoded.packet\n : null;\n },\n };\n};\n","export type RoomActorKind = \"human\" | \"agent\";\n\nexport type RoomActorClient = \"tabula-md\" | \"tabula-mcp\" | \"custom\";\n\nexport type RoomCapability = \"presence\" | \"read\" | \"write\";\n\nexport type RoomActor = {\n id: string;\n kind: RoomActorKind;\n name: string;\n color?: string;\n client: RoomActorClient;\n capabilities: RoomCapability[];\n joinedAt: string;\n};\n\nexport const HUMAN_ROOM_CAPABILITIES: readonly RoomCapability[] = [\n \"presence\",\n \"read\",\n \"write\",\n];\n\nexport const AGENT_ROOM_CAPABILITIES: readonly RoomCapability[] = [\n \"presence\",\n \"read\",\n \"write\",\n];\n\nexport const DEFAULT_HUMAN_ACTOR_CLIENT: RoomActorClient = \"tabula-md\";\nexport const DEFAULT_AGENT_ACTOR_CLIENT: RoomActorClient = \"tabula-mcp\";\nexport const ROOM_ACTOR_ADJECTIVES = [\n \"Bright\",\n \"Calm\",\n \"Careful\",\n \"Clear\",\n \"Clever\",\n \"Curious\",\n \"Gentle\",\n \"Kind\",\n \"Lively\",\n \"Nimble\",\n \"Patient\",\n \"Quiet\",\n \"Ready\",\n \"Sharp\",\n \"Steady\",\n \"Thoughtful\",\n \"Warm\",\n \"Wise\",\n] as const;\nexport const ROOM_ACTOR_COLORS = [\n \"#0f766e\",\n \"#2563eb\",\n \"#7c3aed\",\n \"#c2410c\",\n \"#be123c\",\n \"#047857\",\n \"#0e7490\",\n \"#4f46e5\",\n \"#9333ea\",\n \"#b45309\",\n] as const;\nexport const DEFAULT_ACTOR_NAME = \"Curious Human\";\nexport const DEFAULT_ACTOR_COLOR = ROOM_ACTOR_COLORS[0];\nexport const ROOM_ACTOR_MAX_ID_LENGTH = 128;\nexport const ROOM_ACTOR_MAX_NAME_LENGTH = 40;\n\nconst ROOM_ACTOR_COLOR_PATTERN = /^#[0-9a-f]{6}$/i;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nconst isRoomActorKind = (value: unknown): value is RoomActorKind =>\n value === \"human\" || value === \"agent\";\n\nconst isRoomActorClient = (value: unknown): value is RoomActorClient =>\n value === \"tabula-md\" || value === \"tabula-mcp\" || value === \"custom\";\n\nexport const isRoomCapability = (value: unknown): value is RoomCapability =>\n value === \"presence\" || value === \"read\" || value === \"write\";\n\nexport const getDefaultRoomCapabilities = (kind: RoomActorKind) =>\n kind === \"agent\" ? [...AGENT_ROOM_CAPABILITIES] : [...HUMAN_ROOM_CAPABILITIES];\n\nexport const normalizeRoomCapabilities = (\n capabilities: unknown,\n kind: RoomActorKind = \"human\",\n): RoomCapability[] => {\n if (!Array.isArray(capabilities)) {\n return getDefaultRoomCapabilities(kind);\n }\n\n const normalized = capabilities.filter(isRoomCapability);\n return normalized.length > 0 ? [...new Set(normalized)] : getDefaultRoomCapabilities(kind);\n};\n\nexport const hasRoomCapability = (\n actor: Pick<RoomActor, \"capabilities\"> | null | undefined,\n capability: RoomCapability,\n) => Boolean(actor?.capabilities.includes(capability));\n\nconst getStableActorIndex = (seed: string, modulo: number) => {\n let hash = 2166136261;\n for (let index = 0; index < seed.length; index += 1) {\n hash ^= seed.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n return Math.abs(hash >>> 0) % modulo;\n};\n\nexport const createRoomActorName = (kind: RoomActorKind = \"human\", actorId = \"\") => {\n const adjective =\n ROOM_ACTOR_ADJECTIVES[\n getStableActorIndex(actorId.trim() || kind, ROOM_ACTOR_ADJECTIVES.length)\n ] ?? \"Curious\";\n return `${adjective} ${kind === \"agent\" ? \"Agent\" : \"Human\"}`;\n};\n\nexport const createRoomActorColor = (actorId = \"\") =>\n ROOM_ACTOR_COLORS[\n getStableActorIndex(actorId.trim() || \"actor\", ROOM_ACTOR_COLORS.length)\n ] ?? DEFAULT_ACTOR_COLOR;\n\nexport const createRoomActor = ({\n id,\n kind = \"human\",\n name,\n color,\n client,\n capabilities,\n joinedAt,\n}: {\n id: string;\n kind?: RoomActorKind;\n name?: string;\n color?: string;\n client?: RoomActorClient;\n capabilities?: readonly RoomCapability[];\n joinedAt?: string;\n}): RoomActor => {\n const actorId = id.trim() || \"actor\";\n return {\n id: actorId.slice(0, ROOM_ACTOR_MAX_ID_LENGTH),\n kind,\n name: (name?.trim() || createRoomActorName(kind, actorId)).slice(0, ROOM_ACTOR_MAX_NAME_LENGTH),\n color: color?.trim().match(ROOM_ACTOR_COLOR_PATTERN)?.[0] || createRoomActorColor(actorId),\n client: client ?? (kind === \"agent\" ? DEFAULT_AGENT_ACTOR_CLIENT : DEFAULT_HUMAN_ACTOR_CLIENT),\n capabilities: capabilities?.length\n ? [...new Set(capabilities)]\n : getDefaultRoomCapabilities(kind),\n joinedAt: joinedAt || new Date(0).toISOString(),\n };\n};\n\nexport const parseRoomActor = (value: unknown): RoomActor | null => {\n if (\n !isRecord(value) ||\n typeof value.id !== \"string\" ||\n value.id.trim() === \"\" ||\n value.id.trim().length > ROOM_ACTOR_MAX_ID_LENGTH ||\n !isRoomActorKind(value.kind) ||\n typeof value.name !== \"string\" ||\n value.name.trim() === \"\" ||\n value.name.trim().length > ROOM_ACTOR_MAX_NAME_LENGTH ||\n !isRoomActorClient(value.client) ||\n !Array.isArray(value.capabilities) ||\n typeof value.joinedAt !== \"string\" ||\n value.joinedAt.trim() === \"\" ||\n value.joinedAt.length > 64 ||\n !Number.isFinite(Date.parse(value.joinedAt))\n ) {\n return null;\n }\n\n const capabilities = value.capabilities.filter(isRoomCapability);\n if (capabilities.length !== value.capabilities.length || capabilities.length === 0 || capabilities.length > 3) {\n return null;\n }\n if (typeof value.color === \"string\" && !ROOM_ACTOR_COLOR_PATTERN.test(value.color.trim())) return null;\n\n return {\n id: value.id.trim(),\n kind: value.kind,\n name: value.name.trim(),\n color:\n typeof value.color === \"string\" && value.color.trim()\n ? value.color.trim()\n : createRoomActorColor(value.id),\n client: value.client,\n capabilities: [...new Set(capabilities)],\n joinedAt: value.joinedAt,\n };\n};\n","import { decodeEncryptedData, encodeEncryptedData } from \"./data/encode\";\nimport { WORKSPACE_ROOM_SCHEMA_VERSION } from \"./workspaceRoomModel\";\n\nexport const ROOM_CHECKPOINT_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport type WorkspaceRoomCheckpointMetadata = {\n kind: \"workspace-room-crdt\";\n roomId: string;\n schemaVersion: typeof WORKSPACE_ROOM_SCHEMA_VERSION;\n};\n\nexport type LoadedWorkspaceRoomCheckpoint =\n | {\n status: \"ready\";\n generation: number;\n encryptedCheckpoint: Uint8Array;\n expiresAt: number;\n }\n | {\n status: \"expired\";\n generation: number;\n expiresAt: number;\n };\n\nexport type SaveWorkspaceRoomCheckpointRequest = {\n expectedGeneration: number;\n encryptedCheckpoint: Uint8Array;\n expiresAt: number;\n};\n\nexport type SaveWorkspaceRoomCheckpointResult =\n | { ok: true; generation: number }\n | { ok: false; reason: \"conflict\"; generation: number };\n\nexport type WorkspaceRoomCheckpointStore = {\n enabled: boolean;\n loadEncryptedCheckpoint(\n roomId: string,\n signal?: AbortSignal,\n ): Promise<LoadedWorkspaceRoomCheckpoint | null>;\n saveEncryptedCheckpoint(\n roomId: string,\n request: SaveWorkspaceRoomCheckpointRequest,\n signal?: AbortSignal,\n ): Promise<SaveWorkspaceRoomCheckpointResult>;\n};\n\nconst getAdditionalData = (roomId: string) =>\n new TextEncoder().encode(\n `tabula.workspace-room-crdt:v${WORKSPACE_ROOM_SCHEMA_VERSION}:${roomId}`,\n );\n\nexport const encryptWorkspaceRoomCheckpoint = async ({\n roomId,\n update,\n roomKey,\n}: {\n roomId: string;\n update: Uint8Array;\n roomKey: string | CryptoKey;\n}) =>\n encodeEncryptedData(update, {\n encryptionKey: roomKey,\n metadata: {\n kind: \"workspace-room-crdt\",\n roomId,\n schemaVersion: WORKSPACE_ROOM_SCHEMA_VERSION,\n } satisfies WorkspaceRoomCheckpointMetadata,\n additionalData: getAdditionalData(roomId),\n });\n\nexport const decryptWorkspaceRoomCheckpoint = async ({\n encryptedCheckpoint,\n roomId,\n roomKey,\n}: {\n encryptedCheckpoint: Uint8Array;\n roomId: string;\n roomKey: string | CryptoKey;\n}) => {\n const decoded = await decodeEncryptedData<WorkspaceRoomCheckpointMetadata>(\n encryptedCheckpoint,\n {\n decryptionKey: roomKey,\n additionalData: getAdditionalData(roomId),\n },\n );\n\n if (\n decoded.metadata.kind !== \"workspace-room-crdt\" ||\n decoded.metadata.roomId !== roomId ||\n decoded.metadata.schemaVersion !== WORKSPACE_ROOM_SCHEMA_VERSION\n ) {\n throw new Error(\"Room checkpoint failed: unsupported checkpoint metadata\");\n }\n return decoded.data;\n};\n","import * as Y from \"yjs\";\nimport {\n WORKSPACE_ROOM_MAX_COMMENTS,\n WORKSPACE_ROOM_MAX_COMMENT_LENGTH,\n WORKSPACE_ROOM_MAX_REPLIES,\n WORKSPACE_ROOM_ROOT_ID,\n WORKSPACE_ROOM_SCHEMA_VERSION,\n type WorkspaceRoomComment,\n type WorkspaceRoomCommentReply,\n type WorkspaceRoomNode,\n type WorkspaceRoomNodeType,\n type WorkspaceRoomSnapshot,\n type WorkspaceRoomStructureSnapshot,\n} from \"./workspaceRoomModel\";\n\nexport type WorkspaceRoomCrdt = {\n doc: Y.Doc;\n meta: Y.Map<unknown>;\n nodes: Y.Map<Y.Map<unknown>>;\n documents: Y.Map<Y.Text>;\n comments: Y.Map<Y.Map<unknown>>;\n};\n\nexport type WorkspaceRoomStructureResult =\n | { ok: true }\n | { ok: false; message: string };\n\ntype InitialWorkspaceRoomNode = {\n id: string;\n type: WorkspaceRoomNodeType;\n parentId?: string | null;\n title: string;\n order?: number;\n createdAt?: string;\n updatedAt?: string;\n markdown?: string;\n};\n\ntype InitialWorkspaceRoomComment = Omit<WorkspaceRoomComment, \"replies\"> & {\n replies?: readonly WorkspaceRoomCommentReply[];\n};\n\nconst asString = (value: unknown, fallback = \"\") =>\n typeof value === \"string\" ? value : fallback;\n\nconst asNumber = (value: unknown, fallback = 0) =>\n typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n\nconst asOptionalString = (value: unknown) =>\n typeof value === \"string\" && value.length > 0 ? value : undefined;\n\nconst normalizeTitle = (title: string, fallback: string) => {\n const normalized = title.trim().split(\"\\0\").join(\" \").replace(/[/\\\\]/g, \" \").replace(/\\s+/g, \" \");\n return normalized && normalized !== \".\" && normalized !== \"..\" ? normalized.slice(0, 120) : fallback;\n};\n\nconst createNodeMap = ({\n id,\n type,\n parentId = WORKSPACE_ROOM_ROOT_ID,\n title,\n order = 0,\n createdAt = new Date().toISOString(),\n updatedAt = createdAt,\n}: InitialWorkspaceRoomNode) => {\n const node = new Y.Map<unknown>();\n node.set(\"id\", id);\n node.set(\"type\", type);\n node.set(\"parentId\", type === \"folder\" && id === WORKSPACE_ROOM_ROOT_ID ? null : parentId);\n node.set(\"title\", normalizeTitle(title, type === \"folder\" ? \"Folder\" : \"Untitled.md\"));\n node.set(\"order\", order);\n node.set(\"createdAt\", createdAt);\n node.set(\"updatedAt\", updatedAt);\n return node;\n};\n\nconst readNode = (id: string, node: Y.Map<unknown>): WorkspaceRoomNode | null => {\n const type = node.get(\"type\");\n if (type !== \"folder\" && type !== \"document\") {\n return null;\n }\n\n const parentValue = node.get(\"parentId\");\n return {\n id,\n type,\n parentId: parentValue === null || typeof parentValue === \"string\" ? parentValue : WORKSPACE_ROOM_ROOT_ID,\n title: asString(node.get(\"title\"), type === \"folder\" ? \"Folder\" : \"Untitled.md\"),\n order: asNumber(node.get(\"order\")),\n createdAt: asString(node.get(\"createdAt\"), new Date(0).toISOString()),\n updatedAt: asString(node.get(\"updatedAt\"), new Date(0).toISOString()),\n };\n};\n\nconst compareNodes = (first: WorkspaceRoomNode, second: WorkspaceRoomNode) =>\n first.order - second.order ||\n first.title.localeCompare(second.title, undefined, { numeric: true, sensitivity: \"base\" }) ||\n first.id.localeCompare(second.id);\n\nexport const createWorkspaceRoomCrdt = ({\n roomId,\n doc = new Y.Doc(),\n initialize = true,\n}: {\n roomId: string;\n doc?: Y.Doc;\n initialize?: boolean;\n}): WorkspaceRoomCrdt => {\n const meta = doc.getMap(\"tabula.meta\");\n const nodes = doc.getMap<Y.Map<unknown>>(\"tabula.nodes\");\n const documents = doc.getMap<Y.Text>(\"tabula.documents\");\n const comments = doc.getMap<Y.Map<unknown>>(\"tabula.comments\");\n\n if (initialize) {\n doc.transact(() => {\n if (!meta.has(\"schemaVersion\")) {\n meta.set(\"schemaVersion\", WORKSPACE_ROOM_SCHEMA_VERSION);\n }\n if (!meta.has(\"roomId\")) {\n meta.set(\"roomId\", roomId);\n }\n if (!meta.has(\"rootId\")) {\n meta.set(\"rootId\", WORKSPACE_ROOM_ROOT_ID);\n }\n if (!nodes.has(WORKSPACE_ROOM_ROOT_ID)) {\n nodes.set(WORKSPACE_ROOM_ROOT_ID, createNodeMap({\n id: WORKSPACE_ROOM_ROOT_ID,\n type: \"folder\",\n parentId: null,\n title: \"Workspace\",\n order: 0,\n createdAt: new Date(0).toISOString(),\n }));\n }\n }, \"tabula.bootstrap\");\n }\n\n return { doc, meta, nodes, documents, comments };\n};\n\nexport const validateWorkspaceRoomStructure = (\n room: WorkspaceRoomCrdt,\n expectedRoomId: string,\n): WorkspaceRoomStructureResult => {\n if (\n room.meta.get(\"schemaVersion\") !== WORKSPACE_ROOM_SCHEMA_VERSION ||\n room.meta.get(\"roomId\") !== expectedRoomId ||\n room.meta.get(\"rootId\") !== WORKSPACE_ROOM_ROOT_ID\n ) {\n return { ok: false, message: \"This room uses an unsupported workspace format.\" };\n }\n\n const root = room.nodes.get(WORKSPACE_ROOM_ROOT_ID);\n if (root?.get(\"type\") !== \"folder\" || root.get(\"parentId\") !== null) {\n return { ok: false, message: \"This room has an invalid workspace root.\" };\n }\n\n for (const [nodeId, node] of room.nodes) {\n const parsed = readNode(nodeId, node);\n if (!parsed) {\n return { ok: false, message: \"This room contains an invalid workspace node.\" };\n }\n if (nodeId !== WORKSPACE_ROOM_ROOT_ID) {\n const parent = parsed.parentId ? room.nodes.get(parsed.parentId) : undefined;\n if (parent?.get(\"type\") !== \"folder\") {\n return { ok: false, message: \"This room contains an invalid folder relationship.\" };\n }\n }\n if (parsed.type === \"document\" && !(room.documents.get(nodeId) instanceof Y.Text)) {\n return { ok: false, message: \"This room contains a document without Markdown content.\" };\n }\n if (parsed.type === \"folder\" && room.documents.has(nodeId)) {\n return { ok: false, message: \"This room contains invalid folder content.\" };\n }\n }\n\n for (const documentId of room.documents.keys()) {\n if (room.nodes.get(documentId)?.get(\"type\") !== \"document\") {\n return { ok: false, message: \"This room contains orphaned Markdown content.\" };\n }\n }\n\n for (const comment of room.comments.values()) {\n const fileId = asString(comment.get(\"fileId\"));\n if (room.nodes.get(fileId)?.get(\"type\") !== \"document\") {\n return { ok: false, message: \"This room contains an orphaned comment.\" };\n }\n }\n\n return { ok: true };\n};\n\nexport const initializeWorkspaceRoomCrdt = (\n room: WorkspaceRoomCrdt,\n {\n nodes,\n comments = [],\n }: {\n nodes: readonly InitialWorkspaceRoomNode[];\n comments?: readonly InitialWorkspaceRoomComment[];\n },\n) => {\n room.doc.transact(() => {\n for (const input of nodes) {\n if (!input.id || input.id === WORKSPACE_ROOM_ROOT_ID) {\n continue;\n }\n room.nodes.set(input.id, createNodeMap(input));\n if (input.type === \"document\") {\n const text = new Y.Text();\n if (input.markdown) {\n text.insert(0, input.markdown);\n }\n room.documents.set(input.id, text);\n }\n }\n for (const comment of comments) {\n setWorkspaceRoomComment(room, comment);\n }\n }, \"tabula.initialize\");\n};\n\nexport const getWorkspaceRoomDocument = (room: WorkspaceRoomCrdt, documentId: string) =>\n room.documents.get(documentId) ?? null;\n\nexport const createWorkspaceRoomFolder = (\n room: WorkspaceRoomCrdt,\n input: Omit<InitialWorkspaceRoomNode, \"type\" | \"markdown\">,\n) => {\n const parentId = input.parentId ?? WORKSPACE_ROOM_ROOT_ID;\n if (\n !input.id ||\n input.id === WORKSPACE_ROOM_ROOT_ID ||\n room.nodes.has(input.id) ||\n room.nodes.get(parentId)?.get(\"type\") !== \"folder\"\n ) {\n return false;\n }\n room.doc.transact(() => {\n room.nodes.set(input.id, createNodeMap({ ...input, parentId, type: \"folder\" }));\n }, \"tabula.folder.create\");\n return true;\n};\n\nexport const createWorkspaceRoomDocument = (\n room: WorkspaceRoomCrdt,\n input: Omit<InitialWorkspaceRoomNode, \"type\">,\n) => {\n const parentId = input.parentId ?? WORKSPACE_ROOM_ROOT_ID;\n if (\n !input.id ||\n input.id === WORKSPACE_ROOM_ROOT_ID ||\n room.nodes.has(input.id) ||\n room.nodes.get(parentId)?.get(\"type\") !== \"folder\"\n ) {\n return false;\n }\n room.doc.transact(() => {\n room.nodes.set(input.id, createNodeMap({ ...input, parentId, type: \"document\" }));\n const text = new Y.Text();\n if (input.markdown) {\n text.insert(0, input.markdown);\n }\n room.documents.set(input.id, text);\n }, \"tabula.document.create\");\n return true;\n};\n\nconst collectDescendantNodeIds = (room: WorkspaceRoomCrdt, nodeId: string) => {\n const ids = new Set([nodeId]);\n let changed = true;\n while (changed) {\n changed = false;\n room.nodes.forEach((node, id) => {\n if (!ids.has(id) && ids.has(asString(node.get(\"parentId\")))) {\n ids.add(id);\n changed = true;\n }\n });\n }\n return ids;\n};\n\nexport const deleteWorkspaceRoomNode = (room: WorkspaceRoomCrdt, nodeId: string) => {\n if (nodeId === WORKSPACE_ROOM_ROOT_ID) {\n return;\n }\n const deletedIds = collectDescendantNodeIds(room, nodeId);\n room.doc.transact(() => {\n for (const id of deletedIds) {\n room.nodes.delete(id);\n room.documents.delete(id);\n }\n room.comments.forEach((comment, commentId) => {\n if (deletedIds.has(asString(comment.get(\"fileId\")))) {\n room.comments.delete(commentId);\n }\n });\n }, \"tabula.node.delete\");\n};\n\nexport const renameWorkspaceRoomNode = (\n room: WorkspaceRoomCrdt,\n nodeId: string,\n title: string,\n updatedAt = new Date().toISOString(),\n) => {\n const node = room.nodes.get(nodeId);\n if (!node) {\n return false;\n }\n const type = node.get(\"type\") === \"folder\" ? \"folder\" : \"document\";\n const normalizedTitle = normalizeTitle(title, type === \"folder\" ? \"Folder\" : \"Untitled.md\");\n if (node.get(\"title\") === normalizedTitle) return true;\n room.doc.transact(() => {\n node.set(\"title\", normalizedTitle);\n node.set(\"updatedAt\", updatedAt);\n }, \"tabula.node.rename\");\n return true;\n};\n\nconst wouldCreateCycle = (room: WorkspaceRoomCrdt, nodeId: string, parentId: string) => {\n let currentId: string | null = parentId;\n const visited = new Set<string>();\n while (currentId) {\n if (currentId === nodeId || visited.has(currentId)) {\n return true;\n }\n visited.add(currentId);\n const parentValue: unknown = room.nodes.get(currentId)?.get(\"parentId\");\n currentId = typeof parentValue === \"string\" ? parentValue : null;\n }\n return false;\n};\n\nexport const moveWorkspaceRoomNode = (\n room: WorkspaceRoomCrdt,\n nodeId: string,\n parentId: string,\n updatedAt = new Date().toISOString(),\n) => {\n const node = room.nodes.get(nodeId);\n const parent = room.nodes.get(parentId);\n if (!node || parent?.get(\"type\") !== \"folder\" || nodeId === WORKSPACE_ROOM_ROOT_ID || wouldCreateCycle(room, nodeId, parentId)) {\n return false;\n }\n if (node.get(\"parentId\") === parentId) return true;\n room.doc.transact(() => {\n node.set(\"parentId\", parentId);\n node.set(\"updatedAt\", updatedAt);\n }, \"tabula.node.move\");\n return true;\n};\n\nexport const setWorkspaceRoomNodeOrder = (\n room: WorkspaceRoomCrdt,\n nodeId: string,\n order: number,\n updatedAt = new Date().toISOString(),\n) => {\n const node = room.nodes.get(nodeId);\n if (!node || !Number.isFinite(order)) return false;\n if (node.get(\"order\") === order) return true;\n room.doc.transact(() => {\n node.set(\"order\", order);\n node.set(\"updatedAt\", updatedAt);\n }, \"tabula.node.order\");\n return true;\n};\n\nconst createReplyMap = (reply: WorkspaceRoomCommentReply) => {\n const map = new Y.Map<unknown>();\n map.set(\"id\", reply.id);\n map.set(\"body\", reply.body.trim());\n if (reply.authorId) map.set(\"authorId\", reply.authorId);\n if (reply.authorName) map.set(\"authorName\", reply.authorName);\n if (reply.authorColor) map.set(\"authorColor\", reply.authorColor);\n map.set(\"createdAt\", reply.createdAt);\n return map;\n};\n\nconst createRelativeAnchor = (text: Y.Text | undefined, index: number | undefined, assoc: number) =>\n text && typeof index === \"number\"\n ? Y.encodeRelativePosition(\n Y.createRelativePositionFromTypeIndex(\n text,\n Math.max(0, Math.min(index, text.length)),\n assoc,\n ),\n )\n : undefined;\n\nexport const setWorkspaceRoomComment = (\n room: WorkspaceRoomCrdt,\n comment: InitialWorkspaceRoomComment,\n) => {\n const text = room.documents.get(comment.fileId);\n const body = comment.body.trim();\n const repliesInput = comment.replies ?? [];\n if (\n !text ||\n room.nodes.get(comment.fileId)?.get(\"type\") !== \"document\" ||\n !comment.id ||\n !body ||\n body.length > WORKSPACE_ROOM_MAX_COMMENT_LENGTH ||\n (!room.comments.has(comment.id) && room.comments.size >= WORKSPACE_ROOM_MAX_COMMENTS) ||\n repliesInput.length > WORKSPACE_ROOM_MAX_REPLIES ||\n repliesInput.some((reply) => !reply.id || !reply.body.trim() || reply.body.length > WORKSPACE_ROOM_MAX_COMMENT_LENGTH)\n ) {\n return false;\n }\n const map = new Y.Map<unknown>();\n map.set(\"id\", comment.id);\n map.set(\"fileId\", comment.fileId);\n map.set(\"body\", body);\n if (comment.authorId) map.set(\"authorId\", comment.authorId);\n if (comment.authorName) map.set(\"authorName\", comment.authorName);\n if (comment.authorColor) map.set(\"authorColor\", comment.authorColor);\n if (comment.quote) map.set(\"quote\", comment.quote.slice(0, WORKSPACE_ROOM_MAX_COMMENT_LENGTH));\n if (comment.sourceQuote) map.set(\"sourceQuote\", comment.sourceQuote.slice(0, WORKSPACE_ROOM_MAX_COMMENT_LENGTH));\n const anchorStart = createRelativeAnchor(text, comment.selectionStart, 0);\n const anchorEnd = createRelativeAnchor(text, comment.selectionEnd, -1);\n if (anchorStart) map.set(\"anchorStart\", anchorStart);\n if (anchorEnd) map.set(\"anchorEnd\", anchorEnd);\n map.set(\"resolved\", comment.resolved);\n map.set(\"createdAt\", comment.createdAt);\n const replies = new Y.Map<Y.Map<unknown>>();\n for (const reply of repliesInput) {\n replies.set(reply.id, createReplyMap(reply));\n }\n map.set(\"replies\", replies);\n room.comments.set(comment.id, map);\n return true;\n};\n\nexport const deleteWorkspaceRoomComment = (room: WorkspaceRoomCrdt, commentId: string) => {\n room.comments.delete(commentId);\n};\n\nexport const setWorkspaceRoomCommentResolved = (\n room: WorkspaceRoomCrdt,\n commentId: string,\n resolved: boolean,\n) => {\n room.comments.get(commentId)?.set(\"resolved\", resolved);\n};\n\nexport const addWorkspaceRoomCommentReply = (\n room: WorkspaceRoomCrdt,\n commentId: string,\n reply: WorkspaceRoomCommentReply,\n) => {\n const comment = room.comments.get(commentId);\n const replies = comment?.get(\"replies\");\n if (\n !(replies instanceof Y.Map) ||\n replies.size >= WORKSPACE_ROOM_MAX_REPLIES ||\n !reply.id ||\n !reply.body.trim() ||\n reply.body.length > WORKSPACE_ROOM_MAX_COMMENT_LENGTH\n ) {\n return false;\n }\n replies.set(reply.id, createReplyMap(reply));\n return true;\n};\n\nconst readRelativeAnchor = (room: WorkspaceRoomCrdt, value: unknown) => {\n if (!(value instanceof Uint8Array)) {\n return undefined;\n }\n try {\n const absolute = Y.createAbsolutePositionFromRelativePosition(Y.decodeRelativePosition(value), room.doc);\n return absolute?.index;\n } catch {\n return undefined;\n }\n};\n\nconst readReplies = (value: unknown): WorkspaceRoomCommentReply[] => {\n if (!(value instanceof Y.Map)) {\n return [];\n }\n const replies: WorkspaceRoomCommentReply[] = [];\n value.forEach((reply, id) => {\n if (!(reply instanceof Y.Map)) return;\n const body = asString(reply.get(\"body\")).trim();\n if (!body) return;\n replies.push({\n id,\n body,\n authorId: asOptionalString(reply.get(\"authorId\")),\n authorName: asOptionalString(reply.get(\"authorName\")),\n authorColor: asOptionalString(reply.get(\"authorColor\")),\n createdAt: asString(reply.get(\"createdAt\"), new Date(0).toISOString()),\n });\n });\n return replies.sort((first, second) => first.createdAt.localeCompare(second.createdAt) || first.id.localeCompare(second.id));\n};\n\nconst readComment = (\n room: WorkspaceRoomCrdt,\n id: string,\n comment: Y.Map<unknown>,\n): WorkspaceRoomComment | null => {\n const fileId = asString(comment.get(\"fileId\"));\n const body = asString(comment.get(\"body\")).trim();\n if (!fileId || !body) return null;\n return {\n id,\n fileId,\n body,\n authorId: asOptionalString(comment.get(\"authorId\")),\n authorName: asOptionalString(comment.get(\"authorName\")),\n authorColor: asOptionalString(comment.get(\"authorColor\")),\n quote: asOptionalString(comment.get(\"quote\")),\n sourceQuote: asOptionalString(comment.get(\"sourceQuote\")),\n selectionStart: readRelativeAnchor(room, comment.get(\"anchorStart\")),\n selectionEnd: readRelativeAnchor(room, comment.get(\"anchorEnd\")),\n resolved: comment.get(\"resolved\") === true,\n createdAt: asString(comment.get(\"createdAt\"), new Date(0).toISOString()),\n replies: readReplies(comment.get(\"replies\")),\n };\n};\n\nconst sortComments = (comments: WorkspaceRoomComment[]) =>\n comments.sort((first, second) =>\n first.createdAt.localeCompare(second.createdAt) || first.id.localeCompare(second.id));\n\nexport const getWorkspaceRoomDocumentComments = (\n room: WorkspaceRoomCrdt,\n documentId: string,\n): WorkspaceRoomComment[] => {\n if (\n room.nodes.get(documentId)?.get(\"type\") !== \"document\" ||\n !room.documents.has(documentId)\n ) {\n return [];\n }\n const comments: WorkspaceRoomComment[] = [];\n room.comments.forEach((comment, id) => {\n if (comment.get(\"fileId\") !== documentId) return;\n const parsed = readComment(room, id, comment);\n if (parsed) comments.push(parsed);\n });\n return sortComments(comments);\n};\n\nexport const getWorkspaceRoomSnapshot = (room: WorkspaceRoomCrdt): WorkspaceRoomSnapshot => {\n const structure = getWorkspaceRoomStructureSnapshot(room);\n const documents: Record<string, string> = {};\n for (const node of structure.nodes) {\n if (node.type === \"document\") {\n documents[node.id] = room.documents.get(node.id)?.toString() ?? \"\";\n }\n }\n\n return {\n ...structure,\n documents,\n commentsByFileId: getWorkspaceRoomComments(room),\n };\n};\n\nexport const getWorkspaceRoomStructureSnapshot = (\n room: WorkspaceRoomCrdt,\n): WorkspaceRoomStructureSnapshot => {\n const nodes: WorkspaceRoomNode[] = [];\n room.nodes.forEach((node, id) => {\n const parsed = readNode(id, node);\n if (parsed) nodes.push(parsed);\n });\n nodes.sort(compareNodes);\n return {\n roomId: asString(room.meta.get(\"roomId\")),\n schemaVersion: WORKSPACE_ROOM_SCHEMA_VERSION,\n rootId: asString(room.meta.get(\"rootId\"), WORKSPACE_ROOM_ROOT_ID),\n nodes,\n };\n};\n\nexport const getWorkspaceRoomComments = (\n room: WorkspaceRoomCrdt,\n): Record<string, WorkspaceRoomComment[]> => {\n const documentIds = new Set<string>();\n room.nodes.forEach((node, id) => {\n if (node.get(\"type\") === \"document\" && room.documents.has(id)) documentIds.add(id);\n });\n const commentsByFileId: Record<string, WorkspaceRoomComment[]> = {};\n room.comments.forEach((comment, id) => {\n const nextComment = readComment(room, id, comment);\n if (!nextComment || !documentIds.has(nextComment.fileId)) return;\n const { fileId } = nextComment;\n (commentsByFileId[fileId] ??= []).push(nextComment);\n });\n for (const comments of Object.values(commentsByFileId)) {\n sortComments(comments);\n }\n return commentsByFileId;\n};\n","import * as decoding from \"lib0/decoding\";\nimport * as encoding from \"lib0/encoding\";\nimport * as Y from \"yjs\";\nimport {\n applyAwarenessUpdate,\n encodeAwarenessUpdate,\n type Awareness,\n} from \"y-protocols/awareness\";\nimport * as syncProtocol from \"y-protocols/sync\";\nimport {\n createRoomChunkAssembler,\n decodeRoomWirePacket,\n encodeRoomWirePackets,\n ROOM_WIRE_CHUNK_BYTES,\n ROOM_WIRE_MAX_CRDT_STATE_BYTES,\n type RoomWireDataPacket,\n} from \"./roomBinaryProtocol\";\nimport { hasRoomCapability, type RoomActor } from \"./roomCollaboration\";\nimport {\n validateRoomPayload,\n type EncryptedEnvelope,\n type EnvelopeKind,\n} from \"./room/envelope\";\n\nconst MAX_INBOUND_ENVELOPES = 64;\nconst MAX_INBOUND_BUFFER_CHARS = 32 * 1024 * 1024;\nconst MAX_ENCRYPTED_ENVELOPE_CHARS = Math.ceil((ROOM_WIRE_CHUNK_BYTES + 2_048) * 4 / 3);\nconst UPDATE_RETRY_MAX_DELAY_MS = 30_000;\nconst UPDATE_RETRY_BASE_DELAY_MS = 500;\n\nexport const REMOTE_SYNC_ORIGIN = Symbol(\"tabula.remote-sync\");\nexport const REMOTE_AWARENESS_ORIGIN = Symbol(\"tabula.remote-awareness\");\n\nexport type RemoteSyncOrigin = {\n type: typeof REMOTE_SYNC_ORIGIN;\n senderId: string;\n};\n\nexport const isRemoteSyncOrigin = (origin: unknown): origin is RemoteSyncOrigin =>\n Boolean(\n origin &&\n typeof origin === \"object\" &&\n (origin as Partial<RemoteSyncOrigin>).type === REMOTE_SYNC_ORIGIN,\n );\n\ntype SendPacketResult = \"sent\" | \"offline\" | \"failed\" | \"discarded\";\n\nexport type WorkspaceRoomSyncClock = {\n setTimeout(callback: () => void, delayMs: number): unknown;\n clearTimeout(handle: unknown): void;\n createId(): string;\n};\n\nexport type WorkspaceRoomSyncCrypto = {\n encryptEnvelope(\n roomKey: CryptoKey,\n roomId: string,\n kind: EnvelopeKind,\n version: number,\n plaintext: Uint8Array,\n ): Promise<EncryptedEnvelope>;\n decryptEnvelope(roomKey: CryptoKey, envelope: EncryptedEnvelope): Promise<Uint8Array>;\n};\n\nexport type WorkspaceRoomTransportHandlers = {\n onConnect: () => void;\n onJoined: (message: { roomId: string; clientId: string; peerCount: number }) => void;\n onPeerJoined: (message: { roomId: string; clientId: string }) => void;\n onMessage: (envelope: unknown) => void;\n onPeers: (message: { roomId: string; peers: string[] }) => void;\n onError: (message: { error?: string }) => void;\n onDisconnect: () => void;\n onConnectError: () => void;\n};\n\nexport type WorkspaceRoomTransport = {\n readonly connected: boolean;\n connect(): void;\n sendEnvelope(envelope: EncryptedEnvelope): void;\n sendVolatileEnvelope(envelope: EncryptedEnvelope): void;\n disconnect(): void;\n};\n\nexport type WorkspaceRoomSyncAdapters = {\n clock: WorkspaceRoomSyncClock;\n crypto: WorkspaceRoomSyncCrypto;\n createRoomTransport(options: {\n baseUrl: string;\n roomId: string;\n clientId: string;\n handlers: WorkspaceRoomTransportHandlers;\n }): WorkspaceRoomTransport;\n};\n\ntype TransportLifecycleHandlers = Omit<WorkspaceRoomTransportHandlers, \"onMessage\">;\n\nexport type WorkspaceRoomSyncControllerOptions = {\n roomId: string;\n doc: Y.Doc;\n awareness: Awareness;\n adapters: WorkspaceRoomSyncAdapters;\n isClosed: () => boolean;\n getIdentityId: () => string;\n getSenderActor: (senderId: string) => RoomActor | null;\n onCapacityExceeded: () => void;\n onInvalidMessage: (message: string) => void;\n onUnsupportedMessage: () => void;\n};\n\nexport const createWorkspaceRoomSyncController = ({\n roomId,\n doc,\n awareness,\n adapters,\n isClosed,\n getIdentityId,\n getSenderActor,\n onCapacityExceeded,\n onInvalidMessage,\n onUnsupportedMessage,\n}: WorkspaceRoomSyncControllerOptions) => {\n const chunkAssembler = createRoomChunkAssembler();\n const pendingAwarenessClients = new Set<number>();\n const inboundEnvelopes: Array<{ envelope: EncryptedEnvelope; bufferedChars: number }> = [];\n let roomKey: CryptoKey | null = null;\n let transport: WorkspaceRoomTransport | null = null;\n let envelopeVersion = 0;\n let outboundQueue: Promise<SendPacketResult> = Promise.resolve(\"sent\");\n let pendingLocalUpdate: Uint8Array | null = null;\n let localUpdateSendInFlight = false;\n let localUpdateRetryTimer: unknown;\n let localUpdateRetryAttempt = 0;\n let awarenessSendInFlight = false;\n let pendingAwarenessReliable = false;\n let syncStep1SendInFlight = false;\n let syncStep1Pending = false;\n let inboundBufferedChars = 0;\n let inboundProcessing = false;\n let disposed = false;\n\n const unavailable = () => disposed || isClosed();\n\n const sendPacket = (packet: RoomWireDataPacket, volatile = false) => {\n if (packet.type === \"sync.message\" && packet.payload.byteLength > ROOM_WIRE_MAX_CRDT_STATE_BYTES) {\n onCapacityExceeded();\n return Promise.resolve<SendPacketResult>(\"discarded\");\n }\n const task: Promise<SendPacketResult> = outboundQueue.then(async () => {\n if (unavailable() || !roomKey || !transport?.connected) return \"offline\";\n const packets = encodeRoomWirePackets(packet, adapters.clock.createId);\n for (const plaintext of packets) {\n if (unavailable() || !transport?.connected) return \"offline\";\n envelopeVersion += 1;\n const envelope = await adapters.crypto.encryptEnvelope(\n roomKey,\n roomId,\n \"room-event\",\n envelopeVersion,\n plaintext,\n );\n if (unavailable() || !transport?.connected) return \"offline\";\n if (volatile) transport.sendVolatileEnvelope(envelope);\n else transport.sendEnvelope(envelope);\n }\n return \"sent\";\n });\n outboundQueue = task.catch(() => {\n onInvalidMessage(\"A live collaboration update could not be sent.\");\n return \"failed\";\n });\n return outboundQueue;\n };\n\n const flushSyncStep1 = () => {\n if (unavailable() || syncStep1SendInFlight || !syncStep1Pending) return;\n syncStep1Pending = false;\n syncStep1SendInFlight = true;\n const encoder = encoding.createEncoder();\n syncProtocol.writeSyncStep1(encoder, doc);\n void sendPacket({\n type: \"sync.message\",\n senderId: getIdentityId(),\n payload: encoding.toUint8Array(encoder),\n }).finally(() => {\n syncStep1SendInFlight = false;\n flushSyncStep1();\n });\n };\n\n const sendSyncStep1 = () => {\n syncStep1Pending = true;\n flushSyncStep1();\n };\n\n const flushAwareness = () => {\n if (unavailable() || awarenessSendInFlight || pendingAwarenessClients.size === 0) return;\n const clients = [...pendingAwarenessClients];\n const volatile = !pendingAwarenessReliable;\n pendingAwarenessClients.clear();\n pendingAwarenessReliable = false;\n awarenessSendInFlight = true;\n const payload = encodeAwarenessUpdate(awareness, clients);\n void sendPacket({\n type: \"awareness.updated\",\n senderId: getIdentityId(),\n payload,\n }, volatile).finally(() => {\n awarenessSendInFlight = false;\n flushAwareness();\n });\n };\n\n const publishAwareness = (clients = [awareness.clientID], volatile = true) => {\n for (const clientId of clients) pendingAwarenessClients.add(clientId);\n if (!volatile) pendingAwarenessReliable = true;\n flushAwareness();\n };\n\n const clearLocalUpdateRetry = () => {\n if (!localUpdateRetryTimer) return;\n adapters.clock.clearTimeout(localUpdateRetryTimer);\n localUpdateRetryTimer = undefined;\n };\n\n function scheduleLocalUpdateRetry() {\n if (unavailable() || localUpdateRetryTimer) return;\n const delay = Math.min(\n UPDATE_RETRY_MAX_DELAY_MS,\n UPDATE_RETRY_BASE_DELAY_MS * (2 ** localUpdateRetryAttempt),\n );\n localUpdateRetryAttempt += 1;\n localUpdateRetryTimer = adapters.clock.setTimeout(() => {\n localUpdateRetryTimer = undefined;\n flushLocalUpdates();\n }, delay);\n }\n\n function flushLocalUpdates() {\n if (unavailable() || localUpdateSendInFlight || !pendingLocalUpdate || !transport?.connected) return;\n const update = pendingLocalUpdate;\n pendingLocalUpdate = null;\n localUpdateSendInFlight = true;\n const encoder = encoding.createEncoder();\n syncProtocol.writeUpdate(encoder, update);\n void sendPacket({\n type: \"sync.message\",\n senderId: getIdentityId(),\n payload: encoding.toUint8Array(encoder),\n }).then((result) => {\n if (result !== \"sent\" && !unavailable()) {\n pendingLocalUpdate = pendingLocalUpdate\n ? Y.mergeUpdates([update, pendingLocalUpdate])\n : update;\n if (result === \"failed\") scheduleLocalUpdateRetry();\n } else if (result === \"sent\") {\n localUpdateRetryAttempt = 0;\n }\n }).finally(() => {\n localUpdateSendInFlight = false;\n if (!localUpdateRetryTimer) flushLocalUpdates();\n });\n }\n\n const handleSyncMessage = async (packet: RoomWireDataPacket) => {\n const probe = decoding.createDecoder(packet.payload);\n const messageType = decoding.readVarUint(probe);\n const senderActor = getSenderActor(packet.senderId);\n if (\n messageType !== syncProtocol.messageYjsSyncStep1 &&\n (!senderActor || !hasRoomCapability(senderActor, \"write\"))\n ) return;\n const decoder = decoding.createDecoder(packet.payload);\n const reply = encoding.createEncoder();\n syncProtocol.readSyncMessage(decoder, reply, doc, {\n type: REMOTE_SYNC_ORIGIN,\n senderId: packet.senderId,\n } satisfies RemoteSyncOrigin, () => {\n onInvalidMessage(\"A malformed collaboration update was ignored.\");\n });\n if (encoding.length(reply) > 0) {\n await sendPacket({\n type: \"sync.message\",\n senderId: getIdentityId(),\n payload: encoding.toUint8Array(reply),\n });\n }\n };\n\n const handleDataPacket = async (packet: RoomWireDataPacket) => {\n if (packet.senderId === getIdentityId()) return;\n if (packet.type === \"awareness.updated\") {\n applyAwarenessUpdate(awareness, packet.payload, REMOTE_AWARENESS_ORIGIN);\n return;\n }\n await handleSyncMessage(packet);\n };\n\n const processEnvelope = async (envelope: EncryptedEnvelope) => {\n if (unavailable() || !roomKey) return;\n try {\n const plaintext = await adapters.crypto.decryptEnvelope(roomKey, envelope);\n const decoded = decodeRoomWirePacket(plaintext);\n if (!decoded.ok) {\n if (decoded.reason === \"unsupported\") onUnsupportedMessage();\n onInvalidMessage(\"An unsupported collaboration message was ignored.\");\n return;\n }\n if (decoded.packet.type === \"sync.chunk\") {\n const assembled = chunkAssembler.push(decoded.packet);\n if (assembled) await handleDataPacket(assembled);\n } else {\n await handleDataPacket(decoded.packet);\n }\n } catch {\n onInvalidMessage(\"An encrypted collaboration message could not be opened.\");\n }\n };\n\n const drainInboundEnvelopes = async () => {\n if (inboundProcessing) return;\n inboundProcessing = true;\n try {\n while (!unavailable() && inboundEnvelopes.length > 0) {\n const next = inboundEnvelopes.shift()!;\n inboundBufferedChars -= next.bufferedChars;\n await processEnvelope(next.envelope);\n }\n } finally {\n inboundProcessing = false;\n }\n };\n\n const routeEnvelope = (value: unknown) => {\n if (unavailable()) return;\n if (!validateRoomPayload(value) || value.roomId !== roomId || value.kind !== \"room-event\") {\n onInvalidMessage(\"A collaboration server message was ignored.\");\n return;\n }\n const bufferedChars = value.ciphertext.length + value.iv.length;\n if (\n value.ciphertext.length > MAX_ENCRYPTED_ENVELOPE_CHARS ||\n inboundEnvelopes.length >= MAX_INBOUND_ENVELOPES ||\n inboundBufferedChars + bufferedChars > MAX_INBOUND_BUFFER_CHARS\n ) {\n onInvalidMessage(\"An oversized collaboration message was ignored.\");\n return;\n }\n inboundEnvelopes.push({ envelope: value, bufferedChars });\n inboundBufferedChars += bufferedChars;\n void drainInboundEnvelopes();\n };\n\n return {\n setRoomKey(key: CryptoKey) {\n roomKey = key;\n },\n connect(baseUrl: string, handlers: TransportLifecycleHandlers) {\n transport?.disconnect();\n const nextTransport = adapters.createRoomTransport({\n baseUrl,\n roomId,\n clientId: getIdentityId(),\n handlers: { ...handlers, onMessage: routeEnvelope },\n });\n transport = nextTransport;\n nextTransport.connect();\n },\n isConnected: () => Boolean(transport?.connected),\n onJoined() {\n publishAwareness([awareness.clientID], false);\n sendSyncStep1();\n clearLocalUpdateRetry();\n localUpdateRetryAttempt = 0;\n flushLocalUpdates();\n },\n onPeerJoined() {\n publishAwareness([awareness.clientID], false);\n sendSyncStep1();\n },\n onTransportDisconnected: clearLocalUpdateRetry,\n handleLocalUpdate(update: Uint8Array) {\n pendingLocalUpdate = pendingLocalUpdate ? Y.mergeUpdates([pendingLocalUpdate, update]) : update;\n flushLocalUpdates();\n },\n handleAwarenessUpdate(\n changes: { added: number[]; updated: number[]; removed: number[] },\n origin: unknown,\n ) {\n if (origin !== REMOTE_AWARENESS_ORIGIN && !unavailable()) {\n publishAwareness([...changes.added, ...changes.updated, ...changes.removed]);\n }\n },\n publishAwareness,\n pruneChunks: () => chunkAssembler.prune(),\n getResourceCounts: () => ({\n inboundEnvelopes: inboundEnvelopes.length,\n inboundBufferedChars,\n pendingAwarenessClients: pendingAwarenessClients.size,\n pendingLocalUpdateBytes: pendingLocalUpdate?.byteLength ?? 0,\n }),\n dispose() {\n if (disposed) return;\n disposed = true;\n clearLocalUpdateRetry();\n transport?.disconnect();\n transport = null;\n roomKey = null;\n pendingLocalUpdate = null;\n pendingAwarenessClients.clear();\n syncStep1Pending = false;\n inboundEnvelopes.length = 0;\n inboundBufferedChars = 0;\n chunkAssembler.clear();\n },\n };\n};\n\nexport type WorkspaceRoomSyncController = ReturnType<typeof createWorkspaceRoomSyncController>;\n"],"names":["ROOM_WIRE_PROTOCOL_VERSION","ROOM_WIRE_CHUNK_BYTES","ROOM_WIRE_CHUNK_PAYLOAD_BYTES","ROOM_WIRE_MAX_MESSAGE_BYTES","ROOM_WIRE_MAX_CRDT_STATE_BYTES","ROOM_WIRE_MAX_CHUNKS","ROOM_WIRE_MAX_INFLIGHT_PER_ACTOR","ROOM_WIRE_CHUNK_TTL_MS","ROOM_WIRE_MAX_BUFFERED_BYTES","packetTypeCodes","packetTypesByCode","validSenderId","senderId","encodeRoomWirePacket","packet","encoder","encoding","decodeRoomWirePacket","bytes","decoder","decoding","type","payload","messageId","chunkIndex","chunkCount","totalBytes","encodeRoomWirePackets","createMessageId","encoded","_","encodedChunk","createRoomChunkAssembler","pending","prune","now","key","value","entry","actorEntries","candidate","first","second","oldest","total","offset","index","chunk","decoded","HUMAN_ROOM_CAPABILITIES","AGENT_ROOM_CAPABILITIES","DEFAULT_HUMAN_ACTOR_CLIENT","DEFAULT_AGENT_ACTOR_CLIENT","ROOM_ACTOR_ADJECTIVES","ROOM_ACTOR_COLORS","DEFAULT_ACTOR_NAME","DEFAULT_ACTOR_COLOR","ROOM_ACTOR_MAX_ID_LENGTH","ROOM_ACTOR_MAX_NAME_LENGTH","ROOM_ACTOR_COLOR_PATTERN","isRecord","isRoomActorKind","isRoomActorClient","isRoomCapability","getDefaultRoomCapabilities","kind","normalizeRoomCapabilities","capabilities","normalized","hasRoomCapability","actor","capability","getStableActorIndex","seed","modulo","hash","createRoomActorName","actorId","createRoomActorColor","createRoomActor","id","name","color","client","joinedAt","_a","parseRoomActor","ROOM_CHECKPOINT_RETENTION_MS","getAdditionalData","roomId","WORKSPACE_ROOM_SCHEMA_VERSION","encryptWorkspaceRoomCheckpoint","update","roomKey","encodeEncryptedData","decryptWorkspaceRoomCheckpoint","encryptedCheckpoint","decodeEncryptedData","asString","fallback","asNumber","asOptionalString","normalizeTitle","title","createNodeMap","parentId","WORKSPACE_ROOM_ROOT_ID","order","createdAt","updatedAt","node","Y","readNode","parentValue","compareNodes","createWorkspaceRoomCrdt","doc","initialize","meta","nodes","documents","comments","validateWorkspaceRoomStructure","room","expectedRoomId","root","nodeId","parsed","parent","documentId","comment","fileId","_b","initializeWorkspaceRoomCrdt","input","text","setWorkspaceRoomComment","getWorkspaceRoomDocument","createWorkspaceRoomFolder","createWorkspaceRoomDocument","collectDescendantNodeIds","ids","changed","deleteWorkspaceRoomNode","deletedIds","commentId","renameWorkspaceRoomNode","normalizedTitle","wouldCreateCycle","currentId","visited","moveWorkspaceRoomNode","setWorkspaceRoomNodeOrder","createReplyMap","reply","map","createRelativeAnchor","assoc","body","repliesInput","WORKSPACE_ROOM_MAX_COMMENT_LENGTH","WORKSPACE_ROOM_MAX_COMMENTS","WORKSPACE_ROOM_MAX_REPLIES","anchorStart","anchorEnd","replies","deleteWorkspaceRoomComment","setWorkspaceRoomCommentResolved","resolved","addWorkspaceRoomCommentReply","readRelativeAnchor","absolute","readReplies","readComment","sortComments","getWorkspaceRoomDocumentComments","getWorkspaceRoomSnapshot","structure","getWorkspaceRoomStructureSnapshot","getWorkspaceRoomComments","documentIds","commentsByFileId","nextComment","MAX_INBOUND_ENVELOPES","MAX_INBOUND_BUFFER_CHARS","MAX_ENCRYPTED_ENVELOPE_CHARS","UPDATE_RETRY_MAX_DELAY_MS","UPDATE_RETRY_BASE_DELAY_MS","REMOTE_SYNC_ORIGIN","REMOTE_AWARENESS_ORIGIN","isRemoteSyncOrigin","origin","createWorkspaceRoomSyncController","awareness","adapters","isClosed","getIdentityId","getSenderActor","onCapacityExceeded","onInvalidMessage","onUnsupportedMessage","chunkAssembler","pendingAwarenessClients","inboundEnvelopes","transport","envelopeVersion","outboundQueue","pendingLocalUpdate","localUpdateSendInFlight","localUpdateRetryTimer","localUpdateRetryAttempt","awarenessSendInFlight","pendingAwarenessReliable","syncStep1SendInFlight","syncStep1Pending","inboundBufferedChars","inboundProcessing","disposed","unavailable","sendPacket","volatile","packets","plaintext","envelope","flushSyncStep1","syncProtocol","sendSyncStep1","flushAwareness","clients","encodeAwarenessUpdate","publishAwareness","clientId","clearLocalUpdateRetry","scheduleLocalUpdateRetry","delay","flushLocalUpdates","result","handleSyncMessage","probe","messageType","senderActor","handleDataPacket","applyAwarenessUpdate","processEnvelope","assembled","drainInboundEnvelopes","next","routeEnvelope","validateRoomPayload","bufferedChars","baseUrl","handlers","nextTransport","changes"],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as Y from "yjs";
|
|
2
|
+
import { type Awareness } from "y-protocols/awareness";
|
|
3
|
+
import { type RoomActor } from "./roomCollaboration";
|
|
4
|
+
import { type EncryptedEnvelope, type EnvelopeKind } from "./room/envelope";
|
|
5
|
+
export declare const REMOTE_SYNC_ORIGIN: unique symbol;
|
|
6
|
+
export declare const REMOTE_AWARENESS_ORIGIN: unique symbol;
|
|
7
|
+
export type RemoteSyncOrigin = {
|
|
8
|
+
type: typeof REMOTE_SYNC_ORIGIN;
|
|
9
|
+
senderId: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const isRemoteSyncOrigin: (origin: unknown) => origin is RemoteSyncOrigin;
|
|
12
|
+
export type WorkspaceRoomSyncClock = {
|
|
13
|
+
setTimeout(callback: () => void, delayMs: number): unknown;
|
|
14
|
+
clearTimeout(handle: unknown): void;
|
|
15
|
+
createId(): string;
|
|
16
|
+
};
|
|
17
|
+
export type WorkspaceRoomSyncCrypto = {
|
|
18
|
+
encryptEnvelope(roomKey: CryptoKey, roomId: string, kind: EnvelopeKind, version: number, plaintext: Uint8Array): Promise<EncryptedEnvelope>;
|
|
19
|
+
decryptEnvelope(roomKey: CryptoKey, envelope: EncryptedEnvelope): Promise<Uint8Array>;
|
|
20
|
+
};
|
|
21
|
+
export type WorkspaceRoomTransportHandlers = {
|
|
22
|
+
onConnect: () => void;
|
|
23
|
+
onJoined: (message: {
|
|
24
|
+
roomId: string;
|
|
25
|
+
clientId: string;
|
|
26
|
+
peerCount: number;
|
|
27
|
+
}) => void;
|
|
28
|
+
onPeerJoined: (message: {
|
|
29
|
+
roomId: string;
|
|
30
|
+
clientId: string;
|
|
31
|
+
}) => void;
|
|
32
|
+
onMessage: (envelope: unknown) => void;
|
|
33
|
+
onPeers: (message: {
|
|
34
|
+
roomId: string;
|
|
35
|
+
peers: string[];
|
|
36
|
+
}) => void;
|
|
37
|
+
onError: (message: {
|
|
38
|
+
error?: string;
|
|
39
|
+
}) => void;
|
|
40
|
+
onDisconnect: () => void;
|
|
41
|
+
onConnectError: () => void;
|
|
42
|
+
};
|
|
43
|
+
export type WorkspaceRoomTransport = {
|
|
44
|
+
readonly connected: boolean;
|
|
45
|
+
connect(): void;
|
|
46
|
+
sendEnvelope(envelope: EncryptedEnvelope): void;
|
|
47
|
+
sendVolatileEnvelope(envelope: EncryptedEnvelope): void;
|
|
48
|
+
disconnect(): void;
|
|
49
|
+
};
|
|
50
|
+
export type WorkspaceRoomSyncAdapters = {
|
|
51
|
+
clock: WorkspaceRoomSyncClock;
|
|
52
|
+
crypto: WorkspaceRoomSyncCrypto;
|
|
53
|
+
createRoomTransport(options: {
|
|
54
|
+
baseUrl: string;
|
|
55
|
+
roomId: string;
|
|
56
|
+
clientId: string;
|
|
57
|
+
handlers: WorkspaceRoomTransportHandlers;
|
|
58
|
+
}): WorkspaceRoomTransport;
|
|
59
|
+
};
|
|
60
|
+
type TransportLifecycleHandlers = Omit<WorkspaceRoomTransportHandlers, "onMessage">;
|
|
61
|
+
export type WorkspaceRoomSyncControllerOptions = {
|
|
62
|
+
roomId: string;
|
|
63
|
+
doc: Y.Doc;
|
|
64
|
+
awareness: Awareness;
|
|
65
|
+
adapters: WorkspaceRoomSyncAdapters;
|
|
66
|
+
isClosed: () => boolean;
|
|
67
|
+
getIdentityId: () => string;
|
|
68
|
+
getSenderActor: (senderId: string) => RoomActor | null;
|
|
69
|
+
onCapacityExceeded: () => void;
|
|
70
|
+
onInvalidMessage: (message: string) => void;
|
|
71
|
+
onUnsupportedMessage: () => void;
|
|
72
|
+
};
|
|
73
|
+
export declare const createWorkspaceRoomSyncController: ({ roomId, doc, awareness, adapters, isClosed, getIdentityId, getSenderActor, onCapacityExceeded, onInvalidMessage, onUnsupportedMessage, }: WorkspaceRoomSyncControllerOptions) => {
|
|
74
|
+
setRoomKey(key: CryptoKey): void;
|
|
75
|
+
connect(baseUrl: string, handlers: TransportLifecycleHandlers): void;
|
|
76
|
+
isConnected: () => boolean;
|
|
77
|
+
onJoined(): void;
|
|
78
|
+
onPeerJoined(): void;
|
|
79
|
+
onTransportDisconnected: () => void;
|
|
80
|
+
handleLocalUpdate(update: Uint8Array): void;
|
|
81
|
+
handleAwarenessUpdate(changes: {
|
|
82
|
+
added: number[];
|
|
83
|
+
updated: number[];
|
|
84
|
+
removed: number[];
|
|
85
|
+
}, origin: unknown): void;
|
|
86
|
+
publishAwareness: (clients?: number[], volatile?: boolean) => void;
|
|
87
|
+
pruneChunks: () => void;
|
|
88
|
+
getResourceCounts: () => {
|
|
89
|
+
inboundEnvelopes: number;
|
|
90
|
+
inboundBufferedChars: number;
|
|
91
|
+
pendingAwarenessClients: number;
|
|
92
|
+
pendingLocalUpdateBytes: number;
|
|
93
|
+
};
|
|
94
|
+
dispose(): void;
|
|
95
|
+
};
|
|
96
|
+
export type WorkspaceRoomSyncController = ReturnType<typeof createWorkspaceRoomSyncController>;
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=workspaceRoomSync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaceRoomSync.d.ts","sourceRoot":"","sources":["../src/workspaceRoomSync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type WorkspaceConnectionStatus = "idle" | "connecting" | "connected" | "reconnecting" | "disconnected" | "failed";
|
|
2
|
+
export type WorkspaceViewFile = {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
text: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const getWorkspaceStatusLabel: (status: WorkspaceConnectionStatus) => string;
|
|
8
|
+
export declare const getActiveWorkspaceStatus: ({ isLive, connectionStatus, }: {
|
|
9
|
+
isLive: boolean;
|
|
10
|
+
connectionStatus: WorkspaceConnectionStatus;
|
|
11
|
+
}) => WorkspaceConnectionStatus;
|
|
12
|
+
export declare const getWorkspaceFileSearchText: (file: WorkspaceViewFile) => string;
|
|
13
|
+
//# sourceMappingURL=workspaceViewModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaceViewModel.d.ts","sourceRoot":"","sources":["../src/workspaceViewModel.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,yBAAyB,GACjC,MAAM,GACN,YAAY,GACZ,WAAW,GACX,cAAc,GACd,cAAc,GACd,QAAQ,CAAC;AAEb,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,yBAAyB,WAQ7D,CAAC;AAEb,eAAO,MAAM,wBAAwB,GAAI,+BAGtC;IACD,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,yBAAyB,CAAC;CAC7C,8BAAyC,CAAC;AAE3C,eAAO,MAAM,0BAA0B,GAAI,MAAM,iBAAiB,WAIjE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tabula-md/tabula",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Tabula.md document, workspace CRDT, protocol, and share-link contracts.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./collaboration": {
|
|
16
|
+
"types": "./dist/collaboration.d.ts",
|
|
17
|
+
"import": "./dist/collaboration.js"
|
|
18
|
+
},
|
|
19
|
+
"./data/encryption": {
|
|
20
|
+
"types": "./dist/data/encryption.d.ts",
|
|
21
|
+
"import": "./dist/data/encryption.js"
|
|
22
|
+
},
|
|
23
|
+
"./data/encode": {
|
|
24
|
+
"types": "./dist/data/encode.d.ts",
|
|
25
|
+
"import": "./dist/data/encode.js"
|
|
26
|
+
},
|
|
27
|
+
"./data/json": {
|
|
28
|
+
"types": "./dist/data/json.d.ts",
|
|
29
|
+
"import": "./dist/data/json.js"
|
|
30
|
+
},
|
|
31
|
+
"./data/restore": {
|
|
32
|
+
"types": "./dist/data/restore.d.ts",
|
|
33
|
+
"import": "./dist/data/restore.js"
|
|
34
|
+
},
|
|
35
|
+
"./room": {
|
|
36
|
+
"types": "./dist/room/envelope.d.ts",
|
|
37
|
+
"import": "./dist/room/envelope.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"package.json"
|
|
44
|
+
],
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/tabula-md/tabula-md.git",
|
|
48
|
+
"directory": "packages/tabula"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/tabula-md/tabula-md/tree/main/packages/tabula#readme",
|
|
51
|
+
"bugs": {
|
|
52
|
+
"url": "https://github.com/tabula-md/tabula-md/issues"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public",
|
|
56
|
+
"provenance": true
|
|
57
|
+
},
|
|
58
|
+
"keywords": [
|
|
59
|
+
"markdown",
|
|
60
|
+
"local-first",
|
|
61
|
+
"collaboration",
|
|
62
|
+
"e2ee",
|
|
63
|
+
"tabula"
|
|
64
|
+
],
|
|
65
|
+
"scripts": {
|
|
66
|
+
"build": "npm run clean && npm run build:types && npm run build:js",
|
|
67
|
+
"build:js": "vite build --config vite.config.ts",
|
|
68
|
+
"build:types": "tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
69
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"yaml": "^2.9.0"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"lib0": "^0.2.117",
|
|
76
|
+
"y-protocols": "^1.0.7",
|
|
77
|
+
"yjs": "^13.6.0"
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"vite": "^6.0.0"
|
|
81
|
+
}
|
|
82
|
+
}
|