@scrypted/server 0.142.7 → 0.142.9
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/dist/rpc-serializer.d.ts +10 -2
 - package/dist/rpc-serializer.js +49 -4
 - package/dist/rpc-serializer.js.map +1 -1
 - package/package.json +3 -3
 - package/src/rpc-serializer.ts +61 -5
 
    
        package/dist/rpc-serializer.d.ts
    CHANGED
    
    | 
         @@ -6,7 +6,7 @@ export declare function createRpcSerializer(options: { 
     | 
|
| 
       6 
6 
     | 
    
         
             
                sendMessageFinish: (message: any) => void;
         
     | 
| 
       7 
7 
     | 
    
         
             
            }): {
         
     | 
| 
       8 
8 
     | 
    
         
             
                kill: (message: string) => void;
         
     | 
| 
       9 
     | 
    
         
            -
                sendMessage: (message: any, reject 
     | 
| 
      
 9 
     | 
    
         
            +
                sendMessage: (message: any, reject?: (e: Error) => void, serializationContext?: any) => void;
         
     | 
| 
       10 
10 
     | 
    
         
             
                setupRpcPeer: (peer: RpcPeer) => void;
         
     | 
| 
       11 
11 
     | 
    
         
             
                onMessageBuffer: (buffer: Buffer) => void;
         
     | 
| 
       12 
12 
     | 
    
         
             
                onMessageFinish: (message: any) => void;
         
     | 
| 
         @@ -17,6 +17,14 @@ export declare function createRpcDuplexSerializer(writable: { 
     | 
|
| 
       17 
17 
     | 
    
         
             
            }): {
         
     | 
| 
       18 
18 
     | 
    
         
             
                onData: (data: Buffer) => void;
         
     | 
| 
       19 
19 
     | 
    
         
             
                setupRpcPeer: (peer: RpcPeer) => void;
         
     | 
| 
       20 
     | 
    
         
            -
                sendMessage: (message: any, reject 
     | 
| 
      
 20 
     | 
    
         
            +
                sendMessage: (message: any, reject?: (e: Error) => void, serializationContext?: any) => void;
         
     | 
| 
      
 21 
     | 
    
         
            +
                onDisconnected: () => void;
         
     | 
| 
      
 22 
     | 
    
         
            +
            };
         
     | 
| 
      
 23 
     | 
    
         
            +
            export declare function createDataChannelSerializer(dc: {
         
     | 
| 
      
 24 
     | 
    
         
            +
                send: (data: Buffer) => void;
         
     | 
| 
      
 25 
     | 
    
         
            +
            }): {
         
     | 
| 
      
 26 
     | 
    
         
            +
                onData: (data: Buffer) => void;
         
     | 
| 
      
 27 
     | 
    
         
            +
                setupRpcPeer: (peer: RpcPeer) => void;
         
     | 
| 
      
 28 
     | 
    
         
            +
                sendMessage: (message: any, reject?: (e: Error) => void, serializationContext?: any) => void;
         
     | 
| 
       21 
29 
     | 
    
         
             
                onDisconnected: () => void;
         
     | 
| 
       22 
30 
     | 
    
         
             
            };
         
     | 
    
        package/dist/rpc-serializer.js
    CHANGED
    
    | 
         @@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); 
     | 
|
| 
       3 
3 
     | 
    
         
             
            exports.createDuplexRpcPeer = createDuplexRpcPeer;
         
     | 
| 
       4 
4 
     | 
    
         
             
            exports.createRpcSerializer = createRpcSerializer;
         
     | 
| 
       5 
5 
     | 
    
         
             
            exports.createRpcDuplexSerializer = createRpcDuplexSerializer;
         
     | 
| 
      
 6 
     | 
    
         
            +
            exports.createDataChannelSerializer = createDataChannelSerializer;
         
     | 
| 
       6 
7 
     | 
    
         
             
            const rpc_buffer_serializer_1 = require("./rpc-buffer-serializer");
         
     | 
| 
       7 
8 
     | 
    
         
             
            const rpc_1 = require("./rpc");
         
     | 
| 
       8 
9 
     | 
    
         
             
            function createDuplexRpcPeer(selfName, peerName, readable, writable) {
         
     | 
| 
         @@ -43,16 +44,15 @@ function createRpcSerializer(options) { 
     | 
|
| 
       43 
44 
     | 
    
         
             
                    }
         
     | 
| 
       44 
45 
     | 
    
         
             
                    sendMessageFinish(message);
         
     | 
| 
       45 
46 
     | 
    
         
             
                };
         
     | 
| 
       46 
     | 
    
         
            -
                let pendingSerializationContext =  
     | 
| 
      
 47 
     | 
    
         
            +
                let pendingSerializationContext = undefined;
         
     | 
| 
       47 
48 
     | 
    
         
             
                const setupRpcPeer = (peer) => {
         
     | 
| 
       48 
49 
     | 
    
         
             
                    rpcPeer = peer;
         
     | 
| 
       49 
50 
     | 
    
         
             
                    rpcPeer.addSerializer(Buffer, 'Buffer', new rpc_buffer_serializer_1.SidebandBufferSerializer());
         
     | 
| 
       50 
51 
     | 
    
         
             
                    rpcPeer.constructorSerializerMap.set(Uint8Array, 'Buffer');
         
     | 
| 
       51 
52 
     | 
    
         
             
                };
         
     | 
| 
       52 
53 
     | 
    
         
             
                const onMessageBuffer = (buffer) => {
         
     | 
| 
       53 
     | 
    
         
            -
                    pendingSerializationContext = pendingSerializationContext || {
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                    };
         
     | 
| 
      
 54 
     | 
    
         
            +
                    pendingSerializationContext = pendingSerializationContext || {};
         
     | 
| 
      
 55 
     | 
    
         
            +
                    pendingSerializationContext.buffers ||= [];
         
     | 
| 
       56 
56 
     | 
    
         
             
                    const buffers = pendingSerializationContext.buffers;
         
     | 
| 
       57 
57 
     | 
    
         
             
                    buffers.push(buffer);
         
     | 
| 
       58 
58 
     | 
    
         
             
                };
         
     | 
| 
         @@ -155,4 +155,49 @@ function createRpcDuplexSerializer(writable) { 
     | 
|
| 
       155 
155 
     | 
    
         
             
                    onDisconnected: serializer.onDisconnected,
         
     | 
| 
       156 
156 
     | 
    
         
             
                };
         
     | 
| 
       157 
157 
     | 
    
         
             
            }
         
     | 
| 
      
 158 
     | 
    
         
            +
            function createDataChannelSerializer(dc) {
         
     | 
| 
      
 159 
     | 
    
         
            +
                // Chunking and debouncing state
         
     | 
| 
      
 160 
     | 
    
         
            +
                let pending;
         
     | 
| 
      
 161 
     | 
    
         
            +
                // Max packet size for data channels is 16KB
         
     | 
| 
      
 162 
     | 
    
         
            +
                const MAX_PACKET_SIZE = 16384;
         
     | 
| 
      
 163 
     | 
    
         
            +
                // Flush pending chunks with proper chunking
         
     | 
| 
      
 164 
     | 
    
         
            +
                function flushPending() {
         
     | 
| 
      
 165 
     | 
    
         
            +
                    if (!pending || pending.length === 0)
         
     | 
| 
      
 166 
     | 
    
         
            +
                        return;
         
     | 
| 
      
 167 
     | 
    
         
            +
                    const chunks = pending;
         
     | 
| 
      
 168 
     | 
    
         
            +
                    pending = undefined;
         
     | 
| 
      
 169 
     | 
    
         
            +
                    // Process all pending chunks
         
     | 
| 
      
 170 
     | 
    
         
            +
                    for (const data of chunks) {
         
     | 
| 
      
 171 
     | 
    
         
            +
                        let offset = 0;
         
     | 
| 
      
 172 
     | 
    
         
            +
                        // Split data into chunks that fit within MAX_PACKET_SIZE
         
     | 
| 
      
 173 
     | 
    
         
            +
                        while (offset < data.length) {
         
     | 
| 
      
 174 
     | 
    
         
            +
                            const remaining = data.length - offset;
         
     | 
| 
      
 175 
     | 
    
         
            +
                            const chunkSize = Math.min(remaining, MAX_PACKET_SIZE);
         
     | 
| 
      
 176 
     | 
    
         
            +
                            const chunkData = data.subarray(offset, offset + chunkSize);
         
     | 
| 
      
 177 
     | 
    
         
            +
                            dc.send(chunkData);
         
     | 
| 
      
 178 
     | 
    
         
            +
                            offset += chunkSize;
         
     | 
| 
      
 179 
     | 
    
         
            +
                        }
         
     | 
| 
      
 180 
     | 
    
         
            +
                    }
         
     | 
| 
      
 181 
     | 
    
         
            +
                }
         
     | 
| 
      
 182 
     | 
    
         
            +
                // Queue data for sending with next-tick debouncing
         
     | 
| 
      
 183 
     | 
    
         
            +
                function queuePending(data) {
         
     | 
| 
      
 184 
     | 
    
         
            +
                    const hadPending = !!pending;
         
     | 
| 
      
 185 
     | 
    
         
            +
                    if (!pending)
         
     | 
| 
      
 186 
     | 
    
         
            +
                        pending = [];
         
     | 
| 
      
 187 
     | 
    
         
            +
                    pending.push(data);
         
     | 
| 
      
 188 
     | 
    
         
            +
                    // Schedule flush for next tick if not already scheduled
         
     | 
| 
      
 189 
     | 
    
         
            +
                    if (!hadPending) {
         
     | 
| 
      
 190 
     | 
    
         
            +
                        setTimeout(() => flushPending(), 0);
         
     | 
| 
      
 191 
     | 
    
         
            +
                    }
         
     | 
| 
      
 192 
     | 
    
         
            +
                }
         
     | 
| 
      
 193 
     | 
    
         
            +
                // Create a wrapper around the data channel send method for chunking
         
     | 
| 
      
 194 
     | 
    
         
            +
                const chunkingDataChannel = {
         
     | 
| 
      
 195 
     | 
    
         
            +
                    write: (data) => {
         
     | 
| 
      
 196 
     | 
    
         
            +
                        queuePending(data);
         
     | 
| 
      
 197 
     | 
    
         
            +
                    }
         
     | 
| 
      
 198 
     | 
    
         
            +
                };
         
     | 
| 
      
 199 
     | 
    
         
            +
                // Create the duplex serializer which handles all RPC serialization
         
     | 
| 
      
 200 
     | 
    
         
            +
                const duplexSerializer = createRpcDuplexSerializer(chunkingDataChannel);
         
     | 
| 
      
 201 
     | 
    
         
            +
                return duplexSerializer;
         
     | 
| 
      
 202 
     | 
    
         
            +
            }
         
     | 
| 
       158 
203 
     | 
    
         
             
            //# sourceMappingURL=rpc-serializer.js.map
         
     | 
| 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            {"version":3,"file":"rpc-serializer.js","sourceRoot":"","sources":["../src/rpc-serializer.ts"],"names":[],"mappings":";;AAIA,kDAkBC;AAED, 
     | 
| 
      
 1 
     | 
    
         
            +
            {"version":3,"file":"rpc-serializer.js","sourceRoot":"","sources":["../src/rpc-serializer.ts"],"names":[],"mappings":"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"}
         
     | 
    
        package/package.json
    CHANGED
    
    | 
         @@ -1,11 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            {
         
     | 
| 
       2 
2 
     | 
    
         
             
              "name": "@scrypted/server",
         
     | 
| 
       3 
     | 
    
         
            -
              "version": "0.142. 
     | 
| 
      
 3 
     | 
    
         
            +
              "version": "0.142.9",
         
     | 
| 
       4 
4 
     | 
    
         
             
              "description": "",
         
     | 
| 
       5 
5 
     | 
    
         
             
              "dependencies": {
         
     | 
| 
       6 
6 
     | 
    
         
             
                "@scrypted/ffmpeg-static": "^6.1.0-build3",
         
     | 
| 
       7 
     | 
    
         
            -
                "@scrypted/node-pty": "^1.0. 
     | 
| 
       8 
     | 
    
         
            -
                "@scrypted/types": "^0.5. 
     | 
| 
      
 7 
     | 
    
         
            +
                "@scrypted/node-pty": "^1.0.25",
         
     | 
| 
      
 8 
     | 
    
         
            +
                "@scrypted/types": "^0.5.43",
         
     | 
| 
       9 
9 
     | 
    
         
             
                "adm-zip": "^0.5.16",
         
     | 
| 
       10 
10 
     | 
    
         
             
                "body-parser": "^2.2.0",
         
     | 
| 
       11 
11 
     | 
    
         
             
                "cookie-parser": "^1.4.7",
         
     | 
    
        package/src/rpc-serializer.ts
    CHANGED
    
    | 
         @@ -35,7 +35,7 @@ export function createRpcSerializer(options: { 
     | 
|
| 
       35 
35 
     | 
    
         
             
                    rpcPeer.kill('connection closed.');
         
     | 
| 
       36 
36 
     | 
    
         
             
                }
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                const sendMessage = (message: any, reject 
     | 
| 
      
 38 
     | 
    
         
            +
                const sendMessage = (message: any, reject?: (e: Error) => void, serializationContext?: any) => {
         
     | 
| 
       39 
39 
     | 
    
         
             
                    if (!connected) {
         
     | 
| 
       40 
40 
     | 
    
         
             
                        reject?.(new Error('peer disconnected'));
         
     | 
| 
       41 
41 
     | 
    
         
             
                        return;
         
     | 
| 
         @@ -50,7 +50,7 @@ export function createRpcSerializer(options: { 
     | 
|
| 
       50 
50 
     | 
    
         
             
                    sendMessageFinish(message);
         
     | 
| 
       51 
51 
     | 
    
         
             
                }
         
     | 
| 
       52 
52 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
                let pendingSerializationContext: any =  
     | 
| 
      
 53 
     | 
    
         
            +
                let pendingSerializationContext: any = undefined;
         
     | 
| 
       54 
54 
     | 
    
         
             
                const setupRpcPeer = (peer: RpcPeer) => {
         
     | 
| 
       55 
55 
     | 
    
         
             
                    rpcPeer = peer;
         
     | 
| 
       56 
56 
     | 
    
         
             
                    rpcPeer.addSerializer(Buffer, 'Buffer', new SidebandBufferSerializer());
         
     | 
| 
         @@ -58,9 +58,8 @@ export function createRpcSerializer(options: { 
     | 
|
| 
       58 
58 
     | 
    
         
             
                }
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
                const onMessageBuffer = (buffer: Buffer) => {
         
     | 
| 
       61 
     | 
    
         
            -
                    pendingSerializationContext = pendingSerializationContext || {
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                    };
         
     | 
| 
      
 61 
     | 
    
         
            +
                    pendingSerializationContext = pendingSerializationContext || {};
         
     | 
| 
      
 62 
     | 
    
         
            +
                    pendingSerializationContext.buffers ||= [];
         
     | 
| 
       64 
63 
     | 
    
         
             
                    const buffers: Buffer[] = pendingSerializationContext.buffers;
         
     | 
| 
       65 
64 
     | 
    
         
             
                    buffers.push(buffer);
         
     | 
| 
       66 
65 
     | 
    
         
             
                };
         
     | 
| 
         @@ -181,3 +180,60 @@ export function createRpcDuplexSerializer(writable: { 
     | 
|
| 
       181 
180 
     | 
    
         
             
                    onDisconnected: serializer.onDisconnected,
         
     | 
| 
       182 
181 
     | 
    
         
             
                };
         
     | 
| 
       183 
182 
     | 
    
         
             
            }
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
            export function createDataChannelSerializer(dc: { send: (data: Buffer) => void }) {
         
     | 
| 
      
 185 
     | 
    
         
            +
                // Chunking and debouncing state
         
     | 
| 
      
 186 
     | 
    
         
            +
                let pending: Buffer[];
         
     | 
| 
      
 187 
     | 
    
         
            +
                
         
     | 
| 
      
 188 
     | 
    
         
            +
                // Max packet size for data channels is 16KB
         
     | 
| 
      
 189 
     | 
    
         
            +
                const MAX_PACKET_SIZE = 16384;
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                // Flush pending chunks with proper chunking
         
     | 
| 
      
 192 
     | 
    
         
            +
                function flushPending() {
         
     | 
| 
      
 193 
     | 
    
         
            +
                    if (!pending || pending.length === 0)
         
     | 
| 
      
 194 
     | 
    
         
            +
                        return;
         
     | 
| 
      
 195 
     | 
    
         
            +
                        
         
     | 
| 
      
 196 
     | 
    
         
            +
                    const chunks = pending;
         
     | 
| 
      
 197 
     | 
    
         
            +
                    pending = undefined;
         
     | 
| 
      
 198 
     | 
    
         
            +
                    
         
     | 
| 
      
 199 
     | 
    
         
            +
                    // Process all pending chunks
         
     | 
| 
      
 200 
     | 
    
         
            +
                    for (const data of chunks) {
         
     | 
| 
      
 201 
     | 
    
         
            +
                        let offset = 0;
         
     | 
| 
      
 202 
     | 
    
         
            +
                        
         
     | 
| 
      
 203 
     | 
    
         
            +
                        // Split data into chunks that fit within MAX_PACKET_SIZE
         
     | 
| 
      
 204 
     | 
    
         
            +
                        while (offset < data.length) {
         
     | 
| 
      
 205 
     | 
    
         
            +
                            const remaining = data.length - offset;
         
     | 
| 
      
 206 
     | 
    
         
            +
                            const chunkSize = Math.min(remaining, MAX_PACKET_SIZE);
         
     | 
| 
      
 207 
     | 
    
         
            +
                            const chunkData = data.subarray(offset, offset + chunkSize);
         
     | 
| 
      
 208 
     | 
    
         
            +
                            
         
     | 
| 
      
 209 
     | 
    
         
            +
                            dc.send(chunkData);
         
     | 
| 
      
 210 
     | 
    
         
            +
                            offset += chunkSize;
         
     | 
| 
      
 211 
     | 
    
         
            +
                        }
         
     | 
| 
      
 212 
     | 
    
         
            +
                    }
         
     | 
| 
      
 213 
     | 
    
         
            +
                }
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                // Queue data for sending with next-tick debouncing
         
     | 
| 
      
 216 
     | 
    
         
            +
                function queuePending(data: Buffer) {
         
     | 
| 
      
 217 
     | 
    
         
            +
                    const hadPending = !!pending;
         
     | 
| 
      
 218 
     | 
    
         
            +
                    if (!pending)
         
     | 
| 
      
 219 
     | 
    
         
            +
                        pending = [];
         
     | 
| 
      
 220 
     | 
    
         
            +
                    pending.push(data);
         
     | 
| 
      
 221 
     | 
    
         
            +
                    
         
     | 
| 
      
 222 
     | 
    
         
            +
                    // Schedule flush for next tick if not already scheduled
         
     | 
| 
      
 223 
     | 
    
         
            +
                    if (!hadPending) {
         
     | 
| 
      
 224 
     | 
    
         
            +
                        setTimeout(() => flushPending(), 0);
         
     | 
| 
      
 225 
     | 
    
         
            +
                    }
         
     | 
| 
      
 226 
     | 
    
         
            +
                }
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                // Create a wrapper around the data channel send method for chunking
         
     | 
| 
      
 229 
     | 
    
         
            +
                const chunkingDataChannel = {
         
     | 
| 
      
 230 
     | 
    
         
            +
                    write: (data: Buffer) => {
         
     | 
| 
      
 231 
     | 
    
         
            +
                        queuePending(data);
         
     | 
| 
      
 232 
     | 
    
         
            +
                    }
         
     | 
| 
      
 233 
     | 
    
         
            +
                };
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                // Create the duplex serializer which handles all RPC serialization
         
     | 
| 
      
 236 
     | 
    
         
            +
                const duplexSerializer = createRpcDuplexSerializer(chunkingDataChannel);
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
                return duplexSerializer;
         
     | 
| 
      
 239 
     | 
    
         
            +
            }
         
     |