@@ -50,6 +50,8 @@ struct VpnConfig {
5050 var blockStun : Bool = true
5151 var blockDoh : Bool = true
5252 var tunnelDoh : Bool = true
53+ var coalesceStepMs : Int = 10 // full-mode batch coalescing
54+ var coalesceMaxMs : Int = 1000
5355
5456 // MARK: serialise
5557
@@ -69,6 +71,8 @@ struct VpnConfig {
6971 " block_stun " : blockStun,
7072 " block_doh " : blockDoh,
7173 " tunnel_doh " : tunnelDoh,
74+ " coalesce_step_ms " : coalesceStepMs,
75+ " coalesce_max_ms " : coalesceMaxMs,
7276 " fetch_ips_from_api " : false ,
7377 " max_ips_to_scan " : 20 ,
7478 " scan_batch_size " : 100 ,
@@ -158,6 +162,8 @@ struct VpnConfig {
158162 if let v = obj [ " block_stun " ] as? Bool { cfg. blockStun = v }
159163 if let v = obj [ " block_doh " ] as? Bool { cfg. blockDoh = v }
160164 if let v = obj [ " tunnel_doh " ] as? Bool { cfg. tunnelDoh = v }
165+ if let v = obj [ " coalesce_step_ms " ] as? Int { cfg. coalesceStepMs = v }
166+ if let v = obj [ " coalesce_max_ms " ] as? Int { cfg. coalesceMaxMs = v }
161167 // script_ids: array or single string (both Android formats)
162168 if let arr = obj [ " script_ids " ] as? [ String ] {
163169 cfg. scriptIds = arr. map { extractId ( $0) } . filter { !$0. isEmpty }
@@ -735,6 +741,31 @@ private struct AdvancedSection: View {
735741 get: { vpn. config. verifySsl } ,
736742 set: { vpn. config. verifySsl = $0; vpn. save ( ) }
737743 ) )
744+
745+ Divider ( )
746+
747+ // Full-mode batch coalescing.
748+ VStack ( alignment: . leading, spacing: 4 ) {
749+ Text ( " Batch Coalescing " ) . font ( . subheadline) . foregroundStyle ( . secondary)
750+ HStack ( spacing: 10 ) {
751+ LabeledField ( label: " Window (ms) " ) {
752+ TextField ( " 10 " , value: Binding (
753+ get: { vpn. config. coalesceStepMs } ,
754+ set: { vpn. config. coalesceStepMs = max ( 0 , $0) ; vpn. save ( ) }
755+ ) , format: . number)
756+ . keyboardType ( . numberPad)
757+ }
758+ LabeledField ( label: " Max (ms) " ) {
759+ TextField ( " 1000 " , value: Binding (
760+ get: { vpn. config. coalesceMaxMs } ,
761+ set: { vpn. config. coalesceMaxMs = max ( 0 , $0) ; vpn. save ( ) }
762+ ) , format: . number)
763+ . keyboardType ( . numberPad)
764+ }
765+ }
766+ Text ( " How long the tunnel waits to batch outbound requests to Apps Script. Lower = snappier; higher = fewer round-trips (better throughput). 0 = compiled default. " )
767+ . font ( . caption) . foregroundStyle ( . secondary)
768+ }
738769 }
739770 }
740771 }
0 commit comments