@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.
@@ -596,6 +596,8 @@ var once = (fn) => {
596
596
  };
597
597
 
598
598
  // src/terminal.ts
599
+ var TERMINAL_INPUT_FLUSH_DELAY_MS = 8;
600
+ var terminalInputFlushPattern = /[\x00-\x1f\x7f]/;
599
601
  var Terminal = class {
600
602
  constructor(okra) {
601
603
  this.okra = okra;
@@ -619,7 +621,7 @@ var Terminal = class {
619
621
  this.okra.listen(`terminal.output.${id}`, handler);
620
622
  }
621
623
  input(id, input) {
622
- return this.okra.invoke("terminal.input", { id, input });
624
+ return Promise.resolve(this.okra.send("terminal.input", { id, input }));
623
625
  }
624
626
  listen(event, handler) {
625
627
  return this.okra.listen(event, handler);
@@ -671,11 +673,42 @@ var Terminal = class {
671
673
  }
672
674
  disposables.clear();
673
675
  };
676
+ let pendingInput = "";
677
+ let inputFlushTimer;
678
+ const flushInput = () => {
679
+ if (inputFlushTimer) {
680
+ clearTimeout(inputFlushTimer);
681
+ inputFlushTimer = void 0;
682
+ }
683
+ if (pendingInput === "") {
684
+ return;
685
+ }
686
+ const input2 = pendingInput;
687
+ pendingInput = "";
688
+ void this.input(id, input2);
689
+ };
690
+ const scheduleInputFlush = () => {
691
+ if (inputFlushTimer) {
692
+ return;
693
+ }
694
+ inputFlushTimer = setTimeout(flushInput, TERMINAL_INPUT_FLUSH_DELAY_MS);
695
+ };
696
+ const queueInput = (chunk) => {
697
+ pendingInput += chunk;
698
+ if (terminalInputFlushPattern.test(chunk)) {
699
+ flushInput();
700
+ return;
701
+ }
702
+ scheduleInputFlush();
703
+ };
704
+ const disposeInput = () => {
705
+ flushInput();
706
+ dispose();
707
+ };
674
708
  const input = new WritableStream({
675
- write: (chunk) => {
676
- this.input(id, chunk);
677
- },
678
- close: dispose
709
+ write: queueInput,
710
+ close: disposeInput,
711
+ abort: disposeInput
679
712
  });
680
713
  let controller = null;
681
714
  const output = new ReadableStream({
@@ -689,7 +722,7 @@ var Terminal = class {
689
722
  },
690
723
  cancel: () => {
691
724
  controller = null;
692
- dispose();
725
+ disposeInput();
693
726
  }
694
727
  });
695
728
  const exit = new Promise((resolve) => {
@@ -701,13 +734,13 @@ var Terminal = class {
701
734
  } catch {
702
735
  }
703
736
  }
704
- dispose();
737
+ disposeInput();
705
738
  resolve(data.exitCode);
706
739
  })
707
740
  );
708
741
  });
709
742
  const kill = once(() => {
710
- dispose();
743
+ disposeInput();
711
744
  return this.okra.invoke("terminal.close", { id });
712
745
  });
713
746
  const resize = (dimensions) => {
@@ -724,7 +757,7 @@ var Terminal = class {
724
757
  kill,
725
758
  resize
726
759
  },
727
- dispose
760
+ dispose: disposeInput
728
761
  };
729
762
  }
730
763
  };
@@ -3278,6 +3311,7 @@ var InvalidConfigurationError = class extends Error {
3278
3311
  };
3279
3312
  var _Transport_instances, connect_fn, startPeriodicPing_fn;
3280
3313
  var Transport = class {
3314
+ // 30 seconds
3281
3315
  constructor(url, eventEmitter, options = {}) {
3282
3316
  this.eventEmitter = eventEmitter;
3283
3317
  this.options = options;
@@ -3303,14 +3337,6 @@ var Transport = class {
3303
3337
  this.messageQueue = [];
3304
3338
  this.MAX_QUEUE_SIZE = 100;
3305
3339
  this.QUEUE_TIMEOUT = 3e4;
3306
- // 30 seconds
3307
- // Rate limiting
3308
- this.rateLimiter = {
3309
- requests: [],
3310
- maxRequests: 50,
3311
- windowMs: 1e3
3312
- // 1 second
3313
- };
3314
3340
  this.validateConfiguration(options);
3315
3341
  this.url = new URL(url);
3316
3342
  this.PING_INTERVAL = options.pingInterval ?? 3e4;
@@ -3562,9 +3588,6 @@ var Transport = class {
3562
3588
  if (this.terminalError) {
3563
3589
  throw this.terminalError;
3564
3590
  }
3565
- if (this.isRateLimited()) {
3566
- throw new RateLimitError("Rate limit exceeded - too many requests");
3567
- }
3568
3591
  this.clearOldQueuedMessages();
3569
3592
  const responseEvent = options.responseEvent || `${action}_${nanoid()}_response`;
3570
3593
  const errorEvent = `${responseEvent}_error`;
@@ -3661,6 +3684,27 @@ var Transport = class {
3661
3684
  };
3662
3685
  return this.sendWithRetry(async () => await send(), options.retries || 10);
3663
3686
  }
3687
+ send(action, data = {}) {
3688
+ if (this.terminalError) {
3689
+ throw this.terminalError;
3690
+ }
3691
+ if (!this.isConnected || this.isClosed) {
3692
+ this.log("debug", "Connection not available, dropping one-way message", {
3693
+ action
3694
+ });
3695
+ return false;
3696
+ }
3697
+ try {
3698
+ this.rws.send(this.pack({ action, data }));
3699
+ this.connectionStats.totalMessages++;
3700
+ this.log("debug", "One-way message sent", { action, data });
3701
+ return true;
3702
+ } catch (error) {
3703
+ this.connectionStats.totalErrors++;
3704
+ this.log("error", "Failed to send one-way message", { action, error });
3705
+ return false;
3706
+ }
3707
+ }
3664
3708
  pack(data) {
3665
3709
  return new Blob([encode(data)]);
3666
3710
  }
@@ -3764,7 +3808,6 @@ var Transport = class {
3764
3808
  if (queuedCount > 0) {
3765
3809
  this.log("debug", `Rejected ${queuedCount} queued messages due to connection close`);
3766
3810
  }
3767
- this.rateLimiter.requests = [];
3768
3811
  this.disposables.dispose();
3769
3812
  try {
3770
3813
  this.rws.close(code, reason);
@@ -3891,18 +3934,6 @@ var Transport = class {
3891
3934
  this.log("debug", `Cleared ${originalLength - this.messageQueue.length} expired messages`);
3892
3935
  }
3893
3936
  }
3894
- /**
3895
- * Rate limiting check
3896
- */
3897
- isRateLimited() {
3898
- const now = Date.now();
3899
- this.rateLimiter.requests = this.rateLimiter.requests.filter((timestamp) => now - timestamp < this.rateLimiter.windowMs);
3900
- if (this.rateLimiter.requests.length >= this.rateLimiter.maxRequests) {
3901
- return true;
3902
- }
3903
- this.rateLimiter.requests.push(now);
3904
- return false;
3905
- }
3906
3937
  /**
3907
3938
  * Calculate exponential backoff delay
3908
3939
  */
@@ -3937,12 +3968,6 @@ var Transport = class {
3937
3968
  maxSize: this.MAX_QUEUE_SIZE,
3938
3969
  oldestMessageAge: this.messageQueue.length > 0 ? now - Math.min(...this.messageQueue.map((m) => m.timestamp)) : 0
3939
3970
  },
3940
- rateLimiter: {
3941
- currentRequests: this.rateLimiter.requests.length,
3942
- maxRequests: this.rateLimiter.maxRequests,
3943
- windowMs: this.rateLimiter.windowMs,
3944
- isLimited: this.isRateLimited()
3945
- },
3946
3971
  config: {
3947
3972
  pingInterval: this.PING_INTERVAL,
3948
3973
  queueTimeout: this.QUEUE_TIMEOUT,
@@ -4008,10 +4033,6 @@ var Transport = class {
4008
4033
  issues.push("High average response time");
4009
4034
  recommendations.push("Check network latency and server performance");
4010
4035
  }
4011
- if (metrics.rateLimiter.isLimited) {
4012
- issues.push("Rate limiting is active");
4013
- recommendations.push("Reduce request frequency or increase rate limit");
4014
- }
4015
4036
  this.log("info", "Connection diagnostics completed", {
4016
4037
  status,
4017
4038
  issueCount: issues.length,
@@ -4032,10 +4053,6 @@ var Transport = class {
4032
4053
  const maintenanceInterval = setInterval(
4033
4054
  () => {
4034
4055
  this.clearOldQueuedMessages();
4035
- const now = Date.now();
4036
- this.rateLimiter.requests = this.rateLimiter.requests.filter(
4037
- (timestamp) => now - timestamp < this.rateLimiter.windowMs
4038
- );
4039
4056
  if (this.options.debug) {
4040
4057
  const health = this.getHealthStatus();
4041
4058
  const metrics = this.getConnectionMetrics();
@@ -5000,6 +5017,7 @@ var NotebookApi = class {
5000
5017
  this.client = client;
5001
5018
  this.secrets = new NotebookSecretApi(client);
5002
5019
  this.previewAuth = new NotebookPreviewAuthApi(client);
5020
+ this.preview = this.previewAuth;
5003
5021
  this.mail = new NotebookMailApi(client);
5004
5022
  }
5005
5023
  async create(template, input = {}, init = true) {
@@ -5107,20 +5125,36 @@ var NotebookSecretApi = class {
5107
5125
  await this.client.delete(`/notebook/${id}/secrets/${encodeURIComponent(name)}`);
5108
5126
  }
5109
5127
  };
5110
- var NotebookPreviewAuthApi = class {
5128
+ var NotebookPreviewApi = class {
5111
5129
  constructor(client) {
5112
5130
  this.client = client;
5113
5131
  }
5114
5132
  async get(id) {
5115
- const response = await this.client.get(`/notebook/${id}/preview-auth`);
5133
+ const response = await this.client.get(`/notebook/${id}/preview`);
5116
5134
  return response.data;
5117
5135
  }
5118
- async set(id, input) {
5119
- const response = await this.client.put(`/notebook/${id}/preview-auth`, input);
5136
+ async setPassword(id, input) {
5137
+ const response = await this.client.put(`/notebook/${id}/preview`, input);
5120
5138
  return response.data;
5121
5139
  }
5122
- async delete(id) {
5123
- await this.client.delete(`/notebook/${id}/preview-auth`);
5140
+ async disable(id) {
5141
+ await this.client.delete(`/notebook/${id}/preview`);
5142
+ }
5143
+ async createSession(id) {
5144
+ const response = await this.client.post(`/notebook/${id}/preview/session`);
5145
+ return response.data;
5146
+ }
5147
+ async createHandoff(id, input) {
5148
+ const response = await this.client.post(`/notebook/${id}/preview/handoff`, input);
5149
+ return response.data;
5150
+ }
5151
+ };
5152
+ var NotebookPreviewAuthApi = class extends NotebookPreviewApi {
5153
+ set(id, input) {
5154
+ return this.setPassword(id, input);
5155
+ }
5156
+ delete(id) {
5157
+ return this.disable(id);
5124
5158
  }
5125
5159
  };
5126
5160
  var NotebookMailApi = class {
@@ -5183,6 +5217,7 @@ var NotebookInstance = class {
5183
5217
  this.services = new Services(this);
5184
5218
  this.secrets = new NotebookSecrets(client, this.data.id);
5185
5219
  this.previewAuth = new NotebookPreviewAuth(client, this.data.id);
5220
+ this.preview = this.previewAuth;
5186
5221
  this.mail = new NotebookMail(client, this.data.id);
5187
5222
  }
5188
5223
  async ready() {
@@ -5215,6 +5250,9 @@ var NotebookInstance = class {
5215
5250
  invoke(action, data = {}, options = {}) {
5216
5251
  return this.socket.invoke(action, data || {}, options);
5217
5252
  }
5253
+ send(action, data = {}) {
5254
+ return this.socket.send(action, data || {});
5255
+ }
5218
5256
  ping() {
5219
5257
  return this.invoke("ping");
5220
5258
  }
@@ -5357,19 +5395,30 @@ var NotebookSecrets = class {
5357
5395
  return this.client.notebook.secrets.delete(this.notebookId, name);
5358
5396
  }
5359
5397
  };
5360
- var NotebookPreviewAuth = class {
5398
+ var NotebookPreview = class {
5361
5399
  constructor(client, notebookId) {
5362
5400
  this.client = client;
5363
5401
  this.notebookId = notebookId;
5364
5402
  }
5365
5403
  get() {
5366
- return this.client.notebook.previewAuth.get(this.notebookId);
5404
+ return this.client.notebook.preview.get(this.notebookId);
5367
5405
  }
5368
- set(input) {
5369
- return this.client.notebook.previewAuth.set(this.notebookId, input);
5406
+ setPassword(input) {
5407
+ return this.client.notebook.preview.setPassword(this.notebookId, input);
5370
5408
  }
5371
5409
  disable() {
5372
- return this.client.notebook.previewAuth.delete(this.notebookId);
5410
+ return this.client.notebook.preview.disable(this.notebookId);
5411
+ }
5412
+ createSession() {
5413
+ return this.client.notebook.preview.createSession(this.notebookId);
5414
+ }
5415
+ createHandoff(input) {
5416
+ return this.client.notebook.preview.createHandoff(this.notebookId, input);
5417
+ }
5418
+ };
5419
+ var NotebookPreviewAuth = class extends NotebookPreview {
5420
+ set(input) {
5421
+ return this.setPassword(input);
5373
5422
  }
5374
5423
  };
5375
5424
  var NotebookMail = class {
@@ -5427,6 +5476,8 @@ export {
5427
5476
  NotebookInstance,
5428
5477
  NotebookMail,
5429
5478
  NotebookMailApi,
5479
+ NotebookPreview,
5480
+ NotebookPreviewApi,
5430
5481
  NotebookPreviewAuth,
5431
5482
  NotebookPreviewAuthApi,
5432
5483
  NotebookSecretApi,