1- import { Buffer } from 'node:buffer'
1+ import { Buffer } from 'node:buffer' ;
2+
3+ const TD = new TextDecoder ( ) ;
4+ const EMPTY_U8 = new Uint8Array ( 0 ) ;
25
36export class ProtoWriter {
4- constructor ( ) { this . chunks = [ ] ; }
7+ constructor ( ) { this . chunks = [ ] ; this . length = 0 ; }
8+ _push ( c ) {
9+ this . chunks . push ( c ) ;
10+ this . length += typeof c === 'number' ? 1 : c . length ;
11+ }
512 writeVarint ( value ) {
613 let v = BigInt ( value ) ;
7- while ( v > 127n ) { this . chunks . push ( ( Number ( v & 127n ) | 128 ) ) ; v >>= 7n ; }
8- this . chunks . push ( Number ( v ) ) ;
14+ while ( v > 127n ) { this . _push ( ( Number ( v & 127n ) | 128 ) ) ; v >>= 7n ; }
15+ this . _push ( Number ( v ) ) ;
916 }
1017 writeTag ( fieldNumber , wireType ) { this . writeVarint ( ( fieldNumber << 3 ) | wireType ) ; }
1118 writeString ( fieldNumber , str ) {
1219 if ( ! str ) return ; // Canonical: omit "", null, undefined
1320 const buf = Buffer . from ( str , 'utf8' ) ;
1421 this . writeTag ( fieldNumber , 2 ) ;
1522 this . writeVarint ( buf . length ) ;
16- this . chunks . push ( buf ) ;
23+ this . _push ( buf ) ;
1724 }
1825 writeBytes ( fieldNumber , buffer ) {
1926 if ( ! buffer || buffer . length === 0 ) return ; // Canonical: omit
@@ -22,7 +29,7 @@ export class ProtoWriter {
2229 }
2330 this . writeTag ( fieldNumber , 2 ) ;
2431 this . writeVarint ( buffer . length ) ;
25- this . chunks . push ( buffer ) ;
32+ this . _push ( buffer ) ;
2633 }
2734 writeInt32 ( fieldNumber , value ) {
2835 if ( ! value ) return ; // Canonical: omit 0, null, undefined
@@ -45,18 +52,17 @@ export class ProtoWriter {
4552 this . writeTag ( fieldNumber , 5 ) ;
4653 const buf = Buffer . alloc ( 4 ) ;
4754 buf . writeFloatLE ( value ) ;
48- this . chunks . push ( buf ) ;
55+ this . _push ( buf ) ;
4956 }
5057 writeMessage ( fieldNumber , writer ) {
5158 const buf = writer . finish ( ) ;
5259 if ( buf . length === 0 ) return ;
5360 this . writeTag ( fieldNumber , 2 ) ;
5461 this . writeVarint ( buf . length ) ;
55- this . chunks . push ( buf ) ;
62+ this . _push ( buf ) ;
5663 }
5764 finish ( ) {
58- const totalLen = this . chunks . reduce ( ( acc , c ) => acc + ( typeof c === 'number' ? 1 : c . length ) , 0 ) ;
59- const buf = new Uint8Array ( totalLen ) ;
65+ const buf = new Uint8Array ( this . length ) ;
6066 let offset = 0 ;
6167 for ( const c of this . chunks ) {
6268 if ( typeof c === 'number' ) buf [ offset ++ ] = c ;
@@ -80,16 +86,15 @@ export class ProtoReader {
8086 return result ;
8187 }
8288 readString ( ) {
83- const v = this . readVarint ( ) ;
84- const len = Number ( v ) ;
89+ const len = Number ( this . readVarint ( ) ) ;
8590 if ( this . pos + len > this . buffer . length ) return "" ;
86- const str = new TextDecoder ( ) . decode ( this . buffer . subarray ( this . pos , this . pos + len ) ) ;
91+ const str = TD . decode ( this . buffer . subarray ( this . pos , this . pos + len ) ) ;
8792 this . pos += len ;
8893 return str ;
8994 }
9095 readBytes ( ) {
9196 const len = Number ( this . readVarint ( ) ) ;
92- if ( this . pos + len > this . buffer . length ) return new Uint8Array ( 0 ) ;
97+ if ( this . pos + len > this . buffer . length ) return EMPTY_U8 ;
9398 const bytes = this . buffer . subarray ( this . pos , this . pos + len ) ;
9499 this . pos += len ;
95100 return bytes ;
@@ -393,7 +398,7 @@ export const NextRequestPolicy = {
393398function isMostlyPrintableUtf8 ( u8 ) {
394399 if ( ! u8 || ! u8 . length ) return false ;
395400 try {
396- const s = new TextDecoder ( ) . decode ( u8 ) ;
401+ const s = TD . decode ( u8 ) ;
397402 if ( ! s ) return false ;
398403 let ok = 0 ;
399404 for ( let i = 0 ; i < s . length ; i ++ ) {
@@ -430,7 +435,7 @@ function decodeProtobufObject(reader, len, depth = 2) {
430435 } else if ( wireType === 2 ) {
431436 const b = reader . readBytes ( ) ;
432437 const entry = { len : b . length } ;
433- if ( isMostlyPrintableUtf8 ( b ) && b . length <= 256 ) entry . utf8 = new TextDecoder ( ) . decode ( b ) ;
438+ if ( isMostlyPrintableUtf8 ( b ) && b . length <= 256 ) entry . utf8 = TD . decode ( b ) ;
434439 if ( depth > 0 && b . length ) {
435440 try {
436441 const nested = decodeProtobufObject ( new ProtoReader ( b ) , b . length , depth - 1 ) ;
@@ -475,6 +480,13 @@ export const RequestCancellationPolicy = {
475480 }
476481} ;
477482
483+ export const ReloadPlaybackContext = {
484+ decode ( reader , len ) {
485+ // Unknown schema; return wire-level decoded object like other unknown messages.
486+ return decodeProtobufObject ( reader , len , 2 ) ;
487+ }
488+ } ;
489+
478490export const StreamerContext = {
479491 encode ( msg , writer ) {
480492 if ( msg . clientInfo ) {
@@ -526,9 +538,12 @@ export const UMPPartId = {
526538} ;
527539
528540export function base64ToU8 ( base64 ) {
529- const standard_base64 = base64 . replace ( / - / g, '+' ) . replace ( / _ / g, '/' ) ;
530- const padded_base64 = standard_base64 . padEnd ( standard_base64 . length + ( 4 - standard_base64 . length % 4 ) % 4 , '=' ) ;
531- return new Uint8Array ( Buffer . from ( padded_base64 , 'base64' ) ) ;
541+ let s = base64 ;
542+ if ( s . includes ( '-' ) ) s = s . replaceAll ( '-' , '+' ) ;
543+ if ( s . includes ( '_' ) ) s = s . replaceAll ( '_' , '/' ) ;
544+ const mod = s . length & 3 ;
545+ if ( mod ) s += '=' . repeat ( 4 - mod ) ;
546+ return new Uint8Array ( Buffer . from ( s , 'base64' ) ) ;
532547}
533548
534549export function concatenateChunks ( chunks ) {
0 commit comments