modal 0.3.7 → 0.3.8
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 +1 -1
- package/dist/index.cjs +39574 -0
- package/dist/index.d.cts +380 -0
- package/dist/index.js +180 -118
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -37797,13 +37797,13 @@ import {
|
|
|
37797
37797
|
} from "nice-grpc";
|
|
37798
37798
|
|
|
37799
37799
|
// src/config.ts
|
|
37800
|
-
import {
|
|
37801
|
-
import path from "node:path";
|
|
37800
|
+
import { readFileSync } from "node:fs";
|
|
37802
37801
|
import { homedir } from "node:os";
|
|
37802
|
+
import path from "node:path";
|
|
37803
37803
|
import { parse as parseToml } from "smol-toml";
|
|
37804
|
-
|
|
37804
|
+
function readConfigFile() {
|
|
37805
37805
|
try {
|
|
37806
|
-
const configContent =
|
|
37806
|
+
const configContent = readFileSync(path.join(homedir(), ".modal.toml"), {
|
|
37807
37807
|
encoding: "utf-8"
|
|
37808
37808
|
});
|
|
37809
37809
|
return parseToml(configContent);
|
|
@@ -37814,7 +37814,7 @@ async function readConfigFile() {
|
|
|
37814
37814
|
throw new Error(`Failed to read or parse .modal.toml: ${err.message}`);
|
|
37815
37815
|
}
|
|
37816
37816
|
}
|
|
37817
|
-
var config =
|
|
37817
|
+
var config = readConfigFile();
|
|
37818
37818
|
function getProfile(profileName) {
|
|
37819
37819
|
profileName = profileName || process.env["MODAL_PROFILE"] || void 0;
|
|
37820
37820
|
if (!profileName) {
|
|
@@ -38505,31 +38505,6 @@ import { ClientError as ClientError5, Status as Status5 } from "nice-grpc";
|
|
|
38505
38505
|
// src/function.ts
|
|
38506
38506
|
import { createHash } from "node:crypto";
|
|
38507
38507
|
|
|
38508
|
-
// src/function_call.ts
|
|
38509
|
-
var FunctionCall = class _FunctionCall {
|
|
38510
|
-
functionCallId;
|
|
38511
|
-
/** @ignore */
|
|
38512
|
-
constructor(functionCallId) {
|
|
38513
|
-
this.functionCallId = functionCallId;
|
|
38514
|
-
}
|
|
38515
|
-
/** Create a new function call from ID. */
|
|
38516
|
-
fromId(functionCallId) {
|
|
38517
|
-
return new _FunctionCall(functionCallId);
|
|
38518
|
-
}
|
|
38519
|
-
/** Get the result of a function call, optionally waiting with a timeout. */
|
|
38520
|
-
async get(options = {}) {
|
|
38521
|
-
const timeout = options.timeout;
|
|
38522
|
-
return await pollFunctionOutput(this.functionCallId, timeout);
|
|
38523
|
-
}
|
|
38524
|
-
/** Cancel a running function call. */
|
|
38525
|
-
async cancel(options = {}) {
|
|
38526
|
-
await client.functionCallCancel({
|
|
38527
|
-
functionCallId: this.functionCallId,
|
|
38528
|
-
terminateContainers: options.terminateContainers
|
|
38529
|
-
});
|
|
38530
|
-
}
|
|
38531
|
-
};
|
|
38532
|
-
|
|
38533
38508
|
// src/pickle.ts
|
|
38534
38509
|
var PickleError = class extends Error {
|
|
38535
38510
|
constructor(message) {
|
|
@@ -38877,79 +38852,62 @@ function loads(buf) {
|
|
|
38877
38852
|
throw new PickleError("pickle stream ended without STOP");
|
|
38878
38853
|
}
|
|
38879
38854
|
|
|
38880
|
-
// src/
|
|
38881
|
-
import { ClientError as ClientError4, Status as Status4 } from "nice-grpc";
|
|
38882
|
-
var maxObjectSizeBytes = 2 * 1024 * 1024;
|
|
38855
|
+
// src/invocation.ts
|
|
38883
38856
|
var outputsTimeout = 55 * 1e3;
|
|
38884
|
-
|
|
38885
|
-
|
|
38886
|
-
|
|
38887
|
-
|
|
38888
|
-
|
|
38889
|
-
|
|
38890
|
-
|
|
38891
|
-
|
|
38892
|
-
this.
|
|
38893
|
-
this.
|
|
38894
|
-
}
|
|
38895
|
-
static async lookup(appName, name, options = {}) {
|
|
38896
|
-
try {
|
|
38897
|
-
const resp = await client.functionGet({
|
|
38898
|
-
appName,
|
|
38899
|
-
objectTag: name,
|
|
38900
|
-
namespace: 1 /* DEPLOYMENT_NAMESPACE_WORKSPACE */,
|
|
38901
|
-
environmentName: environmentName(options.environment)
|
|
38902
|
-
});
|
|
38903
|
-
return new _Function_(resp.functionId);
|
|
38904
|
-
} catch (err) {
|
|
38905
|
-
if (err instanceof ClientError4 && err.code === Status4.NOT_FOUND)
|
|
38906
|
-
throw new NotFoundError(`Function '${appName}/${name}' not found`);
|
|
38907
|
-
throw err;
|
|
38908
|
-
}
|
|
38857
|
+
var ControlPlaneInvocation = class _ControlPlaneInvocation {
|
|
38858
|
+
functionCallId;
|
|
38859
|
+
input;
|
|
38860
|
+
functionCallJwt;
|
|
38861
|
+
inputJwt;
|
|
38862
|
+
constructor(functionCallId, input, functionCallJwt, inputJwt) {
|
|
38863
|
+
this.functionCallId = functionCallId;
|
|
38864
|
+
this.input = input;
|
|
38865
|
+
this.functionCallJwt = functionCallJwt;
|
|
38866
|
+
this.inputJwt = inputJwt;
|
|
38909
38867
|
}
|
|
38910
|
-
|
|
38911
|
-
|
|
38912
|
-
|
|
38913
|
-
|
|
38914
|
-
|
|
38915
|
-
|
|
38868
|
+
static async create(functionId, input, invocationType) {
|
|
38869
|
+
const functionPutInputsItem = {
|
|
38870
|
+
idx: 0,
|
|
38871
|
+
input
|
|
38872
|
+
};
|
|
38873
|
+
const functionMapResponse = await client.functionMap({
|
|
38874
|
+
functionId,
|
|
38875
|
+
functionCallType: 1 /* FUNCTION_CALL_TYPE_UNARY */,
|
|
38876
|
+
functionCallInvocationType: invocationType,
|
|
38877
|
+
pipelinedInputs: [functionPutInputsItem]
|
|
38878
|
+
});
|
|
38879
|
+
return new _ControlPlaneInvocation(
|
|
38880
|
+
functionMapResponse.functionCallId,
|
|
38881
|
+
input,
|
|
38882
|
+
functionMapResponse.functionCallJwt,
|
|
38883
|
+
functionMapResponse.pipelinedInputs[0].inputJwt
|
|
38916
38884
|
);
|
|
38917
|
-
return await pollFunctionOutput(functionCallId);
|
|
38918
38885
|
}
|
|
38919
|
-
|
|
38920
|
-
|
|
38921
|
-
const functionCallId = await this.#execFunctionCall(
|
|
38922
|
-
args,
|
|
38923
|
-
kwargs,
|
|
38924
|
-
4 /* FUNCTION_CALL_INVOCATION_TYPE_SYNC */
|
|
38925
|
-
);
|
|
38926
|
-
return new FunctionCall(functionCallId);
|
|
38886
|
+
static fromFunctionCallId(functionCallId) {
|
|
38887
|
+
return new _ControlPlaneInvocation(functionCallId);
|
|
38927
38888
|
}
|
|
38928
|
-
async
|
|
38929
|
-
|
|
38930
|
-
|
|
38931
|
-
|
|
38932
|
-
|
|
38889
|
+
async awaitOutput(timeout) {
|
|
38890
|
+
return await pollFunctionOutput(this.functionCallId, timeout);
|
|
38891
|
+
}
|
|
38892
|
+
async retry(retryCount) {
|
|
38893
|
+
if (!this.input) {
|
|
38894
|
+
throw new Error("Cannot retry function invocation - input missing");
|
|
38933
38895
|
}
|
|
38934
|
-
const
|
|
38935
|
-
|
|
38936
|
-
|
|
38937
|
-
|
|
38938
|
-
|
|
38939
|
-
|
|
38940
|
-
|
|
38941
|
-
|
|
38942
|
-
args: argsBlobId ? void 0 : payload,
|
|
38943
|
-
argsBlobId,
|
|
38944
|
-
dataFormat: 1 /* DATA_FORMAT_PICKLE */,
|
|
38945
|
-
methodName: this.methodName
|
|
38946
|
-
}
|
|
38947
|
-
}
|
|
38948
|
-
]
|
|
38896
|
+
const retryItem = {
|
|
38897
|
+
inputJwt: this.inputJwt,
|
|
38898
|
+
input: this.input,
|
|
38899
|
+
retryCount
|
|
38900
|
+
};
|
|
38901
|
+
const functionRetryResponse = await client.functionRetryInputs({
|
|
38902
|
+
functionCallJwt: this.functionCallJwt,
|
|
38903
|
+
inputs: [retryItem]
|
|
38949
38904
|
});
|
|
38950
|
-
|
|
38905
|
+
this.inputJwt = functionRetryResponse.inputJwts[0];
|
|
38951
38906
|
}
|
|
38952
38907
|
};
|
|
38908
|
+
function timeNowSeconds() {
|
|
38909
|
+
return Date.now() / 1e3;
|
|
38910
|
+
}
|
|
38953
38911
|
async function pollFunctionOutput(functionCallId, timeout) {
|
|
38954
38912
|
const startTime = Date.now();
|
|
38955
38913
|
let pollTimeout = outputsTimeout;
|
|
@@ -39007,6 +38965,134 @@ async function processResult(result, dataFormat) {
|
|
|
39007
38965
|
}
|
|
39008
38966
|
return deserializeDataFormat(data, dataFormat);
|
|
39009
38967
|
}
|
|
38968
|
+
async function blobDownload(blobId) {
|
|
38969
|
+
const resp = await client.blobGet({ blobId });
|
|
38970
|
+
const s3resp = await fetch(resp.downloadUrl);
|
|
38971
|
+
if (!s3resp.ok) {
|
|
38972
|
+
throw new Error(`Failed to download blob: ${s3resp.statusText}`);
|
|
38973
|
+
}
|
|
38974
|
+
const buf = await s3resp.arrayBuffer();
|
|
38975
|
+
return new Uint8Array(buf);
|
|
38976
|
+
}
|
|
38977
|
+
function deserializeDataFormat(data, dataFormat) {
|
|
38978
|
+
if (!data) {
|
|
38979
|
+
return null;
|
|
38980
|
+
}
|
|
38981
|
+
switch (dataFormat) {
|
|
38982
|
+
case 1 /* DATA_FORMAT_PICKLE */:
|
|
38983
|
+
return loads(data);
|
|
38984
|
+
case 2 /* DATA_FORMAT_ASGI */:
|
|
38985
|
+
throw new Error("ASGI data format is not supported in Go");
|
|
38986
|
+
case 3 /* DATA_FORMAT_GENERATOR_DONE */:
|
|
38987
|
+
return GeneratorDone.decode(data);
|
|
38988
|
+
default:
|
|
38989
|
+
throw new Error(`Unsupported data format: ${dataFormat}`);
|
|
38990
|
+
}
|
|
38991
|
+
}
|
|
38992
|
+
|
|
38993
|
+
// src/function_call.ts
|
|
38994
|
+
var FunctionCall = class _FunctionCall {
|
|
38995
|
+
functionCallId;
|
|
38996
|
+
/** @ignore */
|
|
38997
|
+
constructor(functionCallId) {
|
|
38998
|
+
this.functionCallId = functionCallId;
|
|
38999
|
+
}
|
|
39000
|
+
/** Create a new function call from ID. */
|
|
39001
|
+
fromId(functionCallId) {
|
|
39002
|
+
return new _FunctionCall(functionCallId);
|
|
39003
|
+
}
|
|
39004
|
+
/** Get the result of a function call, optionally waiting with a timeout. */
|
|
39005
|
+
async get(options = {}) {
|
|
39006
|
+
const timeout = options.timeout;
|
|
39007
|
+
const invocation = ControlPlaneInvocation.fromFunctionCallId(
|
|
39008
|
+
this.functionCallId
|
|
39009
|
+
);
|
|
39010
|
+
return invocation.awaitOutput(timeout);
|
|
39011
|
+
}
|
|
39012
|
+
/** Cancel a running function call. */
|
|
39013
|
+
async cancel(options = {}) {
|
|
39014
|
+
await client.functionCallCancel({
|
|
39015
|
+
functionCallId: this.functionCallId,
|
|
39016
|
+
terminateContainers: options.terminateContainers
|
|
39017
|
+
});
|
|
39018
|
+
}
|
|
39019
|
+
};
|
|
39020
|
+
|
|
39021
|
+
// src/function.ts
|
|
39022
|
+
import { ClientError as ClientError4, Status as Status4 } from "nice-grpc";
|
|
39023
|
+
var maxObjectSizeBytes = 2 * 1024 * 1024;
|
|
39024
|
+
var maxSystemRetries = 8;
|
|
39025
|
+
var Function_ = class _Function_ {
|
|
39026
|
+
functionId;
|
|
39027
|
+
methodName;
|
|
39028
|
+
/** @ignore */
|
|
39029
|
+
constructor(functionId, methodName) {
|
|
39030
|
+
this.functionId = functionId;
|
|
39031
|
+
this.methodName = methodName;
|
|
39032
|
+
}
|
|
39033
|
+
static async lookup(appName, name, options = {}) {
|
|
39034
|
+
try {
|
|
39035
|
+
const resp = await client.functionGet({
|
|
39036
|
+
appName,
|
|
39037
|
+
objectTag: name,
|
|
39038
|
+
namespace: 1 /* DEPLOYMENT_NAMESPACE_WORKSPACE */,
|
|
39039
|
+
environmentName: environmentName(options.environment)
|
|
39040
|
+
});
|
|
39041
|
+
return new _Function_(resp.functionId);
|
|
39042
|
+
} catch (err) {
|
|
39043
|
+
if (err instanceof ClientError4 && err.code === Status4.NOT_FOUND)
|
|
39044
|
+
throw new NotFoundError(`Function '${appName}/${name}' not found`);
|
|
39045
|
+
throw err;
|
|
39046
|
+
}
|
|
39047
|
+
}
|
|
39048
|
+
// Execute a single input into a remote Function.
|
|
39049
|
+
async remote(args = [], kwargs = {}) {
|
|
39050
|
+
const input = await this.#createInput(args, kwargs);
|
|
39051
|
+
const invocation = await ControlPlaneInvocation.create(
|
|
39052
|
+
this.functionId,
|
|
39053
|
+
input,
|
|
39054
|
+
4 /* FUNCTION_CALL_INVOCATION_TYPE_SYNC */
|
|
39055
|
+
);
|
|
39056
|
+
let retryCount = 0;
|
|
39057
|
+
while (true) {
|
|
39058
|
+
try {
|
|
39059
|
+
return await invocation.awaitOutput();
|
|
39060
|
+
} catch (err) {
|
|
39061
|
+
if (err instanceof InternalFailure && retryCount <= maxSystemRetries) {
|
|
39062
|
+
await invocation.retry(retryCount);
|
|
39063
|
+
retryCount++;
|
|
39064
|
+
} else {
|
|
39065
|
+
throw err;
|
|
39066
|
+
}
|
|
39067
|
+
}
|
|
39068
|
+
}
|
|
39069
|
+
}
|
|
39070
|
+
// Spawn a single input into a remote function.
|
|
39071
|
+
async spawn(args = [], kwargs = {}) {
|
|
39072
|
+
const input = await this.#createInput(args, kwargs);
|
|
39073
|
+
const invocation = await ControlPlaneInvocation.create(
|
|
39074
|
+
this.functionId,
|
|
39075
|
+
input,
|
|
39076
|
+
3 /* FUNCTION_CALL_INVOCATION_TYPE_ASYNC */
|
|
39077
|
+
);
|
|
39078
|
+
return new FunctionCall(invocation.functionCallId);
|
|
39079
|
+
}
|
|
39080
|
+
async #createInput(args = [], kwargs = {}) {
|
|
39081
|
+
const payload = dumps([args, kwargs]);
|
|
39082
|
+
let argsBlobId = void 0;
|
|
39083
|
+
if (payload.length > maxObjectSizeBytes) {
|
|
39084
|
+
argsBlobId = await blobUpload(payload);
|
|
39085
|
+
}
|
|
39086
|
+
return {
|
|
39087
|
+
args: argsBlobId ? void 0 : payload,
|
|
39088
|
+
argsBlobId,
|
|
39089
|
+
dataFormat: 1 /* DATA_FORMAT_PICKLE */,
|
|
39090
|
+
methodName: this.methodName,
|
|
39091
|
+
finalInput: false
|
|
39092
|
+
// This field isn't specified in the Python client, so it defaults to false.
|
|
39093
|
+
};
|
|
39094
|
+
}
|
|
39095
|
+
};
|
|
39010
39096
|
async function blobUpload(data) {
|
|
39011
39097
|
const contentMd5 = createHash("md5").update(data).digest("base64");
|
|
39012
39098
|
const contentSha256 = createHash("sha256").update(data).digest("base64");
|
|
@@ -39036,30 +39122,6 @@ async function blobUpload(data) {
|
|
|
39036
39122
|
throw new Error("Missing upload URL in BlobCreate response");
|
|
39037
39123
|
}
|
|
39038
39124
|
}
|
|
39039
|
-
async function blobDownload(blobId) {
|
|
39040
|
-
const resp = await client.blobGet({ blobId });
|
|
39041
|
-
const s3resp = await fetch(resp.downloadUrl);
|
|
39042
|
-
if (!s3resp.ok) {
|
|
39043
|
-
throw new Error(`Failed to download blob: ${s3resp.statusText}`);
|
|
39044
|
-
}
|
|
39045
|
-
const buf = await s3resp.arrayBuffer();
|
|
39046
|
-
return new Uint8Array(buf);
|
|
39047
|
-
}
|
|
39048
|
-
function deserializeDataFormat(data, dataFormat) {
|
|
39049
|
-
if (!data) {
|
|
39050
|
-
return null;
|
|
39051
|
-
}
|
|
39052
|
-
switch (dataFormat) {
|
|
39053
|
-
case 1 /* DATA_FORMAT_PICKLE */:
|
|
39054
|
-
return loads(data);
|
|
39055
|
-
case 2 /* DATA_FORMAT_ASGI */:
|
|
39056
|
-
throw new Error("ASGI data format is not supported in Go");
|
|
39057
|
-
case 3 /* DATA_FORMAT_GENERATOR_DONE */:
|
|
39058
|
-
return GeneratorDone.decode(data);
|
|
39059
|
-
default:
|
|
39060
|
-
throw new Error(`Unsupported data format: ${dataFormat}`);
|
|
39061
|
-
}
|
|
39062
|
-
}
|
|
39063
39125
|
|
|
39064
39126
|
// src/cls.ts
|
|
39065
39127
|
var Cls = class _Cls {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modal",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Modal client library for JavaScript",
|
|
5
|
-
"license": "
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://modal.com/docs",
|
|
7
7
|
"repository": "github:modal-labs/libmodal",
|
|
8
8
|
"bugs": "https://github.com/modal-labs/libmodal/issues",
|