@@ -72,6 +72,7 @@ import {
7272 type ChatMessage ,
7373 type DataPublishOptions ,
7474 type SendTextOptions ,
75+ type StreamTextOptions ,
7576 type TextStreamInfo ,
7677} from '../types' ;
7778import {
@@ -1512,11 +1513,10 @@ export default class LocalParticipant extends Participant {
15121513 return msg ;
15131514 }
15141515
1515- async sendText ( text : string , options ?: SendTextOptions ) : Promise < { id : string } > {
1516+ async sendText ( text : string , options ?: SendTextOptions ) : Promise < TextStreamInfo > {
15161517 const streamId = crypto . randomUUID ( ) ;
15171518 const textInBytes = new TextEncoder ( ) . encode ( text ) ;
15181519 const totalTextLength = textInBytes . byteLength ;
1519- const totalTextChunks = Math . ceil ( totalTextLength / STREAM_CHUNK_SIZE ) ;
15201520
15211521 const fileIds = options ?. attachments ?. map ( ( ) => crypto . randomUUID ( ) ) ;
15221522
@@ -1528,67 +1528,29 @@ export default class LocalParticipant extends Participant {
15281528 options ?. onProgress ?.( totalProgress ) ;
15291529 } ;
15301530
1531- const header = new DataStream_Header ( {
1531+ const writer = await this . streamText ( {
15321532 streamId,
1533- totalLength : numberToBigInt ( totalTextLength ) ,
1534- mimeType : 'text/plain' ,
1533+ totalSize : totalTextLength ,
1534+ destinationIdentities : options ?. destinationIdentities ,
15351535 topic : options ?. topic ,
1536- timestamp : numberToBigInt ( Date . now ( ) ) ,
1537- contentHeader : {
1538- case : 'textHeader' ,
1539- value : new DataStream_TextHeader ( {
1540- operationType : DataStream_OperationType . CREATE ,
1541- attachedStreamIds : fileIds ,
1542- } ) ,
1543- } ,
1536+ attachedStreamIds : fileIds ,
15441537 } ) ;
15451538
1546- const destinationIdentities = options ?. destinationIdentities ;
1547-
1548- const packet = new DataPacket ( {
1549- destinationIdentities,
1550- value : {
1551- case : 'streamHeader' ,
1552- value : header ,
1553- } ,
1554- } ) ;
1555-
1556- await this . engine . sendDataPacket ( packet , DataPacket_Kind . RELIABLE ) ;
1539+ const textChunkSize = Math . floor ( STREAM_CHUNK_SIZE / 4 ) ; // utf8 is at most 4 bytes long, so play it safe and take a quarter of the byte size to slice the string
1540+ const totalTextChunks = Math . ceil ( totalTextLength / textChunkSize ) ;
15571541
15581542 for ( let i = 0 ; i < totalTextChunks ; i ++ ) {
1559- const chunkData = textInBytes . slice (
1560- i * STREAM_CHUNK_SIZE ,
1561- Math . min ( ( i + 1 ) * STREAM_CHUNK_SIZE , totalTextLength ) ,
1543+ const chunkData = text . slice (
1544+ i * textChunkSize ,
1545+ Math . min ( ( i + 1 ) * textChunkSize , totalTextLength ) ,
15621546 ) ;
15631547 await this . engine . waitForBufferStatusLow ( DataPacket_Kind . RELIABLE ) ;
1564- const chunk = new DataStream_Chunk ( {
1565- content : chunkData ,
1566- streamId,
1567- chunkIndex : numberToBigInt ( i ) ,
1568- } ) ;
1569- const chunkPacket = new DataPacket ( {
1570- destinationIdentities,
1571- value : {
1572- case : 'streamChunk' ,
1573- value : chunk ,
1574- } ,
1575- } ) ;
1548+ await writer . write ( chunkData ) ;
15761549
1577- await this . engine . sendDataPacket ( chunkPacket , DataPacket_Kind . RELIABLE ) ;
15781550 handleProgress ( Math . ceil ( ( i + 1 ) / totalTextChunks ) , 0 ) ;
15791551 }
15801552
1581- const trailer = new DataStream_Trailer ( {
1582- streamId,
1583- } ) ;
1584- const trailerPacket = new DataPacket ( {
1585- destinationIdentities,
1586- value : {
1587- case : 'streamTrailer' ,
1588- value : trailer ,
1589- } ,
1590- } ) ;
1591- await this . engine . sendDataPacket ( trailerPacket , DataPacket_Kind . RELIABLE ) ;
1553+ await writer . close ( ) ;
15921554
15931555 if ( options ?. attachments && fileIds ) {
15941556 await Promise . all (
@@ -1603,34 +1565,39 @@ export default class LocalParticipant extends Participant {
16031565 ) ,
16041566 ) ;
16051567 }
1606- return { id : streamId } ;
1568+ return writer . info ;
16071569 }
16081570
16091571 /**
16101572 * @internal
16111573 * @experimental CAUTION, might get removed in a minor release
16121574 */
1613- async streamText ( options ?: {
1614- topic ?: string ;
1615- destinationIdentities ?: Array < string > ;
1616- } ) : Promise < TextStreamWriter > {
1617- const streamId = crypto . randomUUID ( ) ;
1575+ async streamText ( options ?: StreamTextOptions ) : Promise < TextStreamWriter > {
1576+ const streamId = options ?. streamId ?? crypto . randomUUID ( ) ;
16181577
16191578 const info : TextStreamInfo = {
16201579 id : streamId ,
16211580 mimeType : 'text/plain' ,
16221581 timestamp : Date . now ( ) ,
16231582 topic : options ?. topic ?? '' ,
1583+ size : options ?. totalSize ,
16241584 } ;
16251585 const header = new DataStream_Header ( {
16261586 streamId,
16271587 mimeType : info . mimeType ,
16281588 topic : info . topic ,
16291589 timestamp : numberToBigInt ( info . timestamp ) ,
1590+ totalLength : numberToBigInt ( options ?. totalSize ) ,
16301591 contentHeader : {
16311592 case : 'textHeader' ,
16321593 value : new DataStream_TextHeader ( {
1633- operationType : DataStream_OperationType . CREATE ,
1594+ version : options ?. version ,
1595+ attachedStreamIds : options ?. attachedStreamIds ,
1596+ replyToStreamId : options ?. replyToStreamId ,
1597+ operationType :
1598+ options ?. type === 'update'
1599+ ? DataStream_OperationType . UPDATE
1600+ : DataStream_OperationType . CREATE ,
16341601 } ) ,
16351602 } ,
16361603 } ) ;
0 commit comments