@phpsandbox/sdk 0.0.38 → 0.0.39

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.
@@ -645,6 +645,8 @@ var PHPSandbox = (() => {
645
645
  };
646
646
 
647
647
  // src/terminal.ts
648
+ var TERMINAL_INPUT_FLUSH_DELAY_MS = 8;
649
+ var terminalInputFlushPattern = /[\x00-\x1f\x7f]/;
648
650
  var Terminal = class {
649
651
  constructor(okra) {
650
652
  this.okra = okra;
@@ -668,7 +670,7 @@ var PHPSandbox = (() => {
668
670
  this.okra.listen(`terminal.output.${id}`, handler);
669
671
  }
670
672
  input(id, input) {
671
- return this.okra.invoke("terminal.input", { id, input });
673
+ return Promise.resolve(this.okra.send("terminal.input", { id, input }));
672
674
  }
673
675
  listen(event, handler) {
674
676
  return this.okra.listen(event, handler);
@@ -720,11 +722,42 @@ var PHPSandbox = (() => {
720
722
  }
721
723
  disposables.clear();
722
724
  };
725
+ let pendingInput = "";
726
+ let inputFlushTimer;
727
+ const flushInput = () => {
728
+ if (inputFlushTimer) {
729
+ clearTimeout(inputFlushTimer);
730
+ inputFlushTimer = void 0;
731
+ }
732
+ if (pendingInput === "") {
733
+ return;
734
+ }
735
+ const input2 = pendingInput;
736
+ pendingInput = "";
737
+ void this.input(id, input2);
738
+ };
739
+ const scheduleInputFlush = () => {
740
+ if (inputFlushTimer) {
741
+ return;
742
+ }
743
+ inputFlushTimer = setTimeout(flushInput, TERMINAL_INPUT_FLUSH_DELAY_MS);
744
+ };
745
+ const queueInput = (chunk) => {
746
+ pendingInput += chunk;
747
+ if (terminalInputFlushPattern.test(chunk)) {
748
+ flushInput();
749
+ return;
750
+ }
751
+ scheduleInputFlush();
752
+ };
753
+ const disposeInput = () => {
754
+ flushInput();
755
+ dispose();
756
+ };
723
757
  const input = new WritableStream({
724
- write: (chunk) => {
725
- this.input(id, chunk);
726
- },
727
- close: dispose
758
+ write: queueInput,
759
+ close: disposeInput,
760
+ abort: disposeInput
728
761
  });
729
762
  let controller = null;
730
763
  const output = new ReadableStream({
@@ -738,7 +771,7 @@ var PHPSandbox = (() => {
738
771
  },
739
772
  cancel: () => {
740
773
  controller = null;
741
- dispose();
774
+ disposeInput();
742
775
  }
743
776
  });
744
777
  const exit = new Promise((resolve) => {
@@ -750,13 +783,13 @@ var PHPSandbox = (() => {
750
783
  } catch {
751
784
  }
752
785
  }
753
- dispose();
786
+ disposeInput();
754
787
  resolve(data.exitCode);
755
788
  })
756
789
  );
757
790
  });
758
791
  const kill = once(() => {
759
- dispose();
792
+ disposeInput();
760
793
  return this.okra.invoke("terminal.close", { id });
761
794
  });
762
795
  const resize = (dimensions) => {
@@ -773,7 +806,7 @@ var PHPSandbox = (() => {
773
806
  kill,
774
807
  resize
775
808
  },
776
- dispose
809
+ dispose: disposeInput
777
810
  };
778
811
  }
779
812
  };
@@ -3327,6 +3360,7 @@ var PHPSandbox = (() => {
3327
3360
  };
3328
3361
  var _Transport_instances, connect_fn, startPeriodicPing_fn;
3329
3362
  var Transport = class {
3363
+ // 30 seconds
3330
3364
  constructor(url, eventEmitter, options = {}) {
3331
3365
  this.eventEmitter = eventEmitter;
3332
3366
  this.options = options;
@@ -3352,14 +3386,6 @@ var PHPSandbox = (() => {
3352
3386
  this.messageQueue = [];
3353
3387
  this.MAX_QUEUE_SIZE = 100;
3354
3388
  this.QUEUE_TIMEOUT = 3e4;
3355
- // 30 seconds
3356
- // Rate limiting
3357
- this.rateLimiter = {
3358
- requests: [],
3359
- maxRequests: 50,
3360
- windowMs: 1e3
3361
- // 1 second
3362
- };
3363
3389
  this.validateConfiguration(options);
3364
3390
  this.url = new URL(url);
3365
3391
  this.PING_INTERVAL = options.pingInterval ?? 3e4;
@@ -3611,9 +3637,6 @@ var PHPSandbox = (() => {
3611
3637
  if (this.terminalError) {
3612
3638
  throw this.terminalError;
3613
3639
  }
3614
- if (this.isRateLimited()) {
3615
- throw new RateLimitError("Rate limit exceeded - too many requests");
3616
- }
3617
3640
  this.clearOldQueuedMessages();
3618
3641
  const responseEvent = options.responseEvent || `${action}_${nanoid()}_response`;
3619
3642
  const errorEvent = `${responseEvent}_error`;
@@ -3710,6 +3733,27 @@ var PHPSandbox = (() => {
3710
3733
  };
3711
3734
  return this.sendWithRetry(async () => await send(), options.retries || 10);
3712
3735
  }
3736
+ send(action, data = {}) {
3737
+ if (this.terminalError) {
3738
+ throw this.terminalError;
3739
+ }
3740
+ if (!this.isConnected || this.isClosed) {
3741
+ this.log("debug", "Connection not available, dropping one-way message", {
3742
+ action
3743
+ });
3744
+ return false;
3745
+ }
3746
+ try {
3747
+ this.rws.send(this.pack({ action, data }));
3748
+ this.connectionStats.totalMessages++;
3749
+ this.log("debug", "One-way message sent", { action, data });
3750
+ return true;
3751
+ } catch (error) {
3752
+ this.connectionStats.totalErrors++;
3753
+ this.log("error", "Failed to send one-way message", { action, error });
3754
+ return false;
3755
+ }
3756
+ }
3713
3757
  pack(data) {
3714
3758
  return new Blob([encode(data)]);
3715
3759
  }
@@ -3813,7 +3857,6 @@ var PHPSandbox = (() => {
3813
3857
  if (queuedCount > 0) {
3814
3858
  this.log("debug", `Rejected ${queuedCount} queued messages due to connection close`);
3815
3859
  }
3816
- this.rateLimiter.requests = [];
3817
3860
  this.disposables.dispose();
3818
3861
  try {
3819
3862
  this.rws.close(code, reason);
@@ -3940,18 +3983,6 @@ var PHPSandbox = (() => {
3940
3983
  this.log("debug", `Cleared ${originalLength - this.messageQueue.length} expired messages`);
3941
3984
  }
3942
3985
  }
3943
- /**
3944
- * Rate limiting check
3945
- */
3946
- isRateLimited() {
3947
- const now = Date.now();
3948
- this.rateLimiter.requests = this.rateLimiter.requests.filter((timestamp) => now - timestamp < this.rateLimiter.windowMs);
3949
- if (this.rateLimiter.requests.length >= this.rateLimiter.maxRequests) {
3950
- return true;
3951
- }
3952
- this.rateLimiter.requests.push(now);
3953
- return false;
3954
- }
3955
3986
  /**
3956
3987
  * Calculate exponential backoff delay
3957
3988
  */
@@ -3986,12 +4017,6 @@ var PHPSandbox = (() => {
3986
4017
  maxSize: this.MAX_QUEUE_SIZE,
3987
4018
  oldestMessageAge: this.messageQueue.length > 0 ? now - Math.min(...this.messageQueue.map((m) => m.timestamp)) : 0
3988
4019
  },
3989
- rateLimiter: {
3990
- currentRequests: this.rateLimiter.requests.length,
3991
- maxRequests: this.rateLimiter.maxRequests,
3992
- windowMs: this.rateLimiter.windowMs,
3993
- isLimited: this.isRateLimited()
3994
- },
3995
4020
  config: {
3996
4021
  pingInterval: this.PING_INTERVAL,
3997
4022
  queueTimeout: this.QUEUE_TIMEOUT,
@@ -4057,10 +4082,6 @@ var PHPSandbox = (() => {
4057
4082
  issues.push("High average response time");
4058
4083
  recommendations.push("Check network latency and server performance");
4059
4084
  }
4060
- if (metrics.rateLimiter.isLimited) {
4061
- issues.push("Rate limiting is active");
4062
- recommendations.push("Reduce request frequency or increase rate limit");
4063
- }
4064
4085
  this.log("info", "Connection diagnostics completed", {
4065
4086
  status,
4066
4087
  issueCount: issues.length,
@@ -4081,10 +4102,6 @@ var PHPSandbox = (() => {
4081
4102
  const maintenanceInterval = setInterval(
4082
4103
  () => {
4083
4104
  this.clearOldQueuedMessages();
4084
- const now = Date.now();
4085
- this.rateLimiter.requests = this.rateLimiter.requests.filter(
4086
- (timestamp) => now - timestamp < this.rateLimiter.windowMs
4087
- );
4088
4105
  if (this.options.debug) {
4089
4106
  const health = this.getHealthStatus();
4090
4107
  const metrics = this.getConnectionMetrics();
@@ -5264,6 +5281,9 @@ var PHPSandbox = (() => {
5264
5281
  invoke(action, data = {}, options = {}) {
5265
5282
  return this.socket.invoke(action, data || {}, options);
5266
5283
  }
5284
+ send(action, data = {}) {
5285
+ return this.socket.send(action, data || {});
5286
+ }
5267
5287
  ping() {
5268
5288
  return this.invoke("ping");
5269
5289
  }