@phpsandbox/sdk 0.0.38 → 0.0.40

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.
@@ -335,6 +335,8 @@ var PHPSandbox = (() => {
335
335
  NotebookInstance: () => NotebookInstance,
336
336
  NotebookMail: () => NotebookMail,
337
337
  NotebookMailApi: () => NotebookMailApi,
338
+ NotebookPreview: () => NotebookPreview,
339
+ NotebookPreviewApi: () => NotebookPreviewApi,
338
340
  NotebookPreviewAuth: () => NotebookPreviewAuth,
339
341
  NotebookPreviewAuthApi: () => NotebookPreviewAuthApi,
340
342
  NotebookSecretApi: () => NotebookSecretApi,
@@ -645,6 +647,8 @@ var PHPSandbox = (() => {
645
647
  };
646
648
 
647
649
  // src/terminal.ts
650
+ var TERMINAL_INPUT_FLUSH_DELAY_MS = 8;
651
+ var terminalInputFlushPattern = /[\x00-\x1f\x7f]/;
648
652
  var Terminal = class {
649
653
  constructor(okra) {
650
654
  this.okra = okra;
@@ -668,7 +672,7 @@ var PHPSandbox = (() => {
668
672
  this.okra.listen(`terminal.output.${id}`, handler);
669
673
  }
670
674
  input(id, input) {
671
- return this.okra.invoke("terminal.input", { id, input });
675
+ return Promise.resolve(this.okra.send("terminal.input", { id, input }));
672
676
  }
673
677
  listen(event, handler) {
674
678
  return this.okra.listen(event, handler);
@@ -720,11 +724,42 @@ var PHPSandbox = (() => {
720
724
  }
721
725
  disposables.clear();
722
726
  };
727
+ let pendingInput = "";
728
+ let inputFlushTimer;
729
+ const flushInput = () => {
730
+ if (inputFlushTimer) {
731
+ clearTimeout(inputFlushTimer);
732
+ inputFlushTimer = void 0;
733
+ }
734
+ if (pendingInput === "") {
735
+ return;
736
+ }
737
+ const input2 = pendingInput;
738
+ pendingInput = "";
739
+ void this.input(id, input2);
740
+ };
741
+ const scheduleInputFlush = () => {
742
+ if (inputFlushTimer) {
743
+ return;
744
+ }
745
+ inputFlushTimer = setTimeout(flushInput, TERMINAL_INPUT_FLUSH_DELAY_MS);
746
+ };
747
+ const queueInput = (chunk) => {
748
+ pendingInput += chunk;
749
+ if (terminalInputFlushPattern.test(chunk)) {
750
+ flushInput();
751
+ return;
752
+ }
753
+ scheduleInputFlush();
754
+ };
755
+ const disposeInput = () => {
756
+ flushInput();
757
+ dispose();
758
+ };
723
759
  const input = new WritableStream({
724
- write: (chunk) => {
725
- this.input(id, chunk);
726
- },
727
- close: dispose
760
+ write: queueInput,
761
+ close: disposeInput,
762
+ abort: disposeInput
728
763
  });
729
764
  let controller = null;
730
765
  const output = new ReadableStream({
@@ -738,7 +773,7 @@ var PHPSandbox = (() => {
738
773
  },
739
774
  cancel: () => {
740
775
  controller = null;
741
- dispose();
776
+ disposeInput();
742
777
  }
743
778
  });
744
779
  const exit = new Promise((resolve) => {
@@ -750,13 +785,13 @@ var PHPSandbox = (() => {
750
785
  } catch {
751
786
  }
752
787
  }
753
- dispose();
788
+ disposeInput();
754
789
  resolve(data.exitCode);
755
790
  })
756
791
  );
757
792
  });
758
793
  const kill = once(() => {
759
- dispose();
794
+ disposeInput();
760
795
  return this.okra.invoke("terminal.close", { id });
761
796
  });
762
797
  const resize = (dimensions) => {
@@ -773,7 +808,7 @@ var PHPSandbox = (() => {
773
808
  kill,
774
809
  resize
775
810
  },
776
- dispose
811
+ dispose: disposeInput
777
812
  };
778
813
  }
779
814
  };
@@ -3327,6 +3362,7 @@ var PHPSandbox = (() => {
3327
3362
  };
3328
3363
  var _Transport_instances, connect_fn, startPeriodicPing_fn;
3329
3364
  var Transport = class {
3365
+ // 30 seconds
3330
3366
  constructor(url, eventEmitter, options = {}) {
3331
3367
  this.eventEmitter = eventEmitter;
3332
3368
  this.options = options;
@@ -3352,14 +3388,6 @@ var PHPSandbox = (() => {
3352
3388
  this.messageQueue = [];
3353
3389
  this.MAX_QUEUE_SIZE = 100;
3354
3390
  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
3391
  this.validateConfiguration(options);
3364
3392
  this.url = new URL(url);
3365
3393
  this.PING_INTERVAL = options.pingInterval ?? 3e4;
@@ -3611,9 +3639,6 @@ var PHPSandbox = (() => {
3611
3639
  if (this.terminalError) {
3612
3640
  throw this.terminalError;
3613
3641
  }
3614
- if (this.isRateLimited()) {
3615
- throw new RateLimitError("Rate limit exceeded - too many requests");
3616
- }
3617
3642
  this.clearOldQueuedMessages();
3618
3643
  const responseEvent = options.responseEvent || `${action}_${nanoid()}_response`;
3619
3644
  const errorEvent = `${responseEvent}_error`;
@@ -3710,6 +3735,27 @@ var PHPSandbox = (() => {
3710
3735
  };
3711
3736
  return this.sendWithRetry(async () => await send(), options.retries || 10);
3712
3737
  }
3738
+ send(action, data = {}) {
3739
+ if (this.terminalError) {
3740
+ throw this.terminalError;
3741
+ }
3742
+ if (!this.isConnected || this.isClosed) {
3743
+ this.log("debug", "Connection not available, dropping one-way message", {
3744
+ action
3745
+ });
3746
+ return false;
3747
+ }
3748
+ try {
3749
+ this.rws.send(this.pack({ action, data }));
3750
+ this.connectionStats.totalMessages++;
3751
+ this.log("debug", "One-way message sent", { action, data });
3752
+ return true;
3753
+ } catch (error) {
3754
+ this.connectionStats.totalErrors++;
3755
+ this.log("error", "Failed to send one-way message", { action, error });
3756
+ return false;
3757
+ }
3758
+ }
3713
3759
  pack(data) {
3714
3760
  return new Blob([encode(data)]);
3715
3761
  }
@@ -3813,7 +3859,6 @@ var PHPSandbox = (() => {
3813
3859
  if (queuedCount > 0) {
3814
3860
  this.log("debug", `Rejected ${queuedCount} queued messages due to connection close`);
3815
3861
  }
3816
- this.rateLimiter.requests = [];
3817
3862
  this.disposables.dispose();
3818
3863
  try {
3819
3864
  this.rws.close(code, reason);
@@ -3940,18 +3985,6 @@ var PHPSandbox = (() => {
3940
3985
  this.log("debug", `Cleared ${originalLength - this.messageQueue.length} expired messages`);
3941
3986
  }
3942
3987
  }
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
3988
  /**
3956
3989
  * Calculate exponential backoff delay
3957
3990
  */
@@ -3986,12 +4019,6 @@ var PHPSandbox = (() => {
3986
4019
  maxSize: this.MAX_QUEUE_SIZE,
3987
4020
  oldestMessageAge: this.messageQueue.length > 0 ? now - Math.min(...this.messageQueue.map((m) => m.timestamp)) : 0
3988
4021
  },
3989
- rateLimiter: {
3990
- currentRequests: this.rateLimiter.requests.length,
3991
- maxRequests: this.rateLimiter.maxRequests,
3992
- windowMs: this.rateLimiter.windowMs,
3993
- isLimited: this.isRateLimited()
3994
- },
3995
4022
  config: {
3996
4023
  pingInterval: this.PING_INTERVAL,
3997
4024
  queueTimeout: this.QUEUE_TIMEOUT,
@@ -4057,10 +4084,6 @@ var PHPSandbox = (() => {
4057
4084
  issues.push("High average response time");
4058
4085
  recommendations.push("Check network latency and server performance");
4059
4086
  }
4060
- if (metrics.rateLimiter.isLimited) {
4061
- issues.push("Rate limiting is active");
4062
- recommendations.push("Reduce request frequency or increase rate limit");
4063
- }
4064
4087
  this.log("info", "Connection diagnostics completed", {
4065
4088
  status,
4066
4089
  issueCount: issues.length,
@@ -4081,10 +4104,6 @@ var PHPSandbox = (() => {
4081
4104
  const maintenanceInterval = setInterval(
4082
4105
  () => {
4083
4106
  this.clearOldQueuedMessages();
4084
- const now = Date.now();
4085
- this.rateLimiter.requests = this.rateLimiter.requests.filter(
4086
- (timestamp) => now - timestamp < this.rateLimiter.windowMs
4087
- );
4088
4107
  if (this.options.debug) {
4089
4108
  const health = this.getHealthStatus();
4090
4109
  const metrics = this.getConnectionMetrics();
@@ -5049,6 +5068,7 @@ var PHPSandbox = (() => {
5049
5068
  this.client = client;
5050
5069
  this.secrets = new NotebookSecretApi(client);
5051
5070
  this.previewAuth = new NotebookPreviewAuthApi(client);
5071
+ this.preview = this.previewAuth;
5052
5072
  this.mail = new NotebookMailApi(client);
5053
5073
  }
5054
5074
  async create(template, input = {}, init = true) {
@@ -5156,20 +5176,36 @@ var PHPSandbox = (() => {
5156
5176
  await this.client.delete(`/notebook/${id}/secrets/${encodeURIComponent(name)}`);
5157
5177
  }
5158
5178
  };
5159
- var NotebookPreviewAuthApi = class {
5179
+ var NotebookPreviewApi = class {
5160
5180
  constructor(client) {
5161
5181
  this.client = client;
5162
5182
  }
5163
5183
  async get(id) {
5164
- const response = await this.client.get(`/notebook/${id}/preview-auth`);
5184
+ const response = await this.client.get(`/notebook/${id}/preview`);
5165
5185
  return response.data;
5166
5186
  }
5167
- async set(id, input) {
5168
- const response = await this.client.put(`/notebook/${id}/preview-auth`, input);
5187
+ async setPassword(id, input) {
5188
+ const response = await this.client.put(`/notebook/${id}/preview`, input);
5169
5189
  return response.data;
5170
5190
  }
5171
- async delete(id) {
5172
- await this.client.delete(`/notebook/${id}/preview-auth`);
5191
+ async disable(id) {
5192
+ await this.client.delete(`/notebook/${id}/preview`);
5193
+ }
5194
+ async createSession(id) {
5195
+ const response = await this.client.post(`/notebook/${id}/preview/session`);
5196
+ return response.data;
5197
+ }
5198
+ async createHandoff(id, input) {
5199
+ const response = await this.client.post(`/notebook/${id}/preview/handoff`, input);
5200
+ return response.data;
5201
+ }
5202
+ };
5203
+ var NotebookPreviewAuthApi = class extends NotebookPreviewApi {
5204
+ set(id, input) {
5205
+ return this.setPassword(id, input);
5206
+ }
5207
+ delete(id) {
5208
+ return this.disable(id);
5173
5209
  }
5174
5210
  };
5175
5211
  var NotebookMailApi = class {
@@ -5232,6 +5268,7 @@ var PHPSandbox = (() => {
5232
5268
  this.services = new Services(this);
5233
5269
  this.secrets = new NotebookSecrets(client, this.data.id);
5234
5270
  this.previewAuth = new NotebookPreviewAuth(client, this.data.id);
5271
+ this.preview = this.previewAuth;
5235
5272
  this.mail = new NotebookMail(client, this.data.id);
5236
5273
  }
5237
5274
  async ready() {
@@ -5264,6 +5301,9 @@ var PHPSandbox = (() => {
5264
5301
  invoke(action, data = {}, options = {}) {
5265
5302
  return this.socket.invoke(action, data || {}, options);
5266
5303
  }
5304
+ send(action, data = {}) {
5305
+ return this.socket.send(action, data || {});
5306
+ }
5267
5307
  ping() {
5268
5308
  return this.invoke("ping");
5269
5309
  }
@@ -5406,19 +5446,30 @@ var PHPSandbox = (() => {
5406
5446
  return this.client.notebook.secrets.delete(this.notebookId, name);
5407
5447
  }
5408
5448
  };
5409
- var NotebookPreviewAuth = class {
5449
+ var NotebookPreview = class {
5410
5450
  constructor(client, notebookId) {
5411
5451
  this.client = client;
5412
5452
  this.notebookId = notebookId;
5413
5453
  }
5414
5454
  get() {
5415
- return this.client.notebook.previewAuth.get(this.notebookId);
5455
+ return this.client.notebook.preview.get(this.notebookId);
5416
5456
  }
5417
- set(input) {
5418
- return this.client.notebook.previewAuth.set(this.notebookId, input);
5457
+ setPassword(input) {
5458
+ return this.client.notebook.preview.setPassword(this.notebookId, input);
5419
5459
  }
5420
5460
  disable() {
5421
- return this.client.notebook.previewAuth.delete(this.notebookId);
5461
+ return this.client.notebook.preview.disable(this.notebookId);
5462
+ }
5463
+ createSession() {
5464
+ return this.client.notebook.preview.createSession(this.notebookId);
5465
+ }
5466
+ createHandoff(input) {
5467
+ return this.client.notebook.preview.createHandoff(this.notebookId, input);
5468
+ }
5469
+ };
5470
+ var NotebookPreviewAuth = class extends NotebookPreview {
5471
+ set(input) {
5472
+ return this.setPassword(input);
5422
5473
  }
5423
5474
  };
5424
5475
  var NotebookMail = class {