@phpsandbox/sdk 0.0.27 → 0.0.28

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.
@@ -910,6 +910,14 @@ var Repl = class {
910
910
  };
911
911
 
912
912
  // src/shell.ts
913
+ function resolveExecInput(command, argsOrOpts = [], opts) {
914
+ const args = Array.isArray(argsOrOpts) ? argsOrOpts : [];
915
+ const resolvedOpts = Array.isArray(argsOrOpts) ? opts : argsOrOpts;
916
+ return {
917
+ command: Array.isArray(command) ? command : args.length > 0 ? [command, ...args] : command,
918
+ opts: resolvedOpts
919
+ };
920
+ }
913
921
  var CommandError = class extends Error {
914
922
  constructor(output, exitCode) {
915
923
  super(output);
@@ -933,10 +941,83 @@ var Shell = class {
933
941
  constructor(okra) {
934
942
  this.okra = okra;
935
943
  }
936
- async exec(command) {
937
- const result = await this.okra.invoke("shell.exec", { command });
944
+ onOutput(id, handler) {
945
+ this.okra.listen(`shell.output.${id}`, handler);
946
+ }
947
+ listen(event, handler) {
948
+ return this.okra.listen(event, handler);
949
+ }
950
+ async exec(command, argsOrOpts = [], opts) {
951
+ const input = resolveExecInput(command, argsOrOpts, opts);
952
+ const { abortSignal, ...payloadOpts } = input.opts ?? {};
953
+ const result = await this.okra.invoke(
954
+ "shell.exec",
955
+ {
956
+ command: input.command,
957
+ opts: Object.keys(payloadOpts).length > 0 ? payloadOpts : void 0
958
+ },
959
+ { abortSignal }
960
+ );
938
961
  return new Result(result.output, result.exitCode);
939
962
  }
963
+ execStream(command, argsOrOpts = [], opts) {
964
+ const input = resolveExecInput(command, argsOrOpts, opts);
965
+ const id = input.opts?.id || nanoid();
966
+ const disposables = /* @__PURE__ */ new Set();
967
+ let controller = null;
968
+ let closed = false;
969
+ const dispose = () => {
970
+ for (const disposable of disposables) {
971
+ disposable.dispose();
972
+ }
973
+ disposables.clear();
974
+ };
975
+ const close = () => {
976
+ if (closed) {
977
+ return;
978
+ }
979
+ closed = true;
980
+ dispose();
981
+ if (controller) {
982
+ try {
983
+ controller.close();
984
+ } catch {
985
+ }
986
+ }
987
+ };
988
+ const fail = (error) => {
989
+ if (closed) {
990
+ return;
991
+ }
992
+ closed = true;
993
+ dispose();
994
+ if (controller) {
995
+ controller.error(error);
996
+ }
997
+ };
998
+ const output = new ReadableStream({
999
+ start: (_controller) => {
1000
+ controller = _controller;
1001
+ disposables.add(
1002
+ this.listen(`shell.output.${id}`, (data) => {
1003
+ controller?.enqueue(data.output);
1004
+ })
1005
+ );
1006
+ },
1007
+ cancel: () => {
1008
+ closed = true;
1009
+ dispose();
1010
+ }
1011
+ });
1012
+ const result = this.exec(input.command, { ...input.opts, id }).then((response) => {
1013
+ close();
1014
+ return response;
1015
+ }).catch((error) => {
1016
+ fail(error);
1017
+ throw error;
1018
+ });
1019
+ return { output, result };
1020
+ }
940
1021
  };
941
1022
 
942
1023
  // node_modules/@msgpack/msgpack/dist.esm/utils/utf8.mjs