modal 0.5.5 → 0.5.6

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.
package/README.md CHANGED
@@ -45,6 +45,7 @@ We also provide a number of examples:
45
45
  - [Check the status and exit code of a Sandbox](https://github.com/modal-labs/libmodal/blob/main/modal-js/examples/sandbox-poll.ts)
46
46
  - [Access Sandbox filesystem](https://github.com/modal-labs/libmodal/blob/main/modal-js/examples/sandbox-filesystem.ts)
47
47
  - [Expose ports on a Sandbox using Tunnels](https://github.com/modal-labs/libmodal/blob/main/modal-js/examples/sandbox-tunnels.ts)
48
+ - [Create connect tokens for a Sandbox](https://github.com/modal-labs/libmodal/blob/main/modal-js/examples/sandbox-connect-token.ts)
48
49
  - [Include Secrets in Sandbox](https://github.com/modal-labs/libmodal/blob/main/modal-js/examples/sandbox-secrets.ts)
49
50
  - [Mount a Volume to a Sandbox](https://github.com/modal-labs/libmodal/blob/main/modal-js/examples/sandbox-volume.ts), and same but [with an ephemeral Volume](https://github.com/modal-labs/libmodal/blob/main/modal-js/examples/sandbox-volume-ephemeral.ts)
50
51
  - [Mount a cloud bucket to a Sandbox](https://github.com/modal-labs/libmodal/blob/main/modal-js/examples/sandbox-cloud-bucket.ts)
package/dist/index.cjs CHANGED
@@ -46227,6 +46227,16 @@ var Sandbox2 = class _Sandbox {
46227
46227
  }
46228
46228
  return this.#taskId;
46229
46229
  }
46230
+ /**
46231
+ * Create a token for making HTTP connections to the Sandbox.
46232
+ */
46233
+ async createConnectToken(params) {
46234
+ const resp = await this.#client.cpClient.sandboxCreateConnectToken({
46235
+ sandboxId: this.sandboxId,
46236
+ userMetadata: params?.userMetadata
46237
+ });
46238
+ return { url: resp.url, token: resp.token };
46239
+ }
46230
46240
  async terminate() {
46231
46241
  await this.#client.cpClient.sandboxTerminate({ sandboxId: this.sandboxId });
46232
46242
  this.#taskId = void 0;
@@ -46672,24 +46682,27 @@ var AuthTokenManager = class {
46672
46682
  logger;
46673
46683
  currentToken = "";
46674
46684
  tokenExpiry = 0;
46675
- stopped = false;
46676
46685
  timeoutId = null;
46677
- initialTokenPromise = null;
46686
+ running = false;
46687
+ fetchPromise = null;
46678
46688
  constructor(client2, logger) {
46679
46689
  this.client = client2;
46680
46690
  this.logger = logger;
46681
46691
  }
46682
46692
  /**
46683
- * Returns the current cached token.
46684
- * If the initial token fetch is still in progress, waits for it to complete.
46693
+ * Returns a valid auth token.
46694
+ * If the current token is expired and the manager is running, triggers an on-demand refresh.
46685
46695
  */
46686
46696
  async getToken() {
46687
- if (this.initialTokenPromise) {
46688
- await this.initialTokenPromise;
46689
- }
46690
46697
  if (this.currentToken && !this.isExpired()) {
46691
46698
  return this.currentToken;
46692
46699
  }
46700
+ if (this.running) {
46701
+ await this.runFetch();
46702
+ if (this.currentToken && !this.isExpired()) {
46703
+ return this.currentToken;
46704
+ }
46705
+ }
46693
46706
  throw new Error("No valid auth token available");
46694
46707
  }
46695
46708
  /**
@@ -46726,7 +46739,7 @@ var AuthTokenManager = class {
46726
46739
  * Background loop that refreshes tokens REFRESH_WINDOW seconds before they expire.
46727
46740
  */
46728
46741
  async backgroundRefresh() {
46729
- while (!this.stopped) {
46742
+ while (this.running) {
46730
46743
  const now = Math.floor(Date.now() / 1e3);
46731
46744
  const refreshTime = this.tokenExpiry - REFRESH_WINDOW;
46732
46745
  const delay = Math.max(0, refreshTime - now) * 1e3;
@@ -46734,11 +46747,11 @@ var AuthTokenManager = class {
46734
46747
  this.timeoutId = setTimeout(resolve, delay);
46735
46748
  this.timeoutId.unref();
46736
46749
  });
46737
- if (this.stopped) {
46750
+ if (!this.running) {
46738
46751
  return;
46739
46752
  }
46740
46753
  try {
46741
- await this.fetchToken();
46754
+ await this.runFetch();
46742
46755
  } catch (error) {
46743
46756
  this.logger.error("Failed to refresh auth token", "error", error);
46744
46757
  await new Promise((resolve) => setTimeout(resolve, 5e3));
@@ -46750,20 +46763,23 @@ var AuthTokenManager = class {
46750
46763
  * Throws an error if the initial token fetch fails.
46751
46764
  */
46752
46765
  async start() {
46753
- this.initialTokenPromise = this.fetchToken();
46766
+ if (this.running) {
46767
+ return;
46768
+ }
46769
+ this.running = true;
46754
46770
  try {
46755
- await this.initialTokenPromise;
46756
- } finally {
46757
- this.initialTokenPromise = null;
46771
+ await this.runFetch();
46772
+ } catch (error) {
46773
+ this.running = false;
46774
+ throw error;
46758
46775
  }
46759
- this.stopped = false;
46760
46776
  this.backgroundRefresh();
46761
46777
  }
46762
46778
  /**
46763
46779
  * Stops the background refresh.
46764
46780
  */
46765
46781
  stop() {
46766
- this.stopped = true;
46782
+ this.running = false;
46767
46783
  if (this.timeoutId) {
46768
46784
  clearTimeout(this.timeoutId);
46769
46785
  this.timeoutId = null;
@@ -46793,6 +46809,18 @@ var AuthTokenManager = class {
46793
46809
  const now = Math.floor(Date.now() / 1e3);
46794
46810
  return now >= this.tokenExpiry;
46795
46811
  }
46812
+ runFetch() {
46813
+ if (!this.fetchPromise) {
46814
+ this.fetchPromise = (async () => {
46815
+ try {
46816
+ await this.fetchToken();
46817
+ } finally {
46818
+ this.fetchPromise = null;
46819
+ }
46820
+ })();
46821
+ }
46822
+ return this.fetchPromise;
46823
+ }
46796
46824
  getCurrentToken() {
46797
46825
  return this.currentToken;
46798
46826
  }
@@ -46804,7 +46832,7 @@ var AuthTokenManager = class {
46804
46832
 
46805
46833
  // src/version.ts
46806
46834
  function getSDKVersion() {
46807
- return true ? "0.5.5" : "0.0.0";
46835
+ return true ? "0.5.6" : "0.0.0";
46808
46836
  }
46809
46837
 
46810
46838
  // src/logger.ts
package/dist/index.d.cts CHANGED
@@ -5824,6 +5824,16 @@ type SandboxExecParams = {
5824
5824
  /** Enable a PTY for the command. */
5825
5825
  pty?: boolean;
5826
5826
  };
5827
+ /** Optional parameters for {@link Sandbox#createConnectToken Sandbox.createConnectToken()}. */
5828
+ type SandboxCreateConnectTokenParams = {
5829
+ /** Optional user-provided metadata string that will be added to the headers by the proxy when forwarding requests to the Sandbox. */
5830
+ userMetadata?: string;
5831
+ };
5832
+ /** Credentials returned by {@link Sandbox#createConnectToken Sandbox.createConnectToken()}. */
5833
+ type SandboxCreateConnectCredentials = {
5834
+ url: string;
5835
+ token: string;
5836
+ };
5827
5837
  /** A port forwarded from within a running Modal {@link Sandbox}. */
5828
5838
  declare class Tunnel {
5829
5839
  host: string;
@@ -5873,6 +5883,10 @@ declare class Sandbox {
5873
5883
  exec(command: string[], params: SandboxExecParams & {
5874
5884
  mode: "binary";
5875
5885
  }): Promise<ContainerProcess<Uint8Array>>;
5886
+ /**
5887
+ * Create a token for making HTTP connections to the Sandbox.
5888
+ */
5889
+ createConnectToken(params?: SandboxCreateConnectTokenParams): Promise<SandboxCreateConnectCredentials>;
5876
5890
  terminate(): Promise<void>;
5877
5891
  wait(): Promise<number>;
5878
5892
  /** Get {@link Tunnel} metadata for the Sandbox.
@@ -6139,4 +6153,4 @@ declare class SandboxTimeoutError extends Error {
6139
6153
 
6140
6154
  declare function checkForRenamedParams(params: any, renames: Record<string, string>): void;
6141
6155
 
6142
- export { AlreadyExistsError, App, type AppFromNameParams, AppService, type ClientOptions, CloudBucketMount, CloudBucketMountService, Cls, type ClsFromNameParams, ClsInstance, ClsService, type ClsWithBatchingParams, type ClsWithConcurrencyParams, type ClsWithOptionsParams, ContainerProcess, type DeleteOptions, type EphemeralOptions, FunctionCall, type FunctionCallCancelParams, type FunctionCallGetParams, FunctionCallService, type FunctionFromNameParams, FunctionService, type FunctionStats, FunctionTimeoutError, type FunctionUpdateAutoscalerParams, Function_, Image, type ImageDeleteParams, type ImageDockerfileCommandsParams, ImageService, InternalFailure, InvalidError, type LogLevel, type Logger, type LookupOptions, ModalClient, type ModalClientParams, type ModalReadStream, type ModalWriteStream, NotFoundError, type Profile, Proxy, type ProxyFromNameParams, ProxyService, Queue, type QueueClearParams, type QueueDeleteParams, QueueEmptyError, type QueueEphemeralParams, type QueueFromNameParams, QueueFullError, type QueueGetParams, type QueueIterateParams, type QueueLenParams, type QueuePutParams, QueueService, RemoteError, Retries, Sandbox, type SandboxCreateParams, type SandboxExecParams, SandboxFile, type SandboxFileMode, type SandboxFromNameParams, type SandboxListParams, SandboxService, SandboxTimeoutError, Secret, type SecretDeleteParams, type SecretFromNameParams, type SecretFromObjectParams, SecretService, type StdioBehavior, type StreamMode, Tunnel, Volume, type VolumeDeleteParams, type VolumeEphemeralParams, type VolumeFromNameParams, VolumeService, checkForRenamedParams, close, initializeClient };
6156
+ export { AlreadyExistsError, App, type AppFromNameParams, AppService, type ClientOptions, CloudBucketMount, CloudBucketMountService, Cls, type ClsFromNameParams, ClsInstance, ClsService, type ClsWithBatchingParams, type ClsWithConcurrencyParams, type ClsWithOptionsParams, ContainerProcess, type DeleteOptions, type EphemeralOptions, FunctionCall, type FunctionCallCancelParams, type FunctionCallGetParams, FunctionCallService, type FunctionFromNameParams, FunctionService, type FunctionStats, FunctionTimeoutError, type FunctionUpdateAutoscalerParams, Function_, Image, type ImageDeleteParams, type ImageDockerfileCommandsParams, ImageService, InternalFailure, InvalidError, type LogLevel, type Logger, type LookupOptions, ModalClient, type ModalClientParams, type ModalReadStream, type ModalWriteStream, NotFoundError, type Profile, Proxy, type ProxyFromNameParams, ProxyService, Queue, type QueueClearParams, type QueueDeleteParams, QueueEmptyError, type QueueEphemeralParams, type QueueFromNameParams, QueueFullError, type QueueGetParams, type QueueIterateParams, type QueueLenParams, type QueuePutParams, QueueService, RemoteError, Retries, Sandbox, type SandboxCreateConnectCredentials, type SandboxCreateConnectTokenParams, type SandboxCreateParams, type SandboxExecParams, SandboxFile, type SandboxFileMode, type SandboxFromNameParams, type SandboxListParams, SandboxService, SandboxTimeoutError, Secret, type SecretDeleteParams, type SecretFromNameParams, type SecretFromObjectParams, SecretService, type StdioBehavior, type StreamMode, Tunnel, Volume, type VolumeDeleteParams, type VolumeEphemeralParams, type VolumeFromNameParams, VolumeService, checkForRenamedParams, close, initializeClient };
package/dist/index.d.ts CHANGED
@@ -5824,6 +5824,16 @@ type SandboxExecParams = {
5824
5824
  /** Enable a PTY for the command. */
5825
5825
  pty?: boolean;
5826
5826
  };
5827
+ /** Optional parameters for {@link Sandbox#createConnectToken Sandbox.createConnectToken()}. */
5828
+ type SandboxCreateConnectTokenParams = {
5829
+ /** Optional user-provided metadata string that will be added to the headers by the proxy when forwarding requests to the Sandbox. */
5830
+ userMetadata?: string;
5831
+ };
5832
+ /** Credentials returned by {@link Sandbox#createConnectToken Sandbox.createConnectToken()}. */
5833
+ type SandboxCreateConnectCredentials = {
5834
+ url: string;
5835
+ token: string;
5836
+ };
5827
5837
  /** A port forwarded from within a running Modal {@link Sandbox}. */
5828
5838
  declare class Tunnel {
5829
5839
  host: string;
@@ -5873,6 +5883,10 @@ declare class Sandbox {
5873
5883
  exec(command: string[], params: SandboxExecParams & {
5874
5884
  mode: "binary";
5875
5885
  }): Promise<ContainerProcess<Uint8Array>>;
5886
+ /**
5887
+ * Create a token for making HTTP connections to the Sandbox.
5888
+ */
5889
+ createConnectToken(params?: SandboxCreateConnectTokenParams): Promise<SandboxCreateConnectCredentials>;
5876
5890
  terminate(): Promise<void>;
5877
5891
  wait(): Promise<number>;
5878
5892
  /** Get {@link Tunnel} metadata for the Sandbox.
@@ -6139,4 +6153,4 @@ declare class SandboxTimeoutError extends Error {
6139
6153
 
6140
6154
  declare function checkForRenamedParams(params: any, renames: Record<string, string>): void;
6141
6155
 
6142
- export { AlreadyExistsError, App, type AppFromNameParams, AppService, type ClientOptions, CloudBucketMount, CloudBucketMountService, Cls, type ClsFromNameParams, ClsInstance, ClsService, type ClsWithBatchingParams, type ClsWithConcurrencyParams, type ClsWithOptionsParams, ContainerProcess, type DeleteOptions, type EphemeralOptions, FunctionCall, type FunctionCallCancelParams, type FunctionCallGetParams, FunctionCallService, type FunctionFromNameParams, FunctionService, type FunctionStats, FunctionTimeoutError, type FunctionUpdateAutoscalerParams, Function_, Image, type ImageDeleteParams, type ImageDockerfileCommandsParams, ImageService, InternalFailure, InvalidError, type LogLevel, type Logger, type LookupOptions, ModalClient, type ModalClientParams, type ModalReadStream, type ModalWriteStream, NotFoundError, type Profile, Proxy, type ProxyFromNameParams, ProxyService, Queue, type QueueClearParams, type QueueDeleteParams, QueueEmptyError, type QueueEphemeralParams, type QueueFromNameParams, QueueFullError, type QueueGetParams, type QueueIterateParams, type QueueLenParams, type QueuePutParams, QueueService, RemoteError, Retries, Sandbox, type SandboxCreateParams, type SandboxExecParams, SandboxFile, type SandboxFileMode, type SandboxFromNameParams, type SandboxListParams, SandboxService, SandboxTimeoutError, Secret, type SecretDeleteParams, type SecretFromNameParams, type SecretFromObjectParams, SecretService, type StdioBehavior, type StreamMode, Tunnel, Volume, type VolumeDeleteParams, type VolumeEphemeralParams, type VolumeFromNameParams, VolumeService, checkForRenamedParams, close, initializeClient };
6156
+ export { AlreadyExistsError, App, type AppFromNameParams, AppService, type ClientOptions, CloudBucketMount, CloudBucketMountService, Cls, type ClsFromNameParams, ClsInstance, ClsService, type ClsWithBatchingParams, type ClsWithConcurrencyParams, type ClsWithOptionsParams, ContainerProcess, type DeleteOptions, type EphemeralOptions, FunctionCall, type FunctionCallCancelParams, type FunctionCallGetParams, FunctionCallService, type FunctionFromNameParams, FunctionService, type FunctionStats, FunctionTimeoutError, type FunctionUpdateAutoscalerParams, Function_, Image, type ImageDeleteParams, type ImageDockerfileCommandsParams, ImageService, InternalFailure, InvalidError, type LogLevel, type Logger, type LookupOptions, ModalClient, type ModalClientParams, type ModalReadStream, type ModalWriteStream, NotFoundError, type Profile, Proxy, type ProxyFromNameParams, ProxyService, Queue, type QueueClearParams, type QueueDeleteParams, QueueEmptyError, type QueueEphemeralParams, type QueueFromNameParams, QueueFullError, type QueueGetParams, type QueueIterateParams, type QueueLenParams, type QueuePutParams, QueueService, RemoteError, Retries, Sandbox, type SandboxCreateConnectCredentials, type SandboxCreateConnectTokenParams, type SandboxCreateParams, type SandboxExecParams, SandboxFile, type SandboxFileMode, type SandboxFromNameParams, type SandboxListParams, SandboxService, SandboxTimeoutError, Secret, type SecretDeleteParams, type SecretFromNameParams, type SecretFromObjectParams, SecretService, type StdioBehavior, type StreamMode, Tunnel, Volume, type VolumeDeleteParams, type VolumeEphemeralParams, type VolumeFromNameParams, VolumeService, checkForRenamedParams, close, initializeClient };
package/dist/index.js CHANGED
@@ -46159,6 +46159,16 @@ var Sandbox2 = class _Sandbox {
46159
46159
  }
46160
46160
  return this.#taskId;
46161
46161
  }
46162
+ /**
46163
+ * Create a token for making HTTP connections to the Sandbox.
46164
+ */
46165
+ async createConnectToken(params) {
46166
+ const resp = await this.#client.cpClient.sandboxCreateConnectToken({
46167
+ sandboxId: this.sandboxId,
46168
+ userMetadata: params?.userMetadata
46169
+ });
46170
+ return { url: resp.url, token: resp.token };
46171
+ }
46162
46172
  async terminate() {
46163
46173
  await this.#client.cpClient.sandboxTerminate({ sandboxId: this.sandboxId });
46164
46174
  this.#taskId = void 0;
@@ -46604,24 +46614,27 @@ var AuthTokenManager = class {
46604
46614
  logger;
46605
46615
  currentToken = "";
46606
46616
  tokenExpiry = 0;
46607
- stopped = false;
46608
46617
  timeoutId = null;
46609
- initialTokenPromise = null;
46618
+ running = false;
46619
+ fetchPromise = null;
46610
46620
  constructor(client2, logger) {
46611
46621
  this.client = client2;
46612
46622
  this.logger = logger;
46613
46623
  }
46614
46624
  /**
46615
- * Returns the current cached token.
46616
- * If the initial token fetch is still in progress, waits for it to complete.
46625
+ * Returns a valid auth token.
46626
+ * If the current token is expired and the manager is running, triggers an on-demand refresh.
46617
46627
  */
46618
46628
  async getToken() {
46619
- if (this.initialTokenPromise) {
46620
- await this.initialTokenPromise;
46621
- }
46622
46629
  if (this.currentToken && !this.isExpired()) {
46623
46630
  return this.currentToken;
46624
46631
  }
46632
+ if (this.running) {
46633
+ await this.runFetch();
46634
+ if (this.currentToken && !this.isExpired()) {
46635
+ return this.currentToken;
46636
+ }
46637
+ }
46625
46638
  throw new Error("No valid auth token available");
46626
46639
  }
46627
46640
  /**
@@ -46658,7 +46671,7 @@ var AuthTokenManager = class {
46658
46671
  * Background loop that refreshes tokens REFRESH_WINDOW seconds before they expire.
46659
46672
  */
46660
46673
  async backgroundRefresh() {
46661
- while (!this.stopped) {
46674
+ while (this.running) {
46662
46675
  const now = Math.floor(Date.now() / 1e3);
46663
46676
  const refreshTime = this.tokenExpiry - REFRESH_WINDOW;
46664
46677
  const delay = Math.max(0, refreshTime - now) * 1e3;
@@ -46666,11 +46679,11 @@ var AuthTokenManager = class {
46666
46679
  this.timeoutId = setTimeout(resolve, delay);
46667
46680
  this.timeoutId.unref();
46668
46681
  });
46669
- if (this.stopped) {
46682
+ if (!this.running) {
46670
46683
  return;
46671
46684
  }
46672
46685
  try {
46673
- await this.fetchToken();
46686
+ await this.runFetch();
46674
46687
  } catch (error) {
46675
46688
  this.logger.error("Failed to refresh auth token", "error", error);
46676
46689
  await new Promise((resolve) => setTimeout(resolve, 5e3));
@@ -46682,20 +46695,23 @@ var AuthTokenManager = class {
46682
46695
  * Throws an error if the initial token fetch fails.
46683
46696
  */
46684
46697
  async start() {
46685
- this.initialTokenPromise = this.fetchToken();
46698
+ if (this.running) {
46699
+ return;
46700
+ }
46701
+ this.running = true;
46686
46702
  try {
46687
- await this.initialTokenPromise;
46688
- } finally {
46689
- this.initialTokenPromise = null;
46703
+ await this.runFetch();
46704
+ } catch (error) {
46705
+ this.running = false;
46706
+ throw error;
46690
46707
  }
46691
- this.stopped = false;
46692
46708
  this.backgroundRefresh();
46693
46709
  }
46694
46710
  /**
46695
46711
  * Stops the background refresh.
46696
46712
  */
46697
46713
  stop() {
46698
- this.stopped = true;
46714
+ this.running = false;
46699
46715
  if (this.timeoutId) {
46700
46716
  clearTimeout(this.timeoutId);
46701
46717
  this.timeoutId = null;
@@ -46725,6 +46741,18 @@ var AuthTokenManager = class {
46725
46741
  const now = Math.floor(Date.now() / 1e3);
46726
46742
  return now >= this.tokenExpiry;
46727
46743
  }
46744
+ runFetch() {
46745
+ if (!this.fetchPromise) {
46746
+ this.fetchPromise = (async () => {
46747
+ try {
46748
+ await this.fetchToken();
46749
+ } finally {
46750
+ this.fetchPromise = null;
46751
+ }
46752
+ })();
46753
+ }
46754
+ return this.fetchPromise;
46755
+ }
46728
46756
  getCurrentToken() {
46729
46757
  return this.currentToken;
46730
46758
  }
@@ -46736,7 +46764,7 @@ var AuthTokenManager = class {
46736
46764
 
46737
46765
  // src/version.ts
46738
46766
  function getSDKVersion() {
46739
- return true ? "0.5.5" : "0.0.0";
46767
+ return true ? "0.5.6" : "0.0.0";
46740
46768
  }
46741
46769
 
46742
46770
  // src/logger.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modal",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "Modal SDK for JavaScript/TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://modal.com/docs/guide/sdk-javascript-go",