@yolk-sdk/sandbox 0.1.0-canary.18
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/LICENSE +21 -0
- package/README.md +60 -0
- package/dist/agent.d.mts +48 -0
- package/dist/agent.d.mts.map +1 -0
- package/dist/agent.mjs +173 -0
- package/dist/agent.mjs.map +1 -0
- package/dist/errors.d.mts +44 -0
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +40 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +7 -0
- package/dist/lifecycle.d.mts +52 -0
- package/dist/lifecycle.d.mts.map +1 -0
- package/dist/lifecycle.mjs +118 -0
- package/dist/lifecycle.mjs.map +1 -0
- package/dist/model.d.mts +84 -0
- package/dist/model.d.mts.map +1 -0
- package/dist/model.mjs +72 -0
- package/dist/model.mjs.map +1 -0
- package/dist/name.d.mts +5 -0
- package/dist/name.d.mts.map +1 -0
- package/dist/name.mjs +19 -0
- package/dist/name.mjs.map +1 -0
- package/dist/service.d.mts +15 -0
- package/dist/service.d.mts.map +1 -0
- package/dist/service.mjs +7 -0
- package/dist/service.mjs.map +1 -0
- package/dist/state-store.d.mts +18 -0
- package/dist/state-store.d.mts.map +1 -0
- package/dist/state-store.mjs +7 -0
- package/dist/state-store.mjs.map +1 -0
- package/dist/testing/index.d.mts +21 -0
- package/dist/testing/index.d.mts.map +1 -0
- package/dist/testing/index.mjs +25 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/vercel/client.d.mts +70 -0
- package/dist/vercel/client.d.mts.map +1 -0
- package/dist/vercel/client.mjs +113 -0
- package/dist/vercel/client.mjs.map +1 -0
- package/dist/vercel/index.d.mts +3 -0
- package/dist/vercel/index.mjs +3 -0
- package/dist/vercel/layer.d.mts +23 -0
- package/dist/vercel/layer.d.mts.map +1 -0
- package/dist/vercel/layer.mjs +250 -0
- package/dist/vercel/layer.mjs.map +1 -0
- package/package.json +72 -0
- package/src/agent.ts +304 -0
- package/src/errors.ts +71 -0
- package/src/index.ts +52 -0
- package/src/lifecycle.ts +186 -0
- package/src/model.ts +122 -0
- package/src/name.ts +23 -0
- package/src/service.ts +19 -0
- package/src/state-store.ts +17 -0
- package/src/testing/index.ts +63 -0
- package/src/vercel/client.ts +223 -0
- package/src/vercel/index.ts +24 -0
- package/src/vercel/layer.ts +396 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.mjs","names":[],"sources":["../src/lifecycle.ts"],"sourcesContent":["import { Effect, Option } from 'effect'\nimport { SandboxInputError } from './errors.ts'\nimport {\n DisposableSandboxLifecycle,\n EmptySandboxInitialSource,\n type SandboxInitialSource,\n type SandboxLifecycle,\n type SandboxState,\n VercelSandboxState\n} from './model.ts'\n\nexport const defaultSandboxIdleTtlMs = 30 * 60_000\nexport const defaultSandboxMaxLifetimeMs = 45 * 60_000\nexport const defaultSandboxCommandTimeoutMs = 120_000\nexport const maxSandboxCommandTimeoutMs = 600_000\nexport const backgroundSandboxProbeMs = 2_000\nexport const sandboxToolOutputLimit = 50_000\nexport const defaultSandboxPorts: ReadonlyArray<number> = [3000, 5173, 4321, 8000]\nexport const defaultSandboxWorkspaceRoot = '/vercel/sandbox'\n\nexport const defaultSandboxLifecycle = DisposableSandboxLifecycle.make({\n idleTtlMs: defaultSandboxIdleTtlMs,\n maxLifetimeMs: defaultSandboxMaxLifetimeMs\n})\n\nexport const defaultSandboxInitialSource = EmptySandboxInitialSource.make({})\n\nexport type SandboxRecreateReason = 'idle_expired' | 'max_expired' | 'name_mismatch'\n\nexport type SandboxStateDecision =\n | {\n readonly _tag: 'UseExisting'\n readonly state: SandboxState\n }\n | {\n readonly _tag: 'Create'\n readonly workspaceReset: boolean\n readonly reason?: SandboxRecreateReason\n }\n\nconst positiveOr = (value: number | undefined, fallback: number) =>\n value === undefined || !Number.isFinite(value) || value <= 0 ? fallback : Math.floor(value)\n\nexport const sandboxLifecycleOrDefault = (lifecycle?: SandboxLifecycle): SandboxLifecycle =>\n lifecycle ?? defaultSandboxLifecycle\n\nexport const sandboxSourceOrDefault = (source?: SandboxInitialSource): SandboxInitialSource =>\n source ?? defaultSandboxInitialSource\n\nexport const sandboxCommandTimeoutMs = (timeoutMs?: number) =>\n Math.min(maxSandboxCommandTimeoutMs, positiveOr(timeoutMs, defaultSandboxCommandTimeoutMs))\n\nexport const validateSandboxCommand = (command: string) => {\n if (command.trim().length === 0) {\n return Effect.fail(\n new SandboxInputError({\n cause: 'empty_command',\n message: 'Sandbox command must not be empty'\n })\n )\n }\n\n return Effect.succeed(command)\n}\n\nexport const normalizeWorkspaceCwd = (cwd?: string | null): Effect.Effect<string, SandboxInputError> => {\n if (cwd === undefined || cwd === null || cwd.trim().length === 0) {\n return Effect.succeed('.')\n }\n\n const trimmed = cwd.trim()\n\n if (trimmed.startsWith('/') || trimmed.includes('\\0')) {\n return Effect.fail(\n new SandboxInputError({\n cause: 'invalid_cwd',\n message: 'cwd must be workspace-relative'\n })\n )\n }\n\n const parts: Array<string> = []\n\n for (const segment of trimmed.split('/')) {\n if (segment.length === 0 || segment === '.') {\n continue\n }\n\n if (segment === '..') {\n const previous = parts.pop()\n if (previous === undefined) {\n return Effect.fail(\n new SandboxInputError({\n cause: 'invalid_cwd',\n message: 'cwd must not escape the workspace'\n })\n )\n }\n continue\n }\n\n parts.push(segment)\n }\n\n return Effect.succeed(parts.length === 0 ? '.' : parts.join('/'))\n}\n\nexport const absoluteSandboxCwd = (workspaceRoot: string, normalizedCwd: string) =>\n normalizedCwd === '.' ? workspaceRoot : `${workspaceRoot}/${normalizedCwd}`\n\nexport const initialSandboxState = (input: {\n readonly name: string\n readonly nowMs: number\n readonly lifecycle: SandboxLifecycle\n}) => {\n switch (input.lifecycle._tag) {\n case 'Disposable':\n return VercelSandboxState.make({\n name: input.name,\n createdAtMs: input.nowMs,\n lastUsedAtMs: input.nowMs,\n expiresAtMs: input.nowMs + input.lifecycle.idleTtlMs,\n maxExpiresAtMs: input.nowMs + input.lifecycle.maxLifetimeMs\n })\n case 'Persistent':\n return VercelSandboxState.make({\n name: input.name,\n createdAtMs: input.nowMs,\n lastUsedAtMs: input.nowMs,\n expiresAtMs: input.nowMs + input.lifecycle.idleTtlMs,\n maxExpiresAtMs: Number.MAX_SAFE_INTEGER\n })\n }\n}\n\nexport const touchSandboxState = (input: {\n readonly state: SandboxState\n readonly nowMs: number\n readonly lifecycle: SandboxLifecycle\n}) => {\n switch (input.lifecycle._tag) {\n case 'Disposable':\n return VercelSandboxState.make({\n ...input.state,\n lastUsedAtMs: input.nowMs,\n expiresAtMs: Math.min(input.nowMs + input.lifecycle.idleTtlMs, input.state.maxExpiresAtMs)\n })\n case 'Persistent':\n return VercelSandboxState.make({\n ...input.state,\n lastUsedAtMs: input.nowMs,\n expiresAtMs: input.nowMs + input.lifecycle.idleTtlMs\n })\n }\n}\n\nexport const sandboxTimeoutExtendDeltaMs = (input: {\n readonly before: SandboxState\n readonly after: SandboxState\n}) => Math.max(0, input.after.expiresAtMs - input.before.expiresAtMs)\n\nexport const sandboxStateDecision = (input: {\n readonly state: Option.Option<SandboxState>\n readonly name: string\n readonly nowMs: number\n}): SandboxStateDecision => {\n if (Option.isNone(input.state)) {\n return { _tag: 'Create', workspaceReset: false }\n }\n\n const state = input.state.value\n\n if (state.name !== input.name) {\n return { _tag: 'Create', workspaceReset: true, reason: 'name_mismatch' }\n }\n\n if (input.nowMs >= state.maxExpiresAtMs) {\n return { _tag: 'Create', workspaceReset: true, reason: 'max_expired' }\n }\n\n if (input.nowMs >= state.expiresAtMs) {\n return { _tag: 'Create', workspaceReset: true, reason: 'idle_expired' }\n }\n\n return { _tag: 'UseExisting', state }\n}\n"],"mappings":"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"}
|
package/dist/model.d.mts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
|
|
3
|
+
//#region src/model.d.ts
|
|
4
|
+
declare const SandboxCommandInput_base: Schema.Class<SandboxCommandInput, Schema.Struct<{
|
|
5
|
+
readonly command: Schema.String;
|
|
6
|
+
readonly cwd: Schema.optional<Schema.String>;
|
|
7
|
+
readonly stdin: Schema.optional<Schema.String>;
|
|
8
|
+
readonly timeoutMs: Schema.optional<Schema.Int>;
|
|
9
|
+
readonly background: Schema.optional<Schema.Boolean>;
|
|
10
|
+
}>, {}>;
|
|
11
|
+
declare class SandboxCommandInput extends SandboxCommandInput_base {}
|
|
12
|
+
declare const SandboxPreviewUrl_base: Schema.Class<SandboxPreviewUrl, Schema.Struct<{
|
|
13
|
+
readonly port: Schema.Int;
|
|
14
|
+
readonly url: Schema.Trimmed;
|
|
15
|
+
}>, {}>;
|
|
16
|
+
declare class SandboxPreviewUrl extends SandboxPreviewUrl_base {}
|
|
17
|
+
declare const VercelSandboxState_base: Schema.Class<VercelSandboxState, Schema.TaggedStruct<"Vercel", {
|
|
18
|
+
readonly name: Schema.Trimmed;
|
|
19
|
+
readonly createdAtMs: Schema.Int;
|
|
20
|
+
readonly lastUsedAtMs: Schema.Int;
|
|
21
|
+
readonly expiresAtMs: Schema.Int;
|
|
22
|
+
readonly maxExpiresAtMs: Schema.Int;
|
|
23
|
+
}>, {}>;
|
|
24
|
+
declare class VercelSandboxState extends VercelSandboxState_base {}
|
|
25
|
+
declare const SandboxState: Schema.Union<readonly [typeof VercelSandboxState]>;
|
|
26
|
+
type SandboxState = typeof SandboxState.Type;
|
|
27
|
+
declare const SandboxCommandResult_base: Schema.Class<SandboxCommandResult, Schema.Struct<{
|
|
28
|
+
readonly exitCode: Schema.NullOr<Schema.Int>;
|
|
29
|
+
readonly stdout: Schema.String;
|
|
30
|
+
readonly stderr: Schema.String;
|
|
31
|
+
readonly durationMs: Schema.Int;
|
|
32
|
+
readonly timedOut: Schema.Boolean;
|
|
33
|
+
readonly workspaceReset: Schema.Boolean;
|
|
34
|
+
readonly backgroundId: Schema.optional<Schema.Trimmed>;
|
|
35
|
+
readonly previewUrls: Schema.$Array<typeof SandboxPreviewUrl>;
|
|
36
|
+
readonly state: Schema.Union<readonly [typeof VercelSandboxState]>;
|
|
37
|
+
}>, {}>;
|
|
38
|
+
declare class SandboxCommandResult extends SandboxCommandResult_base {}
|
|
39
|
+
declare const DisposableSandboxLifecycle_base: Schema.Class<DisposableSandboxLifecycle, Schema.TaggedStruct<"Disposable", {
|
|
40
|
+
readonly idleTtlMs: Schema.Int;
|
|
41
|
+
readonly maxLifetimeMs: Schema.Int;
|
|
42
|
+
}>, {}>;
|
|
43
|
+
declare class DisposableSandboxLifecycle extends DisposableSandboxLifecycle_base {}
|
|
44
|
+
declare const SandboxSnapshotRetention_base: Schema.Class<SandboxSnapshotRetention, Schema.Struct<{
|
|
45
|
+
readonly count: Schema.Int;
|
|
46
|
+
readonly expirationMs: Schema.optional<Schema.Int>;
|
|
47
|
+
readonly deleteEvicted: Schema.optional<Schema.Boolean>;
|
|
48
|
+
}>, {}>;
|
|
49
|
+
declare class SandboxSnapshotRetention extends SandboxSnapshotRetention_base {}
|
|
50
|
+
declare const PersistentSandboxLifecycle_base: Schema.Class<PersistentSandboxLifecycle, Schema.TaggedStruct<"Persistent", {
|
|
51
|
+
readonly idleTtlMs: Schema.Int;
|
|
52
|
+
readonly snapshotExpirationMs: Schema.optional<Schema.Int>;
|
|
53
|
+
readonly keepLastSnapshots: Schema.optional<typeof SandboxSnapshotRetention>;
|
|
54
|
+
}>, {}>;
|
|
55
|
+
declare class PersistentSandboxLifecycle extends PersistentSandboxLifecycle_base {}
|
|
56
|
+
declare const SandboxLifecycle: Schema.Union<readonly [typeof DisposableSandboxLifecycle, typeof PersistentSandboxLifecycle]>;
|
|
57
|
+
type SandboxLifecycle = typeof SandboxLifecycle.Type;
|
|
58
|
+
declare const EmptySandboxInitialSource_base: Schema.Class<EmptySandboxInitialSource, Schema.TaggedStruct<"Empty", {}>, {}>;
|
|
59
|
+
declare class EmptySandboxInitialSource extends EmptySandboxInitialSource_base {}
|
|
60
|
+
declare const SnapshotSandboxInitialSource_base: Schema.Class<SnapshotSandboxInitialSource, Schema.TaggedStruct<"Snapshot", {
|
|
61
|
+
readonly snapshotId: Schema.Trimmed;
|
|
62
|
+
}>, {}>;
|
|
63
|
+
declare class SnapshotSandboxInitialSource extends SnapshotSandboxInitialSource_base {}
|
|
64
|
+
declare const GitSandboxInitialSource_base: Schema.Class<GitSandboxInitialSource, Schema.TaggedStruct<"Git", {
|
|
65
|
+
readonly url: Schema.Trimmed;
|
|
66
|
+
readonly username: Schema.optional<Schema.Trimmed>;
|
|
67
|
+
readonly password: Schema.optional<Schema.Trimmed>;
|
|
68
|
+
readonly depth: Schema.optional<Schema.Int>;
|
|
69
|
+
readonly revision: Schema.optional<Schema.Trimmed>;
|
|
70
|
+
}>, {}>;
|
|
71
|
+
declare class GitSandboxInitialSource extends GitSandboxInitialSource_base {}
|
|
72
|
+
declare const TarballSandboxInitialSource_base: Schema.Class<TarballSandboxInitialSource, Schema.TaggedStruct<"Tarball", {
|
|
73
|
+
readonly url: Schema.Trimmed;
|
|
74
|
+
}>, {}>;
|
|
75
|
+
declare class TarballSandboxInitialSource extends TarballSandboxInitialSource_base {}
|
|
76
|
+
declare const SandboxInitialSource: Schema.Union<readonly [typeof EmptySandboxInitialSource, typeof SnapshotSandboxInitialSource, typeof GitSandboxInitialSource, typeof TarballSandboxInitialSource]>;
|
|
77
|
+
type SandboxInitialSource = typeof SandboxInitialSource.Type;
|
|
78
|
+
declare const SandboxResources_base: Schema.Class<SandboxResources, Schema.Struct<{
|
|
79
|
+
readonly vcpus: Schema.Number;
|
|
80
|
+
}>, {}>;
|
|
81
|
+
declare class SandboxResources extends SandboxResources_base {}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { DisposableSandboxLifecycle, EmptySandboxInitialSource, GitSandboxInitialSource, PersistentSandboxLifecycle, SandboxCommandInput, SandboxCommandResult, SandboxInitialSource, SandboxLifecycle, SandboxPreviewUrl, SandboxResources, SandboxSnapshotRetention, SandboxState, SnapshotSandboxInitialSource, TarballSandboxInitialSource, VercelSandboxState };
|
|
84
|
+
//# sourceMappingURL=model.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.mts","names":[],"sources":["../src/model.ts"],"mappings":";;;cAAuC,wBAAA;;;;;;;cAO1B,mBAAA,SAA4B,wBAQvC;AAAA,cAAG,sBAAA;;;;cAEQ,iBAAA,SAA0B,sBAGrC;AAAA,cAAG,uBAAA;;;;;;;cAEQ,kBAAA,SAA2B,uBASvC;AAAA,cAEY,YAAA,EAAY,MAAA,CAAA,KAAA,kBAAA,kBAAA;AAAA,KACb,YAAA,UAAsB,YAAA,CAAa,IAAI;AAAA,cAAA,yBAAA;;;;;;;;;;;cAEtC,oBAAA,SAA6B,yBAYxC;AAAA,cAAG,+BAAA;;;;cAEQ,0BAAA,SAAmC,+BAM/C;AAAA,cAAG,6BAAA;;;;;cAES,wBAAA,SAAiC,6BAM5C;AAAA,cAAG,+BAAA;;;;;cAEQ,0BAAA,SAAmC,+BAO/C;AAAA,cAEY,gBAAA,EAAgB,MAAA,CAAA,KAAA,kBAAA,0BAAA,SAAA,0BAAA;AAAA,KAIjB,gBAAA,UAA0B,gBAAA,CAAiB,IAAI;AAAA,cAAA,8BAAA;cAE9C,yBAAA,SAAkC,8BAG9C;AAAA,cAAG,iCAAA;;;cAES,4BAAA,SAAqC,iCAKjD;AAAA,cAAG,4BAAA;;;;;;;cAES,uBAAA,SAAgC,4BAS5C;AAAA,cAAG,gCAAA;;;cAES,2BAAA,SAAoC,gCAKhD;AAAA,cAEY,oBAAA,EAAoB,MAAA,CAAA,KAAA,kBAAA,yBAAA,SAAA,4BAAA,SAAA,uBAAA,SAAA,2BAAA;AAAA,KAMrB,oBAAA,UAA8B,oBAAA,CAAqB,IAAI;AAAA,cAAA,qBAAA;;;cAEtD,gBAAA,SAAyB,qBAEpC"}
|
package/dist/model.mjs
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
//#region src/model.ts
|
|
3
|
+
const NonEmptyTrimmedString = Schema.Trimmed.pipe(Schema.check(Schema.isNonEmpty()));
|
|
4
|
+
const NonNegativeInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)));
|
|
5
|
+
const PositiveInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThan(0)));
|
|
6
|
+
const PositiveNumber = Schema.Number.pipe(Schema.check(Schema.isGreaterThan(0)));
|
|
7
|
+
var SandboxCommandInput = class extends Schema.Class("SandboxCommandInput")({
|
|
8
|
+
command: Schema.String,
|
|
9
|
+
cwd: Schema.optional(Schema.String),
|
|
10
|
+
stdin: Schema.optional(Schema.String),
|
|
11
|
+
timeoutMs: Schema.optional(PositiveInteger),
|
|
12
|
+
background: Schema.optional(Schema.Boolean)
|
|
13
|
+
}) {};
|
|
14
|
+
var SandboxPreviewUrl = class extends Schema.Class("SandboxPreviewUrl")({
|
|
15
|
+
port: PositiveInteger,
|
|
16
|
+
url: NonEmptyTrimmedString
|
|
17
|
+
}) {};
|
|
18
|
+
var VercelSandboxState = class extends Schema.TaggedClass()("Vercel", {
|
|
19
|
+
name: NonEmptyTrimmedString,
|
|
20
|
+
createdAtMs: NonNegativeInteger,
|
|
21
|
+
lastUsedAtMs: NonNegativeInteger,
|
|
22
|
+
expiresAtMs: NonNegativeInteger,
|
|
23
|
+
maxExpiresAtMs: NonNegativeInteger
|
|
24
|
+
}) {};
|
|
25
|
+
const SandboxState = Schema.Union([VercelSandboxState]);
|
|
26
|
+
var SandboxCommandResult = class extends Schema.Class("SandboxCommandResult")({
|
|
27
|
+
exitCode: Schema.NullOr(Schema.Int),
|
|
28
|
+
stdout: Schema.String,
|
|
29
|
+
stderr: Schema.String,
|
|
30
|
+
durationMs: NonNegativeInteger,
|
|
31
|
+
timedOut: Schema.Boolean,
|
|
32
|
+
workspaceReset: Schema.Boolean,
|
|
33
|
+
backgroundId: Schema.optional(NonEmptyTrimmedString),
|
|
34
|
+
previewUrls: Schema.Array(SandboxPreviewUrl),
|
|
35
|
+
state: SandboxState
|
|
36
|
+
}) {};
|
|
37
|
+
var DisposableSandboxLifecycle = class extends Schema.TaggedClass()("Disposable", {
|
|
38
|
+
idleTtlMs: PositiveInteger,
|
|
39
|
+
maxLifetimeMs: PositiveInteger
|
|
40
|
+
}) {};
|
|
41
|
+
var SandboxSnapshotRetention = class extends Schema.Class("SandboxSnapshotRetention")({
|
|
42
|
+
count: PositiveInteger,
|
|
43
|
+
expirationMs: Schema.optional(NonNegativeInteger),
|
|
44
|
+
deleteEvicted: Schema.optional(Schema.Boolean)
|
|
45
|
+
}) {};
|
|
46
|
+
var PersistentSandboxLifecycle = class extends Schema.TaggedClass()("Persistent", {
|
|
47
|
+
idleTtlMs: PositiveInteger,
|
|
48
|
+
snapshotExpirationMs: Schema.optional(NonNegativeInteger),
|
|
49
|
+
keepLastSnapshots: Schema.optional(SandboxSnapshotRetention)
|
|
50
|
+
}) {};
|
|
51
|
+
const SandboxLifecycle = Schema.Union([DisposableSandboxLifecycle, PersistentSandboxLifecycle]);
|
|
52
|
+
var EmptySandboxInitialSource = class extends Schema.TaggedClass()("Empty", {}) {};
|
|
53
|
+
var SnapshotSandboxInitialSource = class extends Schema.TaggedClass()("Snapshot", { snapshotId: NonEmptyTrimmedString }) {};
|
|
54
|
+
var GitSandboxInitialSource = class extends Schema.TaggedClass()("Git", {
|
|
55
|
+
url: NonEmptyTrimmedString,
|
|
56
|
+
username: Schema.optional(NonEmptyTrimmedString),
|
|
57
|
+
password: Schema.optional(NonEmptyTrimmedString),
|
|
58
|
+
depth: Schema.optional(PositiveInteger),
|
|
59
|
+
revision: Schema.optional(NonEmptyTrimmedString)
|
|
60
|
+
}) {};
|
|
61
|
+
var TarballSandboxInitialSource = class extends Schema.TaggedClass()("Tarball", { url: NonEmptyTrimmedString }) {};
|
|
62
|
+
const SandboxInitialSource = Schema.Union([
|
|
63
|
+
EmptySandboxInitialSource,
|
|
64
|
+
SnapshotSandboxInitialSource,
|
|
65
|
+
GitSandboxInitialSource,
|
|
66
|
+
TarballSandboxInitialSource
|
|
67
|
+
]);
|
|
68
|
+
var SandboxResources = class extends Schema.Class("SandboxResources")({ vcpus: PositiveNumber }) {};
|
|
69
|
+
//#endregion
|
|
70
|
+
export { DisposableSandboxLifecycle, EmptySandboxInitialSource, GitSandboxInitialSource, PersistentSandboxLifecycle, SandboxCommandInput, SandboxCommandResult, SandboxInitialSource, SandboxLifecycle, SandboxPreviewUrl, SandboxResources, SandboxSnapshotRetention, SandboxState, SnapshotSandboxInitialSource, TarballSandboxInitialSource, VercelSandboxState };
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.mjs","names":[],"sources":["../src/model.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\n\nconst NonEmptyTrimmedString = Schema.Trimmed.pipe(Schema.check(Schema.isNonEmpty()))\nconst NonNegativeInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)))\nconst PositiveInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThan(0)))\nconst PositiveNumber = Schema.Number.pipe(Schema.check(Schema.isGreaterThan(0)))\n\nexport class SandboxCommandInput extends Schema.Class<SandboxCommandInput>(\n 'SandboxCommandInput'\n)({\n command: Schema.String,\n cwd: Schema.optional(Schema.String),\n stdin: Schema.optional(Schema.String),\n timeoutMs: Schema.optional(PositiveInteger),\n background: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class SandboxPreviewUrl extends Schema.Class<SandboxPreviewUrl>('SandboxPreviewUrl')({\n port: PositiveInteger,\n url: NonEmptyTrimmedString\n}) {}\n\nexport class VercelSandboxState extends Schema.TaggedClass<VercelSandboxState>()(\n 'Vercel',\n {\n name: NonEmptyTrimmedString,\n createdAtMs: NonNegativeInteger,\n lastUsedAtMs: NonNegativeInteger,\n expiresAtMs: NonNegativeInteger,\n maxExpiresAtMs: NonNegativeInteger\n }\n) {}\n\nexport const SandboxState = Schema.Union([VercelSandboxState])\nexport type SandboxState = typeof SandboxState.Type\n\nexport class SandboxCommandResult extends Schema.Class<SandboxCommandResult>(\n 'SandboxCommandResult'\n)({\n exitCode: Schema.NullOr(Schema.Int),\n stdout: Schema.String,\n stderr: Schema.String,\n durationMs: NonNegativeInteger,\n timedOut: Schema.Boolean,\n workspaceReset: Schema.Boolean,\n backgroundId: Schema.optional(NonEmptyTrimmedString),\n previewUrls: Schema.Array(SandboxPreviewUrl),\n state: SandboxState\n}) {}\n\nexport class DisposableSandboxLifecycle extends Schema.TaggedClass<DisposableSandboxLifecycle>()(\n 'Disposable',\n {\n idleTtlMs: PositiveInteger,\n maxLifetimeMs: PositiveInteger\n }\n) {}\n\nexport class SandboxSnapshotRetention extends Schema.Class<SandboxSnapshotRetention>(\n 'SandboxSnapshotRetention'\n)({\n count: PositiveInteger,\n expirationMs: Schema.optional(NonNegativeInteger),\n deleteEvicted: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class PersistentSandboxLifecycle extends Schema.TaggedClass<PersistentSandboxLifecycle>()(\n 'Persistent',\n {\n idleTtlMs: PositiveInteger,\n snapshotExpirationMs: Schema.optional(NonNegativeInteger),\n keepLastSnapshots: Schema.optional(SandboxSnapshotRetention)\n }\n) {}\n\nexport const SandboxLifecycle = Schema.Union([\n DisposableSandboxLifecycle,\n PersistentSandboxLifecycle\n])\nexport type SandboxLifecycle = typeof SandboxLifecycle.Type\n\nexport class EmptySandboxInitialSource extends Schema.TaggedClass<EmptySandboxInitialSource>()(\n 'Empty',\n {}\n) {}\n\nexport class SnapshotSandboxInitialSource extends Schema.TaggedClass<SnapshotSandboxInitialSource>()(\n 'Snapshot',\n {\n snapshotId: NonEmptyTrimmedString\n }\n) {}\n\nexport class GitSandboxInitialSource extends Schema.TaggedClass<GitSandboxInitialSource>()(\n 'Git',\n {\n url: NonEmptyTrimmedString,\n username: Schema.optional(NonEmptyTrimmedString),\n password: Schema.optional(NonEmptyTrimmedString),\n depth: Schema.optional(PositiveInteger),\n revision: Schema.optional(NonEmptyTrimmedString)\n }\n) {}\n\nexport class TarballSandboxInitialSource extends Schema.TaggedClass<TarballSandboxInitialSource>()(\n 'Tarball',\n {\n url: NonEmptyTrimmedString\n }\n) {}\n\nexport const SandboxInitialSource = Schema.Union([\n EmptySandboxInitialSource,\n SnapshotSandboxInitialSource,\n GitSandboxInitialSource,\n TarballSandboxInitialSource\n])\nexport type SandboxInitialSource = typeof SandboxInitialSource.Type\n\nexport class SandboxResources extends Schema.Class<SandboxResources>('SandboxResources')({\n vcpus: PositiveNumber\n}) {}\n"],"mappings":";;AAEA,MAAM,wBAAwB,OAAO,QAAQ,KAAK,OAAO,MAAM,OAAO,WAAW,CAAC,CAAC;AACnF,MAAM,qBAAqB,OAAO,IAAI,KAAK,OAAO,MAAM,OAAO,uBAAuB,CAAC,CAAC,CAAC;AACzF,MAAM,kBAAkB,OAAO,IAAI,KAAK,OAAO,MAAM,OAAO,cAAc,CAAC,CAAC,CAAC;AAC7E,MAAM,iBAAiB,OAAO,OAAO,KAAK,OAAO,MAAM,OAAO,cAAc,CAAC,CAAC,CAAC;AAE/E,IAAa,sBAAb,cAAyC,OAAO,MAC9C,qBACF,EAAE;CACA,SAAS,OAAO;CAChB,KAAK,OAAO,SAAS,OAAO,MAAM;CAClC,OAAO,OAAO,SAAS,OAAO,MAAM;CACpC,WAAW,OAAO,SAAS,eAAe;CAC1C,YAAY,OAAO,SAAS,OAAO,OAAO;AAC5C,CAAC,EAAE,CAAC;AAEJ,IAAa,oBAAb,cAAuC,OAAO,MAAyB,mBAAmB,EAAE;CAC1F,MAAM;CACN,KAAK;AACP,CAAC,EAAE,CAAC;AAEJ,IAAa,qBAAb,cAAwC,OAAO,YAAgC,EAC7E,UACA;CACE,MAAM;CACN,aAAa;CACb,cAAc;CACd,aAAa;CACb,gBAAgB;AAClB,CACF,EAAE,CAAC;AAEH,MAAa,eAAe,OAAO,MAAM,CAAC,kBAAkB,CAAC;AAG7D,IAAa,uBAAb,cAA0C,OAAO,MAC/C,sBACF,EAAE;CACA,UAAU,OAAO,OAAO,OAAO,GAAG;CAClC,QAAQ,OAAO;CACf,QAAQ,OAAO;CACf,YAAY;CACZ,UAAU,OAAO;CACjB,gBAAgB,OAAO;CACvB,cAAc,OAAO,SAAS,qBAAqB;CACnD,aAAa,OAAO,MAAM,iBAAiB;CAC3C,OAAO;AACT,CAAC,EAAE,CAAC;AAEJ,IAAa,6BAAb,cAAgD,OAAO,YAAwC,EAC7F,cACA;CACE,WAAW;CACX,eAAe;AACjB,CACF,EAAE,CAAC;AAEH,IAAa,2BAAb,cAA8C,OAAO,MACnD,0BACF,EAAE;CACA,OAAO;CACP,cAAc,OAAO,SAAS,kBAAkB;CAChD,eAAe,OAAO,SAAS,OAAO,OAAO;AAC/C,CAAC,EAAE,CAAC;AAEJ,IAAa,6BAAb,cAAgD,OAAO,YAAwC,EAC7F,cACA;CACE,WAAW;CACX,sBAAsB,OAAO,SAAS,kBAAkB;CACxD,mBAAmB,OAAO,SAAS,wBAAwB;AAC7D,CACF,EAAE,CAAC;AAEH,MAAa,mBAAmB,OAAO,MAAM,CAC3C,4BACA,0BACF,CAAC;AAGD,IAAa,4BAAb,cAA+C,OAAO,YAAuC,EAC3F,SACA,CAAC,CACH,EAAE,CAAC;AAEH,IAAa,+BAAb,cAAkD,OAAO,YAA0C,EACjG,YACA,EACE,YAAY,sBACd,CACF,EAAE,CAAC;AAEH,IAAa,0BAAb,cAA6C,OAAO,YAAqC,EACvF,OACA;CACE,KAAK;CACL,UAAU,OAAO,SAAS,qBAAqB;CAC/C,UAAU,OAAO,SAAS,qBAAqB;CAC/C,OAAO,OAAO,SAAS,eAAe;CACtC,UAAU,OAAO,SAAS,qBAAqB;AACjD,CACF,EAAE,CAAC;AAEH,IAAa,8BAAb,cAAiD,OAAO,YAAyC,EAC/F,WACA,EACE,KAAK,sBACP,CACF,EAAE,CAAC;AAEH,MAAa,uBAAuB,OAAO,MAAM;CAC/C;CACA;CACA;CACA;AACF,CAAC;AAGD,IAAa,mBAAb,cAAsC,OAAO,MAAwB,kBAAkB,EAAE,EACvF,OAAO,eACT,CAAC,EAAE,CAAC"}
|
package/dist/name.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name.d.mts","names":[],"sources":["../src/name.ts"],"mappings":";cAqBa,qBAAA,GAAyB,gBAAwB"}
|
package/dist/name.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/name.ts
|
|
2
|
+
const fnvOffsetBasis32 = 2166136261;
|
|
3
|
+
const fnvPrime32 = 16777619;
|
|
4
|
+
const fnv1a32 = (value, seed) => {
|
|
5
|
+
let hash = seed;
|
|
6
|
+
for (const character of value) {
|
|
7
|
+
hash ^= character.codePointAt(0) ?? 0;
|
|
8
|
+
hash = Math.imul(hash, fnvPrime32);
|
|
9
|
+
}
|
|
10
|
+
return (hash >>> 0).toString(36).padStart(7, "0");
|
|
11
|
+
};
|
|
12
|
+
const stableHash = (value) => {
|
|
13
|
+
return `${fnv1a32(value, fnvOffsetBasis32)}${fnv1a32([...value].reverse().join(""), fnvOffsetBasis32 ^ 2654435769)}`;
|
|
14
|
+
};
|
|
15
|
+
const makeVercelSandboxName = (sandboxSessionId) => `sandbox-${stableHash(sandboxSessionId)}`;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { makeVercelSandboxName };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=name.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name.mjs","names":[],"sources":["../src/name.ts"],"sourcesContent":["const fnvOffsetBasis32 = 0x811c9dc5\nconst fnvPrime32 = 0x01000193\n\nconst fnv1a32 = (value: string, seed: number) => {\n let hash = seed\n\n for (const character of value) {\n hash ^= character.codePointAt(0) ?? 0\n hash = Math.imul(hash, fnvPrime32)\n }\n\n return (hash >>> 0).toString(36).padStart(7, '0')\n}\n\nconst stableHash = (value: string) => {\n const first = fnv1a32(value, fnvOffsetBasis32)\n const second = fnv1a32([...value].reverse().join(''), fnvOffsetBasis32 ^ 0x9e3779b9)\n\n return `${first}${second}`\n}\n\nexport const makeVercelSandboxName = (sandboxSessionId: string) =>\n `sandbox-${stableHash(sandboxSessionId)}`\n"],"mappings":";AAAA,MAAM,mBAAmB;AACzB,MAAM,aAAa;AAEnB,MAAM,WAAW,OAAe,SAAiB;CAC/C,IAAI,OAAO;CAEX,KAAK,MAAM,aAAa,OAAO;EAC7B,QAAQ,UAAU,YAAY,CAAC,KAAK;EACpC,OAAO,KAAK,KAAK,MAAM,UAAU;CACnC;CAEA,QAAQ,SAAS,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAClD;AAEA,MAAM,cAAc,UAAkB;CAIpC,OAAO,GAHO,QAAQ,OAAO,gBAGf,IAFC,QAAQ,CAAC,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,mBAAmB,UAElD;AACzB;AAEA,MAAa,yBAAyB,qBACpC,WAAW,WAAW,gBAAgB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SandboxError, SandboxProviderError, SandboxStateError, SandboxStateStoreError } from "./errors.mjs";
|
|
2
|
+
import { SandboxCommandInput, SandboxCommandResult, SandboxState } from "./model.mjs";
|
|
3
|
+
import { Context, Effect, Option } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/service.d.ts
|
|
6
|
+
type SandboxApi = {
|
|
7
|
+
readonly run: (input: SandboxCommandInput) => Effect.Effect<SandboxCommandResult, SandboxError>;
|
|
8
|
+
readonly currentState: Effect.Effect<Option.Option<SandboxState>, SandboxStateStoreError | SandboxStateError>;
|
|
9
|
+
readonly delete: Effect.Effect<void, SandboxProviderError | SandboxStateStoreError | SandboxStateError>;
|
|
10
|
+
};
|
|
11
|
+
declare const Sandbox_base: Context.ServiceClass<Sandbox, "@yolk-sdk/sandbox/Sandbox", SandboxApi>;
|
|
12
|
+
declare class Sandbox extends Sandbox_base {}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { Sandbox, SandboxApi };
|
|
15
|
+
//# sourceMappingURL=service.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.mts","names":[],"sources":["../src/service.ts"],"mappings":";;;;;KAUY,UAAA;EAAA,SACD,GAAA,GAAM,KAAA,EAAO,mBAAA,KAAwB,MAAA,CAAO,MAAA,CAAO,oBAAA,EAAsB,YAAA;EAAA,SACzE,YAAA,EAAc,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,YAAA,GAAe,sBAAA,GAAyB,iBAAA;EAAA,SAClF,MAAA,EAAQ,MAAA,CAAO,MAAA,OAAa,oBAAA,GAAuB,sBAAA,GAAyB,iBAAA;AAAA;AAAA,cACtF,YAAA;cAEY,OAAA,SAAgB,YAE5B"}
|
package/dist/service.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.mjs","names":[],"sources":["../src/service.ts"],"sourcesContent":["import { Context } from 'effect'\nimport type { Effect, Option } from 'effect'\nimport type {\n SandboxError,\n SandboxProviderError,\n SandboxStateError,\n SandboxStateStoreError\n} from './errors.ts'\nimport type { SandboxCommandInput, SandboxCommandResult, SandboxState } from './model.ts'\n\nexport type SandboxApi = {\n readonly run: (input: SandboxCommandInput) => Effect.Effect<SandboxCommandResult, SandboxError>\n readonly currentState: Effect.Effect<Option.Option<SandboxState>, SandboxStateStoreError | SandboxStateError>\n readonly delete: Effect.Effect<void, SandboxProviderError | SandboxStateStoreError | SandboxStateError>\n}\n\nexport class Sandbox extends Context.Service<Sandbox, SandboxApi>()(\n '@yolk-sdk/sandbox/Sandbox'\n) {}\n"],"mappings":";;AAgBA,IAAa,UAAb,cAA6B,QAAQ,QAA6B,EAChE,2BACF,EAAE,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SandboxStateStoreError } from "./errors.mjs";
|
|
2
|
+
import { SandboxState } from "./model.mjs";
|
|
3
|
+
import { Context, Effect, Option } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/state-store.d.ts
|
|
6
|
+
type SandboxStateStoreApi = {
|
|
7
|
+
readonly load: (sandboxSessionId: string) => Effect.Effect<Option.Option<SandboxState>, SandboxStateStoreError>;
|
|
8
|
+
readonly save: (input: {
|
|
9
|
+
readonly sandboxSessionId: string;
|
|
10
|
+
readonly state: SandboxState;
|
|
11
|
+
}) => Effect.Effect<void, SandboxStateStoreError>;
|
|
12
|
+
readonly clear: (sandboxSessionId: string) => Effect.Effect<void, SandboxStateStoreError>;
|
|
13
|
+
};
|
|
14
|
+
declare const SandboxStateStore_base: Context.ServiceClass<SandboxStateStore, "@yolk-sdk/sandbox/SandboxStateStore", SandboxStateStoreApi>;
|
|
15
|
+
declare class SandboxStateStore extends SandboxStateStore_base {}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { SandboxStateStore, SandboxStateStoreApi };
|
|
18
|
+
//# sourceMappingURL=state-store.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store.d.mts","names":[],"sources":["../src/state-store.ts"],"mappings":";;;;;KAKY,oBAAA;EAAA,SACD,IAAA,GAAO,gBAAA,aAA6B,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,YAAA,GAAe,sBAAA;EAAA,SAC/E,IAAA,GAAO,KAAA;IAAA,SACL,gBAAA;IAAA,SACA,KAAA,EAAO,YAAA;EAAA,MACZ,MAAA,CAAO,MAAA,OAAa,sBAAA;EAAA,SACjB,KAAA,GAAQ,gBAAA,aAA6B,MAAA,CAAO,MAAA,OAAa,sBAAA;AAAA;AAAA,cACnE,sBAAA;cAEY,iBAAA,SAA0B,sBAEtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store.mjs","names":[],"sources":["../src/state-store.ts"],"sourcesContent":["import { Context } from 'effect'\nimport type { Effect, Option } from 'effect'\nimport type { SandboxStateStoreError } from './errors.ts'\nimport type { SandboxState } from './model.ts'\n\nexport type SandboxStateStoreApi = {\n readonly load: (sandboxSessionId: string) => Effect.Effect<Option.Option<SandboxState>, SandboxStateStoreError>\n readonly save: (input: {\n readonly sandboxSessionId: string\n readonly state: SandboxState\n }) => Effect.Effect<void, SandboxStateStoreError>\n readonly clear: (sandboxSessionId: string) => Effect.Effect<void, SandboxStateStoreError>\n}\n\nexport class SandboxStateStore extends Context.Service<SandboxStateStore, SandboxStateStoreApi>()(\n '@yolk-sdk/sandbox/SandboxStateStore'\n) {}\n"],"mappings":";;AAcA,IAAa,oBAAb,cAAuC,QAAQ,QAAiD,EAC9F,qCACF,EAAE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SandboxError } from "../errors.mjs";
|
|
2
|
+
import { SandboxCommandInput, SandboxCommandResult, SandboxState } from "../model.mjs";
|
|
3
|
+
import { Sandbox } from "../service.mjs";
|
|
4
|
+
import { SandboxStateStore } from "../state-store.mjs";
|
|
5
|
+
import { Effect, Layer } from "effect";
|
|
6
|
+
|
|
7
|
+
//#region src/testing/index.d.ts
|
|
8
|
+
type FakeSandboxRun = (input: SandboxCommandInput) => Effect.Effect<SandboxCommandResult, SandboxError>;
|
|
9
|
+
type FakeSandboxOptions = {
|
|
10
|
+
readonly run: FakeSandboxRun;
|
|
11
|
+
readonly initialState?: SandboxState;
|
|
12
|
+
};
|
|
13
|
+
declare const makeFakeSandboxLayer: (options: FakeSandboxOptions) => Layer.Layer<Sandbox, never, never>;
|
|
14
|
+
type InMemorySandboxStateStoreEntry = {
|
|
15
|
+
readonly sandboxSessionId: string;
|
|
16
|
+
readonly state: SandboxState;
|
|
17
|
+
};
|
|
18
|
+
declare const makeInMemorySandboxStateStoreLayer: (initial?: ReadonlyArray<InMemorySandboxStateStoreEntry>) => Layer.Layer<SandboxStateStore, never, never>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { FakeSandboxOptions, FakeSandboxRun, InMemorySandboxStateStoreEntry, makeFakeSandboxLayer, makeInMemorySandboxStateStoreLayer };
|
|
21
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/testing/index.ts"],"mappings":";;;;;;;KAMY,cAAA,IACV,KAAA,EAAO,mBAAA,KACJ,MAAA,CAAO,MAAA,CAAO,oBAAA,EAAsB,YAAA;AAAA,KAE7B,kBAAA;EAAA,SACD,GAAA,EAAK,cAAA;EAAA,SACL,YAAA,GAAe,YAAY;AAAA;AAAA,cAGzB,oBAAA,GAAwB,OAAA,EAAS,kBAAA,KAAkB,KAAA,CAAA,KAAA,CAAA,OAAA;AAAA,KAiBpD,8BAAA;EAAA,SACD,gBAAA;EAAA,SACA,KAAA,EAAO,YAAY;AAAA;AAAA,cAGjB,kCAAA,GACX,OAAA,GAAS,aAAA,CAAc,8BAAA,MAAoC,KAAA,CAAA,KAAA,CAAA,iBAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Sandbox } from "../service.mjs";
|
|
2
|
+
import { SandboxStateStore } from "../state-store.mjs";
|
|
3
|
+
import { Effect, Layer, Option, Ref } from "effect";
|
|
4
|
+
//#region src/testing/index.ts
|
|
5
|
+
const makeFakeSandboxLayer = (options) => Layer.effect(Sandbox, Ref.make(Option.fromNullishOr(options.initialState)).pipe(Effect.map((stateRef) => Sandbox.of({
|
|
6
|
+
run: (input) => options.run(input).pipe(Effect.tap((result) => Ref.set(stateRef, Option.some(result.state)))),
|
|
7
|
+
currentState: Ref.get(stateRef),
|
|
8
|
+
delete: Ref.set(stateRef, Option.none())
|
|
9
|
+
}))));
|
|
10
|
+
const makeInMemorySandboxStateStoreLayer = (initial = []) => Layer.effect(SandboxStateStore, Effect.gen(function* () {
|
|
11
|
+
const states = yield* Ref.make(new Map(initial.map((entry) => [entry.sandboxSessionId, entry.state])));
|
|
12
|
+
return SandboxStateStore.of({
|
|
13
|
+
load: (sandboxSessionId) => Ref.get(states).pipe(Effect.map((current) => Option.fromNullishOr(current.get(sandboxSessionId)))),
|
|
14
|
+
save: (input) => Ref.update(states, (current) => new Map([...current, [input.sandboxSessionId, input.state]])),
|
|
15
|
+
clear: (sandboxSessionId) => Ref.update(states, (current) => {
|
|
16
|
+
const next = new Map(current);
|
|
17
|
+
next.delete(sandboxSessionId);
|
|
18
|
+
return next;
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
}));
|
|
22
|
+
//#endregion
|
|
23
|
+
export { makeFakeSandboxLayer, makeInMemorySandboxStateStoreLayer };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/testing/index.ts"],"sourcesContent":["import { Effect, Layer, Option, Ref } from 'effect'\nimport type { SandboxCommandInput, SandboxCommandResult, SandboxState } from '../model.ts'\nimport { Sandbox } from '../service.ts'\nimport { SandboxStateStore } from '../state-store.ts'\nimport type { SandboxError } from '../errors.ts'\n\nexport type FakeSandboxRun = (\n input: SandboxCommandInput\n) => Effect.Effect<SandboxCommandResult, SandboxError>\n\nexport type FakeSandboxOptions = {\n readonly run: FakeSandboxRun\n readonly initialState?: SandboxState\n}\n\nexport const makeFakeSandboxLayer = (options: FakeSandboxOptions) =>\n Layer.effect(\n Sandbox,\n Ref.make(Option.fromNullishOr(options.initialState)).pipe(\n Effect.map(stateRef =>\n Sandbox.of({\n run: input =>\n options.run(input).pipe(\n Effect.tap(result => Ref.set(stateRef, Option.some(result.state)))\n ),\n currentState: Ref.get(stateRef),\n delete: Ref.set(stateRef, Option.none())\n })\n )\n )\n )\n\nexport type InMemorySandboxStateStoreEntry = {\n readonly sandboxSessionId: string\n readonly state: SandboxState\n}\n\nexport const makeInMemorySandboxStateStoreLayer = (\n initial: ReadonlyArray<InMemorySandboxStateStoreEntry> = []\n) =>\n Layer.effect(\n SandboxStateStore,\n Effect.gen(function* () {\n const states = yield* Ref.make(\n new Map(initial.map(entry => [entry.sandboxSessionId, entry.state]))\n )\n\n return SandboxStateStore.of({\n load: sandboxSessionId =>\n Ref.get(states).pipe(\n Effect.map(current => Option.fromNullishOr(current.get(sandboxSessionId)))\n ),\n save: input =>\n Ref.update(states, current => new Map([...current, [input.sandboxSessionId, input.state]])),\n clear: sandboxSessionId =>\n Ref.update(states, current => {\n const next = new Map(current)\n next.delete(sandboxSessionId)\n return next\n })\n })\n })\n )\n"],"mappings":";;;;AAeA,MAAa,wBAAwB,YACnC,MAAM,OACJ,SACA,IAAI,KAAK,OAAO,cAAc,QAAQ,YAAY,CAAC,EAAE,KACnD,OAAO,KAAI,aACT,QAAQ,GAAG;CACT,MAAK,UACH,QAAQ,IAAI,KAAK,EAAE,KACjB,OAAO,KAAI,WAAU,IAAI,IAAI,UAAU,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC,CACnE;CACF,cAAc,IAAI,IAAI,QAAQ;CAC9B,QAAQ,IAAI,IAAI,UAAU,OAAO,KAAK,CAAC;AACzC,CAAC,CACH,CACF,CACF;AAOF,MAAa,sCACX,UAAyD,CAAC,MAE1D,MAAM,OACJ,mBACA,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO,IAAI,KACxB,IAAI,IAAI,QAAQ,KAAI,UAAS,CAAC,MAAM,kBAAkB,MAAM,KAAK,CAAC,CAAC,CACrE;CAEA,OAAO,kBAAkB,GAAG;EAC1B,OAAM,qBACJ,IAAI,IAAI,MAAM,EAAE,KACd,OAAO,KAAI,YAAW,OAAO,cAAc,QAAQ,IAAI,gBAAgB,CAAC,CAAC,CAC3E;EACF,OAAM,UACJ,IAAI,OAAO,SAAQ,YAAW,IAAI,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,kBAAkB,MAAM,KAAK,CAAC,CAAC,CAAC;EAC5F,QAAO,qBACL,IAAI,OAAO,SAAQ,YAAW;GAC5B,MAAM,OAAO,IAAI,IAAI,OAAO;GAC5B,KAAK,OAAO,gBAAgB;GAC5B,OAAO;EACT,CAAC;CACL,CAAC;AACH,CAAC,CACH"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { SandboxInitialSource, SandboxResources, SandboxSnapshotRetention } from "../model.mjs";
|
|
2
|
+
import { Context, Layer } from "effect";
|
|
3
|
+
import { NetworkPolicy } from "@vercel/sandbox";
|
|
4
|
+
|
|
5
|
+
//#region src/vercel/client.d.ts
|
|
6
|
+
type VercelSandboxRuntime = 'node22' | 'node24' | 'node26' | 'python3.13';
|
|
7
|
+
type VercelNetworkPolicy = NetworkPolicy;
|
|
8
|
+
type VercelCommandOutput = {
|
|
9
|
+
readonly stdout: string;
|
|
10
|
+
readonly stderr: string;
|
|
11
|
+
};
|
|
12
|
+
type VercelCommandSignal = 'SIGTERM' | 'SIGKILL';
|
|
13
|
+
type VercelFinishedCommand = {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly exitCode: number;
|
|
16
|
+
readonly output: () => Promise<VercelCommandOutput>;
|
|
17
|
+
};
|
|
18
|
+
type VercelDetachedCommand = {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly exitCode: number | null;
|
|
21
|
+
readonly wait: () => Promise<VercelFinishedCommand>;
|
|
22
|
+
readonly kill: (signal: VercelCommandSignal) => Promise<void>;
|
|
23
|
+
readonly output: () => Promise<VercelCommandOutput>;
|
|
24
|
+
};
|
|
25
|
+
type VercelSandboxFile = {
|
|
26
|
+
readonly path: string;
|
|
27
|
+
readonly content: string;
|
|
28
|
+
readonly mode?: number;
|
|
29
|
+
};
|
|
30
|
+
type VercelRunCommandInput = {
|
|
31
|
+
readonly cmd: string;
|
|
32
|
+
readonly args?: ReadonlyArray<string>;
|
|
33
|
+
readonly cwd?: string;
|
|
34
|
+
};
|
|
35
|
+
type VercelSandboxCreateInput = {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly source: SandboxInitialSource;
|
|
38
|
+
readonly ports: ReadonlyArray<number>;
|
|
39
|
+
readonly timeoutMs: number;
|
|
40
|
+
readonly resources: SandboxResources;
|
|
41
|
+
readonly runtime: VercelSandboxRuntime;
|
|
42
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
43
|
+
readonly persistent: boolean;
|
|
44
|
+
readonly snapshotExpirationMs?: number;
|
|
45
|
+
readonly keepLastSnapshots?: SandboxSnapshotRetention;
|
|
46
|
+
readonly networkPolicy?: VercelNetworkPolicy;
|
|
47
|
+
};
|
|
48
|
+
type VercelSandboxGetInput = {
|
|
49
|
+
readonly name: string;
|
|
50
|
+
};
|
|
51
|
+
type VercelSandboxHandle = {
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly writeFiles: (files: ReadonlyArray<VercelSandboxFile>) => Promise<void>;
|
|
54
|
+
readonly runDetachedCommand: (input: VercelRunCommandInput) => Promise<VercelDetachedCommand>;
|
|
55
|
+
readonly getCommand: (id: string) => Promise<VercelDetachedCommand>;
|
|
56
|
+
readonly extendTimeout: (durationMs: number) => Promise<void>;
|
|
57
|
+
readonly delete: () => Promise<void>;
|
|
58
|
+
readonly domain: (port: number) => string;
|
|
59
|
+
};
|
|
60
|
+
type VercelSandboxClientApi = {
|
|
61
|
+
readonly get: (input: VercelSandboxGetInput) => Promise<VercelSandboxHandle | null>;
|
|
62
|
+
readonly create: (input: VercelSandboxCreateInput) => Promise<VercelSandboxHandle>;
|
|
63
|
+
};
|
|
64
|
+
declare const VercelSandboxClient_base: Context.ServiceClass<VercelSandboxClient, "@yolk-sdk/sandbox/vercel/VercelSandboxClient", VercelSandboxClientApi>;
|
|
65
|
+
declare class VercelSandboxClient extends VercelSandboxClient_base {}
|
|
66
|
+
declare const isVercelMissingSandboxError: (error: unknown) => boolean;
|
|
67
|
+
declare const VercelSandboxClientLive: Layer.Layer<VercelSandboxClient, never, never>;
|
|
68
|
+
//#endregion
|
|
69
|
+
export { VercelCommandOutput, VercelCommandSignal, VercelDetachedCommand, VercelFinishedCommand, VercelNetworkPolicy, VercelRunCommandInput, VercelSandboxClient, VercelSandboxClientApi, VercelSandboxClientLive, VercelSandboxCreateInput, VercelSandboxFile, VercelSandboxGetInput, VercelSandboxHandle, VercelSandboxRuntime, isVercelMissingSandboxError };
|
|
70
|
+
//# sourceMappingURL=client.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.mts","names":[],"sources":["../../src/vercel/client.ts"],"mappings":";;;;;KAIY,oBAAA;AAAA,KACA,mBAAA,GAAsB,aAAa;AAAA,KAEnC,mBAAA;EAAA,SACD,MAAA;EAAA,SACA,MAAM;AAAA;AAAA,KAGL,mBAAA;AAAA,KAEA,qBAAA;EAAA,SACD,EAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA,QAAc,OAAO,CAAC,mBAAA;AAAA;AAAA,KAGrB,qBAAA;EAAA,SACD,EAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA,QAAY,OAAA,CAAQ,qBAAA;EAAA,SACpB,IAAA,GAAO,MAAA,EAAQ,mBAAA,KAAwB,OAAA;EAAA,SACvC,MAAA,QAAc,OAAA,CAAQ,mBAAA;AAAA;AAAA,KAGrB,iBAAA;EAAA,SACD,IAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;AAAA;AAAA,KAGC,qBAAA;EAAA,SACD,GAAA;EAAA,SACA,IAAA,GAAO,aAAa;EAAA,SACpB,GAAA;AAAA;AAAA,KAGC,wBAAA;EAAA,SACD,IAAA;EAAA,SACA,MAAA,EAAQ,oBAAA;EAAA,SACR,KAAA,EAAO,aAAA;EAAA,SACP,SAAA;EAAA,SACA,SAAA,EAAW,gBAAA;EAAA,SACX,OAAA,EAAS,oBAAA;EAAA,SACT,GAAA,GAAM,QAAA,CAAS,MAAA;EAAA,SACf,UAAA;EAAA,SACA,oBAAA;EAAA,SACA,iBAAA,GAAoB,wBAAA;EAAA,SACpB,aAAA,GAAgB,mBAAA;AAAA;AAAA,KAGf,qBAAA;EAAA,SACD,IAAI;AAAA;AAAA,KAGH,mBAAA;EAAA,SACD,IAAA;EAAA,SACA,UAAA,GAAa,KAAA,EAAO,aAAA,CAAc,iBAAA,MAAuB,OAAA;EAAA,SACzD,kBAAA,GAAqB,KAAA,EAAO,qBAAA,KAA0B,OAAA,CAAQ,qBAAA;EAAA,SAC9D,UAAA,GAAa,EAAA,aAAe,OAAA,CAAQ,qBAAA;EAAA,SACpC,aAAA,GAAgB,UAAA,aAAuB,OAAA;EAAA,SACvC,MAAA,QAAc,OAAA;EAAA,SACd,MAAA,GAAS,IAAA;AAAA;AAAA,KAGR,sBAAA;EAAA,SACD,GAAA,GAAM,KAAA,EAAO,qBAAA,KAA0B,OAAA,CAAQ,mBAAA;EAAA,SAC/C,MAAA,GAAS,KAAA,EAAO,wBAAA,KAA6B,OAAA,CAAQ,mBAAA;AAAA;AAAA,cAC/D,wBAAA;cAEY,mBAAA,SAA4B,wBAExC;AAAA,cAEY,2BAAA,GAA+B,KAAc;AAAA,cAoI7C,uBAAA,EAAuB,KAAA,CAAA,KAAA,CAAA,mBAAA"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Context, Layer } from "effect";
|
|
2
|
+
import { APIError, Sandbox } from "@vercel/sandbox";
|
|
3
|
+
//#region src/vercel/client.ts
|
|
4
|
+
var VercelSandboxClient = class extends Context.Service()("@yolk-sdk/sandbox/vercel/VercelSandboxClient") {};
|
|
5
|
+
const isVercelMissingSandboxError = (error) => error instanceof APIError && (error.response.status === 404 || error.response.status === 410);
|
|
6
|
+
const commandOutput = (command) => Promise.all([command.stdout(), command.stderr()]).then(([stdout, stderr]) => ({
|
|
7
|
+
stdout,
|
|
8
|
+
stderr
|
|
9
|
+
}));
|
|
10
|
+
const toFinishedCommand = (command) => ({
|
|
11
|
+
id: command.cmdId,
|
|
12
|
+
exitCode: command.exitCode,
|
|
13
|
+
output: () => commandOutput(command)
|
|
14
|
+
});
|
|
15
|
+
const toDetachedCommand = (command) => ({
|
|
16
|
+
id: command.cmdId,
|
|
17
|
+
exitCode: command.exitCode,
|
|
18
|
+
wait: () => command.wait().then(toFinishedCommand),
|
|
19
|
+
kill: (signal) => command.kill(signal),
|
|
20
|
+
output: () => commandOutput(command)
|
|
21
|
+
});
|
|
22
|
+
const toHandle = (sandbox) => ({
|
|
23
|
+
name: sandbox.name,
|
|
24
|
+
writeFiles: (files) => sandbox.writeFiles(files.map((file) => ({
|
|
25
|
+
path: file.path,
|
|
26
|
+
content: file.content,
|
|
27
|
+
...file.mode === void 0 ? {} : { mode: file.mode }
|
|
28
|
+
}))),
|
|
29
|
+
runDetachedCommand: (input) => sandbox.runCommand({
|
|
30
|
+
cmd: input.cmd,
|
|
31
|
+
args: input.args === void 0 ? [] : [...input.args],
|
|
32
|
+
...input.cwd === void 0 ? {} : { cwd: input.cwd },
|
|
33
|
+
detached: true
|
|
34
|
+
}).then(toDetachedCommand),
|
|
35
|
+
getCommand: (id) => sandbox.getCommand(id).then(toDetachedCommand),
|
|
36
|
+
extendTimeout: (durationMs) => sandbox.extendTimeout(durationMs).then(() => void 0),
|
|
37
|
+
delete: () => sandbox.delete().then(() => void 0),
|
|
38
|
+
domain: (port) => sandbox.domain(port)
|
|
39
|
+
});
|
|
40
|
+
const envObject = (env) => env === void 0 ? void 0 : Object.fromEntries(Object.entries(env));
|
|
41
|
+
const retentionObject = (retention) => retention === void 0 ? void 0 : {
|
|
42
|
+
count: retention.count,
|
|
43
|
+
...retention.expirationMs === void 0 ? {} : { expiration: retention.expirationMs },
|
|
44
|
+
...retention.deleteEvicted === void 0 ? {} : { deleteEvicted: retention.deleteEvicted }
|
|
45
|
+
};
|
|
46
|
+
const commonCreateOptions = (input) => ({
|
|
47
|
+
name: input.name,
|
|
48
|
+
ports: [...input.ports],
|
|
49
|
+
timeout: input.timeoutMs,
|
|
50
|
+
resources: { vcpus: input.resources.vcpus },
|
|
51
|
+
env: envObject(input.env),
|
|
52
|
+
persistent: input.persistent,
|
|
53
|
+
networkPolicy: input.networkPolicy,
|
|
54
|
+
snapshotExpiration: input.snapshotExpirationMs,
|
|
55
|
+
keepLastSnapshots: retentionObject(input.keepLastSnapshots)
|
|
56
|
+
});
|
|
57
|
+
const gitSource = (source) => {
|
|
58
|
+
if (source.username === void 0 !== (source.password === void 0)) throw new Error("Vercel git source requires both username and password when using basic auth");
|
|
59
|
+
if (source.username !== void 0 && source.password !== void 0) return {
|
|
60
|
+
type: "git",
|
|
61
|
+
url: source.url,
|
|
62
|
+
username: source.username,
|
|
63
|
+
password: source.password,
|
|
64
|
+
...source.depth === void 0 ? {} : { depth: source.depth },
|
|
65
|
+
...source.revision === void 0 ? {} : { revision: source.revision }
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
type: "git",
|
|
69
|
+
url: source.url,
|
|
70
|
+
...source.depth === void 0 ? {} : { depth: source.depth },
|
|
71
|
+
...source.revision === void 0 ? {} : { revision: source.revision }
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
const createSandbox = (input) => {
|
|
75
|
+
const common = commonCreateOptions(input);
|
|
76
|
+
switch (input.source._tag) {
|
|
77
|
+
case "Empty": return Sandbox.create({
|
|
78
|
+
...common,
|
|
79
|
+
runtime: input.runtime
|
|
80
|
+
});
|
|
81
|
+
case "Snapshot": return Sandbox.create({
|
|
82
|
+
...common,
|
|
83
|
+
source: {
|
|
84
|
+
type: "snapshot",
|
|
85
|
+
snapshotId: input.source.snapshotId
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
case "Git": return Sandbox.create({
|
|
89
|
+
...common,
|
|
90
|
+
runtime: input.runtime,
|
|
91
|
+
source: gitSource(input.source)
|
|
92
|
+
});
|
|
93
|
+
case "Tarball": return Sandbox.create({
|
|
94
|
+
...common,
|
|
95
|
+
runtime: input.runtime,
|
|
96
|
+
source: {
|
|
97
|
+
type: "tarball",
|
|
98
|
+
url: input.source.url
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const VercelSandboxClientLive = Layer.succeed(VercelSandboxClient, VercelSandboxClient.of({
|
|
104
|
+
get: (input) => Sandbox.get({ name: input.name }).then(toHandle).catch((error) => {
|
|
105
|
+
if (isVercelMissingSandboxError(error)) return null;
|
|
106
|
+
throw error;
|
|
107
|
+
}),
|
|
108
|
+
create: (input) => createSandbox(input).then(toHandle)
|
|
109
|
+
}));
|
|
110
|
+
//#endregion
|
|
111
|
+
export { VercelSandboxClient, VercelSandboxClientLive, isVercelMissingSandboxError };
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.mjs","names":["VercelSdkSandbox"],"sources":["../../src/vercel/client.ts"],"sourcesContent":["import { Context, Layer } from 'effect'\nimport { APIError, Sandbox as VercelSdkSandbox, type Command, type CommandFinished, type NetworkPolicy } from '@vercel/sandbox'\nimport type { SandboxInitialSource, SandboxResources, SandboxSnapshotRetention } from '../model.ts'\n\nexport type VercelSandboxRuntime = 'node22' | 'node24' | 'node26' | 'python3.13'\nexport type VercelNetworkPolicy = NetworkPolicy\n\nexport type VercelCommandOutput = {\n readonly stdout: string\n readonly stderr: string\n}\n\nexport type VercelCommandSignal = 'SIGTERM' | 'SIGKILL'\n\nexport type VercelFinishedCommand = {\n readonly id: string\n readonly exitCode: number\n readonly output: () => Promise<VercelCommandOutput>\n}\n\nexport type VercelDetachedCommand = {\n readonly id: string\n readonly exitCode: number | null\n readonly wait: () => Promise<VercelFinishedCommand>\n readonly kill: (signal: VercelCommandSignal) => Promise<void>\n readonly output: () => Promise<VercelCommandOutput>\n}\n\nexport type VercelSandboxFile = {\n readonly path: string\n readonly content: string\n readonly mode?: number\n}\n\nexport type VercelRunCommandInput = {\n readonly cmd: string\n readonly args?: ReadonlyArray<string>\n readonly cwd?: string\n}\n\nexport type VercelSandboxCreateInput = {\n readonly name: string\n readonly source: SandboxInitialSource\n readonly ports: ReadonlyArray<number>\n readonly timeoutMs: number\n readonly resources: SandboxResources\n readonly runtime: VercelSandboxRuntime\n readonly env?: Readonly<Record<string, string>>\n readonly persistent: boolean\n readonly snapshotExpirationMs?: number\n readonly keepLastSnapshots?: SandboxSnapshotRetention\n readonly networkPolicy?: VercelNetworkPolicy\n}\n\nexport type VercelSandboxGetInput = {\n readonly name: string\n}\n\nexport type VercelSandboxHandle = {\n readonly name: string\n readonly writeFiles: (files: ReadonlyArray<VercelSandboxFile>) => Promise<void>\n readonly runDetachedCommand: (input: VercelRunCommandInput) => Promise<VercelDetachedCommand>\n readonly getCommand: (id: string) => Promise<VercelDetachedCommand>\n readonly extendTimeout: (durationMs: number) => Promise<void>\n readonly delete: () => Promise<void>\n readonly domain: (port: number) => string\n}\n\nexport type VercelSandboxClientApi = {\n readonly get: (input: VercelSandboxGetInput) => Promise<VercelSandboxHandle | null>\n readonly create: (input: VercelSandboxCreateInput) => Promise<VercelSandboxHandle>\n}\n\nexport class VercelSandboxClient extends Context.Service<VercelSandboxClient, VercelSandboxClientApi>()(\n '@yolk-sdk/sandbox/vercel/VercelSandboxClient'\n) {}\n\nexport const isVercelMissingSandboxError = (error: unknown) =>\n error instanceof APIError && (error.response.status === 404 || error.response.status === 410)\n\nconst commandOutput = (command: Command | CommandFinished): Promise<VercelCommandOutput> =>\n Promise.all([command.stdout(), command.stderr()]).then(([stdout, stderr]) => ({ stdout, stderr }))\n\nconst toFinishedCommand = (command: CommandFinished): VercelFinishedCommand => ({\n id: command.cmdId,\n exitCode: command.exitCode,\n output: () => commandOutput(command)\n})\n\nconst toDetachedCommand = (command: Command): VercelDetachedCommand => ({\n id: command.cmdId,\n exitCode: command.exitCode,\n wait: () => command.wait().then(toFinishedCommand),\n kill: signal => command.kill(signal),\n output: () => commandOutput(command)\n})\n\nconst toHandle = (sandbox: VercelSdkSandbox): VercelSandboxHandle => ({\n name: sandbox.name,\n writeFiles: files =>\n sandbox.writeFiles(files.map(file => ({\n path: file.path,\n content: file.content,\n ...(file.mode === undefined ? {} : { mode: file.mode })\n }))),\n runDetachedCommand: input =>\n sandbox.runCommand({\n cmd: input.cmd,\n args: input.args === undefined ? [] : [...input.args],\n ...(input.cwd === undefined ? {} : { cwd: input.cwd }),\n detached: true\n }).then(toDetachedCommand),\n getCommand: id => sandbox.getCommand(id).then(toDetachedCommand),\n extendTimeout: durationMs => sandbox.extendTimeout(durationMs).then(() => undefined),\n delete: () => sandbox.delete().then(() => undefined),\n domain: port => sandbox.domain(port)\n})\n\nconst envObject = (env?: Readonly<Record<string, string>>) =>\n env === undefined ? undefined : Object.fromEntries(Object.entries(env))\n\nconst retentionObject = (retention?: SandboxSnapshotRetention) =>\n retention === undefined\n ? undefined\n : {\n count: retention.count,\n ...(retention.expirationMs === undefined ? {} : { expiration: retention.expirationMs }),\n ...(retention.deleteEvicted === undefined ? {} : { deleteEvicted: retention.deleteEvicted })\n }\n\ntype AnonymousGitSource = {\n readonly type: 'git'\n readonly url: string\n readonly depth?: number\n readonly revision?: string\n}\n\ntype BasicAuthGitSource = AnonymousGitSource & {\n readonly username: string\n readonly password: string\n}\n\nconst commonCreateOptions = (input: VercelSandboxCreateInput) => ({\n name: input.name,\n ports: [...input.ports],\n timeout: input.timeoutMs,\n resources: { vcpus: input.resources.vcpus },\n env: envObject(input.env),\n persistent: input.persistent,\n networkPolicy: input.networkPolicy,\n snapshotExpiration: input.snapshotExpirationMs,\n keepLastSnapshots: retentionObject(input.keepLastSnapshots)\n})\n\nconst gitSource = (\n source: Extract<SandboxInitialSource, { readonly _tag: 'Git' }>\n): AnonymousGitSource | BasicAuthGitSource => {\n if ((source.username === undefined) !== (source.password === undefined)) {\n throw new Error('Vercel git source requires both username and password when using basic auth')\n }\n\n if (source.username !== undefined && source.password !== undefined) {\n return {\n type: 'git',\n url: source.url,\n username: source.username,\n password: source.password,\n ...(source.depth === undefined ? {} : { depth: source.depth }),\n ...(source.revision === undefined ? {} : { revision: source.revision })\n }\n }\n\n return {\n type: 'git',\n url: source.url,\n ...(source.depth === undefined ? {} : { depth: source.depth }),\n ...(source.revision === undefined ? {} : { revision: source.revision })\n }\n}\n\nconst createSandbox = (input: VercelSandboxCreateInput) => {\n const common = commonCreateOptions(input)\n\n switch (input.source._tag) {\n case 'Empty':\n return VercelSdkSandbox.create({\n ...common,\n runtime: input.runtime\n })\n case 'Snapshot':\n return VercelSdkSandbox.create({\n ...common,\n source: { type: 'snapshot', snapshotId: input.source.snapshotId }\n })\n case 'Git':\n return VercelSdkSandbox.create({\n ...common,\n runtime: input.runtime,\n source: gitSource(input.source)\n })\n case 'Tarball':\n return VercelSdkSandbox.create({\n ...common,\n runtime: input.runtime,\n source: { type: 'tarball', url: input.source.url }\n })\n }\n}\n\nexport const VercelSandboxClientLive = Layer.succeed(\n VercelSandboxClient,\n VercelSandboxClient.of({\n get: input =>\n VercelSdkSandbox.get({ name: input.name }).then(toHandle).catch(error => {\n if (isVercelMissingSandboxError(error)) {\n return null\n }\n\n throw error\n }),\n create: input => createSandbox(input).then(toHandle)\n })\n)\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { VercelCommandOutput, VercelCommandSignal, VercelDetachedCommand, VercelFinishedCommand, VercelNetworkPolicy, VercelRunCommandInput, VercelSandboxClient, VercelSandboxClientApi, VercelSandboxClientLive, VercelSandboxCreateInput, VercelSandboxFile, VercelSandboxGetInput, VercelSandboxHandle, VercelSandboxRuntime, isVercelMissingSandboxError } from "./client.mjs";
|
|
2
|
+
import { VercelSandboxLayerConfig, makeVercelSandboxLayer, makeVercelSandboxLayerWithClient } from "./layer.mjs";
|
|
3
|
+
export { type VercelCommandOutput, type VercelCommandSignal, type VercelDetachedCommand, type VercelFinishedCommand, type VercelNetworkPolicy, type VercelRunCommandInput, VercelSandboxClient, type VercelSandboxClientApi, VercelSandboxClientLive, type VercelSandboxCreateInput, type VercelSandboxFile, type VercelSandboxGetInput, type VercelSandboxHandle, type VercelSandboxLayerConfig, type VercelSandboxRuntime, isVercelMissingSandboxError, makeVercelSandboxLayer, makeVercelSandboxLayerWithClient };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { VercelSandboxClient, VercelSandboxClientLive, isVercelMissingSandboxError } from "./client.mjs";
|
|
2
|
+
import { makeVercelSandboxLayer, makeVercelSandboxLayerWithClient } from "./layer.mjs";
|
|
3
|
+
export { VercelSandboxClient, VercelSandboxClientLive, isVercelMissingSandboxError, makeVercelSandboxLayer, makeVercelSandboxLayerWithClient };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SandboxInitialSource, SandboxLifecycle, SandboxResources } from "../model.mjs";
|
|
2
|
+
import { Sandbox } from "../service.mjs";
|
|
3
|
+
import { SandboxStateStore } from "../state-store.mjs";
|
|
4
|
+
import { VercelNetworkPolicy, VercelSandboxClient, VercelSandboxRuntime } from "./client.mjs";
|
|
5
|
+
import { Layer } from "effect";
|
|
6
|
+
|
|
7
|
+
//#region src/vercel/layer.d.ts
|
|
8
|
+
type VercelSandboxLayerConfig = {
|
|
9
|
+
readonly sandboxSessionId: string;
|
|
10
|
+
readonly lifecycle?: SandboxLifecycle;
|
|
11
|
+
readonly source?: SandboxInitialSource;
|
|
12
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
13
|
+
readonly ports?: ReadonlyArray<number>;
|
|
14
|
+
readonly resources?: SandboxResources;
|
|
15
|
+
readonly runtime?: VercelSandboxRuntime;
|
|
16
|
+
readonly networkPolicy?: VercelNetworkPolicy;
|
|
17
|
+
readonly workspaceRoot?: string;
|
|
18
|
+
};
|
|
19
|
+
declare const makeVercelSandboxLayerWithClient: (config: VercelSandboxLayerConfig) => Layer.Layer<Sandbox, never, VercelSandboxClient | SandboxStateStore>;
|
|
20
|
+
declare const makeVercelSandboxLayer: (config: VercelSandboxLayerConfig) => Layer.Layer<Sandbox, never, SandboxStateStore>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { VercelSandboxLayerConfig, makeVercelSandboxLayer, makeVercelSandboxLayerWithClient };
|
|
23
|
+
//# sourceMappingURL=layer.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer.d.mts","names":[],"sources":["../../src/vercel/layer.ts"],"mappings":";;;;;;;KAuCY,wBAAA;EAAA,SACD,gBAAA;EAAA,SACA,SAAA,GAAY,gBAAA;EAAA,SACZ,MAAA,GAAS,oBAAA;EAAA,SACT,GAAA,GAAM,QAAA,CAAS,MAAA;EAAA,SACf,KAAA,GAAQ,aAAA;EAAA,SACR,SAAA,GAAY,gBAAA;EAAA,SACZ,OAAA,GAAU,oBAAA;EAAA,SACV,aAAA,GAAgB,mBAAA;EAAA,SAChB,aAAA;AAAA;AAAA,cAoLE,gCAAA,GAAoC,MAAA,EAAQ,wBAAA,KAAwB,KAAA,CAAA,KAAA,CAAA,OAAA,SAAA,mBAAA,GAAA,iBAAA;AAAA,cAsKpE,sBAAA,GAA0B,MAAA,EAAQ,wBAAA,KAAwB,KAAA,CAAA,KAAA,CAAA,OAAA,SAAA,iBAAA"}
|