@alienplatform/sdk 1.14.1 → 2.0.1
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/dist/dist.js +371 -275
- package/dist/index.d.ts +22 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -14356
- package/dist/native.d.ts +26 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +2 -0
- package/dist/worker-runtime/channel.d.ts +25 -0
- package/dist/worker-runtime/channel.d.ts.map +1 -0
- package/dist/worker-runtime/errors.d.ts +79 -0
- package/dist/worker-runtime/errors.d.ts.map +1 -0
- package/dist/worker-runtime/event-loop.d.ts +43 -0
- package/dist/worker-runtime/event-loop.d.ts.map +1 -0
- package/dist/{generated → worker-runtime/generated}/control.d.ts +15 -15
- package/dist/worker-runtime/generated/control.d.ts.map +1 -0
- package/dist/worker-runtime/generated/google/protobuf/duration.d.ts.map +1 -0
- package/dist/worker-runtime/generated/google/protobuf/timestamp.d.ts.map +1 -0
- package/dist/{generated → worker-runtime/generated}/wait_until.d.ts +29 -29
- package/dist/worker-runtime/generated/wait_until.d.ts.map +1 -0
- package/dist/worker-runtime/grpc-utils.d.ts +23 -0
- package/dist/worker-runtime/grpc-utils.d.ts.map +1 -0
- package/dist/worker-runtime/index.d.ts +33 -0
- package/dist/worker-runtime/index.d.ts.map +1 -0
- package/dist/{src.js → worker-runtime/index.js} +9370 -4035
- package/dist/worker-runtime/registry.d.ts +169 -0
- package/dist/worker-runtime/registry.d.ts.map +1 -0
- package/dist/worker-runtime/service-definitions.d.ts +12 -0
- package/dist/worker-runtime/service-definitions.d.ts.map +1 -0
- package/dist/worker-runtime/wait-until-manager.d.ts +34 -0
- package/dist/worker-runtime/wait-until-manager.d.ts.map +1 -0
- package/package.json +18 -38
- package/.turbo/turbo-build.log +0 -30
- package/AGENTS.md +0 -70
- package/dist/bearerTokenAuthenticationPolicy.js +0 -3028
- package/dist/bindings/artifact-registry.d.ts +0 -88
- package/dist/bindings/artifact-registry.d.ts.map +0 -1
- package/dist/bindings/build.d.ts +0 -67
- package/dist/bindings/build.d.ts.map +0 -1
- package/dist/bindings/index.d.ts +0 -13
- package/dist/bindings/index.d.ts.map +0 -1
- package/dist/bindings/kv.d.ts +0 -113
- package/dist/bindings/kv.d.ts.map +0 -1
- package/dist/bindings/postgres.d.ts +0 -90
- package/dist/bindings/postgres.d.ts.map +0 -1
- package/dist/bindings/postgres.test.d.ts +0 -2
- package/dist/bindings/postgres.test.d.ts.map +0 -1
- package/dist/bindings/queue.d.ts +0 -81
- package/dist/bindings/queue.d.ts.map +0 -1
- package/dist/bindings/service-account.d.ts +0 -46
- package/dist/bindings/service-account.d.ts.map +0 -1
- package/dist/bindings/storage.d.ts +0 -164
- package/dist/bindings/storage.d.ts.map +0 -1
- package/dist/bindings/vault.d.ts +0 -65
- package/dist/bindings/vault.d.ts.map +0 -1
- package/dist/bindings/worker.d.ts +0 -72
- package/dist/bindings/worker.d.ts.map +0 -1
- package/dist/channel.d.ts +0 -39
- package/dist/channel.d.ts.map +0 -1
- package/dist/checksum.js +0 -6176
- package/dist/commands/client.d.ts +0 -47
- package/dist/commands/client.d.ts.map +0 -1
- package/dist/commands/errors.d.ts +0 -198
- package/dist/commands/errors.d.ts.map +0 -1
- package/dist/commands/index.d.ts +0 -23
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -387
- package/dist/commands/types.d.ts +0 -40
- package/dist/commands/types.d.ts.map +0 -1
- package/dist/commands.d.ts +0 -55
- package/dist/commands.d.ts.map +0 -1
- package/dist/context.d.ts +0 -182
- package/dist/context.d.ts.map +0 -1
- package/dist/dist-cjs.js +0 -15258
- package/dist/dist2.js +0 -1239
- package/dist/errors.d.ts +0 -359
- package/dist/errors.d.ts.map +0 -1
- package/dist/es5.js +0 -1720
- package/dist/esm.js +0 -18068
- package/dist/esm2.js +0 -3166
- package/dist/event-streams.js +0 -770
- package/dist/events.d.ts +0 -163
- package/dist/events.d.ts.map +0 -1
- package/dist/generated/artifact_registry.d.ts +0 -302
- package/dist/generated/artifact_registry.d.ts.map +0 -1
- package/dist/generated/build.d.ts +0 -184
- package/dist/generated/build.d.ts.map +0 -1
- package/dist/generated/container.d.ts +0 -101
- package/dist/generated/container.d.ts.map +0 -1
- package/dist/generated/control.d.ts.map +0 -1
- package/dist/generated/google/protobuf/duration.d.ts.map +0 -1
- package/dist/generated/google/protobuf/timestamp.d.ts.map +0 -1
- package/dist/generated/kv.d.ts +0 -182
- package/dist/generated/kv.d.ts.map +0 -1
- package/dist/generated/queue.d.ts +0 -127
- package/dist/generated/queue.d.ts.map +0 -1
- package/dist/generated/service_account.d.ts +0 -112
- package/dist/generated/service_account.d.ts.map +0 -1
- package/dist/generated/storage.d.ts +0 -784
- package/dist/generated/storage.d.ts.map +0 -1
- package/dist/generated/vault.d.ts +0 -107
- package/dist/generated/vault.d.ts.map +0 -1
- package/dist/generated/wait_until.d.ts.map +0 -1
- package/dist/generated/worker.d.ts +0 -107
- package/dist/generated/worker.d.ts.map +0 -1
- package/dist/global.d.ts +0 -208
- package/dist/global.d.ts.map +0 -1
- package/dist/grpc-utils.d.ts +0 -25
- package/dist/grpc-utils.d.ts.map +0 -1
- package/dist/jws.js +0 -611
- package/dist/open.js +0 -461
- package/dist/rolldown-runtime.js +0 -44
- package/dist/src2.js +0 -114032
- package/dist/types.d.ts +0 -337
- package/dist/types.d.ts.map +0 -1
- package/dist/wait-until.d.ts +0 -115
- package/dist/wait-until.d.ts.map +0 -1
- package/scripts/generate-proto.sh +0 -46
- package/src/bindings/AGENTS.md +0 -105
- package/src/bindings/artifact-registry.ts +0 -317
- package/src/bindings/build.ts +0 -195
- package/src/bindings/index.ts +0 -13
- package/src/bindings/kv.ts +0 -240
- package/src/bindings/postgres.test.ts +0 -17
- package/src/bindings/postgres.ts +0 -446
- package/src/bindings/queue.ts +0 -191
- package/src/bindings/service-account.ts +0 -113
- package/src/bindings/storage.ts +0 -536
- package/src/bindings/vault.ts +0 -133
- package/src/bindings/worker.ts +0 -164
- package/src/channel.ts +0 -102
- package/src/commands/client.ts +0 -446
- package/src/commands/errors.ts +0 -126
- package/src/commands/index.ts +0 -41
- package/src/commands/types.ts +0 -52
- package/src/commands.ts +0 -76
- package/src/context.ts +0 -368
- package/src/errors.ts +0 -280
- package/src/events.ts +0 -511
- package/src/generated/artifact_registry.ts +0 -2096
- package/src/generated/build.ts +0 -1311
- package/src/generated/container.ts +0 -503
- package/src/generated/control.ts +0 -2018
- package/src/generated/google/protobuf/duration.ts +0 -196
- package/src/generated/google/protobuf/timestamp.ts +0 -226
- package/src/generated/kv.ts +0 -1169
- package/src/generated/queue.ts +0 -753
- package/src/generated/service_account.ts +0 -814
- package/src/generated/storage.ts +0 -3820
- package/src/generated/vault.ts +0 -543
- package/src/generated/wait_until.ts +0 -829
- package/src/generated/worker.ts +0 -759
- package/src/global.ts +0 -287
- package/src/grpc-utils.ts +0 -159
- package/src/index.ts +0 -160
- package/src/types.ts +0 -397
- package/src/wait-until.ts +0 -273
- package/tsconfig.json +0 -8
- package/tsdown.config.ts +0 -17
- /package/dist/{generated → worker-runtime/generated}/google/protobuf/duration.d.ts +0 -0
- /package/dist/{generated → worker-runtime/generated}/google/protobuf/timestamp.d.ts +0 -0
package/src/commands/errors.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Commands Client Error Definitions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { defineError } from "@alienplatform/core"
|
|
6
|
-
import { z } from "zod/v4"
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Error thrown when command creation fails.
|
|
10
|
-
*/
|
|
11
|
-
export const CommandCreationFailedError = defineError({
|
|
12
|
-
code: "COMMAND_CREATION_FAILED",
|
|
13
|
-
context: z.object({
|
|
14
|
-
deploymentId: z.string(),
|
|
15
|
-
command: z.string(),
|
|
16
|
-
reason: z.string(),
|
|
17
|
-
}),
|
|
18
|
-
message: ({ deploymentId, command, reason }) =>
|
|
19
|
-
`Failed to create command '${command}' for deployment '${deploymentId}': ${reason}`,
|
|
20
|
-
retryable: false,
|
|
21
|
-
internal: false,
|
|
22
|
-
httpStatusCode: 500,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Error thrown when command execution times out.
|
|
27
|
-
*/
|
|
28
|
-
export const CommandTimeoutError = defineError({
|
|
29
|
-
code: "COMMAND_TIMEOUT",
|
|
30
|
-
context: z.object({
|
|
31
|
-
commandId: z.string(),
|
|
32
|
-
command: z.string(),
|
|
33
|
-
timeoutMs: z.number(),
|
|
34
|
-
lastState: z.string(),
|
|
35
|
-
}),
|
|
36
|
-
message: ({ command, timeoutMs, lastState }) =>
|
|
37
|
-
`Command '${command}' timed out after ${timeoutMs}ms (last state: ${lastState})`,
|
|
38
|
-
retryable: true,
|
|
39
|
-
internal: false,
|
|
40
|
-
httpStatusCode: 504,
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Error thrown when the deployment returns an error response.
|
|
45
|
-
*/
|
|
46
|
-
export const DeploymentCommandError = defineError({
|
|
47
|
-
code: "DEPLOYMENT_COMMAND_ERROR",
|
|
48
|
-
context: z.object({
|
|
49
|
-
commandId: z.string(),
|
|
50
|
-
command: z.string(),
|
|
51
|
-
errorCode: z.string(),
|
|
52
|
-
errorMessage: z.string(),
|
|
53
|
-
errorDetails: z.string().optional(),
|
|
54
|
-
}),
|
|
55
|
-
message: ({ command, errorCode, errorMessage }) =>
|
|
56
|
-
`Deployment command '${command}' failed: [${errorCode}] ${errorMessage}`,
|
|
57
|
-
retryable: false,
|
|
58
|
-
internal: false,
|
|
59
|
-
httpStatusCode: 500,
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Error thrown when command expires before completion.
|
|
64
|
-
*/
|
|
65
|
-
export const CommandExpiredError = defineError({
|
|
66
|
-
code: "COMMAND_EXPIRED",
|
|
67
|
-
context: z.object({
|
|
68
|
-
commandId: z.string(),
|
|
69
|
-
command: z.string(),
|
|
70
|
-
}),
|
|
71
|
-
message: ({ command }) => `Command '${command}' expired before completion`,
|
|
72
|
-
retryable: false,
|
|
73
|
-
internal: false,
|
|
74
|
-
httpStatusCode: 410,
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Error thrown when storage upload/download fails.
|
|
79
|
-
*/
|
|
80
|
-
export const StorageOperationFailedError = defineError({
|
|
81
|
-
code: "STORAGE_OPERATION_FAILED",
|
|
82
|
-
context: z.object({
|
|
83
|
-
operation: z.enum(["upload", "download"]),
|
|
84
|
-
url: z.string(),
|
|
85
|
-
reason: z.string(),
|
|
86
|
-
}),
|
|
87
|
-
message: ({ operation, reason }) => `Storage ${operation} failed: ${reason}`,
|
|
88
|
-
retryable: true,
|
|
89
|
-
internal: false,
|
|
90
|
-
httpStatusCode: 500,
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Error thrown when response decoding fails.
|
|
95
|
-
*/
|
|
96
|
-
export const ResponseDecodingFailedError = defineError({
|
|
97
|
-
code: "RESPONSE_DECODING_FAILED",
|
|
98
|
-
context: z.object({
|
|
99
|
-
commandId: z.string(),
|
|
100
|
-
command: z.string(),
|
|
101
|
-
reason: z.string(),
|
|
102
|
-
}),
|
|
103
|
-
message: ({ command, reason }) => `Failed to decode response for command '${command}': ${reason}`,
|
|
104
|
-
retryable: false,
|
|
105
|
-
internal: false,
|
|
106
|
-
httpStatusCode: 500,
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Error thrown when Manager returns an HTTP error.
|
|
111
|
-
*/
|
|
112
|
-
export const ManagerHttpError = defineError({
|
|
113
|
-
code: "MANAGER_HTTP_ERROR",
|
|
114
|
-
context: z.object({
|
|
115
|
-
method: z.string(),
|
|
116
|
-
url: z.string(),
|
|
117
|
-
status: z.number(),
|
|
118
|
-
statusText: z.string(),
|
|
119
|
-
body: z.string().optional(),
|
|
120
|
-
}),
|
|
121
|
-
message: ({ method, url, status, statusText }) =>
|
|
122
|
-
`Manager ${method} ${url} failed: ${status} ${statusText}`,
|
|
123
|
-
retryable: false,
|
|
124
|
-
internal: false,
|
|
125
|
-
httpStatusCode: 500,
|
|
126
|
-
})
|
package/src/commands/index.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Commands client — invoke commands on remote Alien deployments.
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* ```typescript
|
|
6
|
-
* import { CommandsClient } from "@alienplatform/sdk/commands"
|
|
7
|
-
*
|
|
8
|
-
* const commands = new CommandsClient({
|
|
9
|
-
* managerUrl: "https://manager.example.com",
|
|
10
|
-
* deploymentId: "deployment_123",
|
|
11
|
-
* token: "bearer_token",
|
|
12
|
-
* })
|
|
13
|
-
*
|
|
14
|
-
* const result = await commands.invoke("generate-report", {
|
|
15
|
-
* startDate: "2024-01-01",
|
|
16
|
-
* endDate: "2024-01-31",
|
|
17
|
-
* })
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
export { CommandsClient } from "./client.js"
|
|
22
|
-
export type {
|
|
23
|
-
CommandsClientConfig,
|
|
24
|
-
BodySpec,
|
|
25
|
-
CommandResponse,
|
|
26
|
-
CommandState,
|
|
27
|
-
CommandStatusResponse,
|
|
28
|
-
CreateCommandResponse,
|
|
29
|
-
InvokeOptions,
|
|
30
|
-
PresignedRequest,
|
|
31
|
-
StorageUpload,
|
|
32
|
-
} from "./types.js"
|
|
33
|
-
export {
|
|
34
|
-
DeploymentCommandError,
|
|
35
|
-
ManagerHttpError,
|
|
36
|
-
CommandCreationFailedError,
|
|
37
|
-
CommandExpiredError,
|
|
38
|
-
CommandTimeoutError,
|
|
39
|
-
ResponseDecodingFailedError,
|
|
40
|
-
StorageOperationFailedError,
|
|
41
|
-
} from "./errors.js"
|
package/src/commands/types.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Commands Protocol Types
|
|
3
|
-
*
|
|
4
|
-
* Core command types are re-exported from @alienplatform/core,
|
|
5
|
-
* which auto-generates them from the Rust implementation.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
// Re-export core command types from @alienplatform/core
|
|
9
|
-
export type {
|
|
10
|
-
BodySpec,
|
|
11
|
-
CommandState,
|
|
12
|
-
CommandResponse,
|
|
13
|
-
CommandStatusResponse,
|
|
14
|
-
CreateCommandResponse,
|
|
15
|
-
PresignedRequest,
|
|
16
|
-
PresignedRequestBackend,
|
|
17
|
-
StorageUpload,
|
|
18
|
-
} from "@alienplatform/core"
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Options for invoking a command
|
|
22
|
-
*/
|
|
23
|
-
export interface InvokeOptions {
|
|
24
|
-
/** Timeout in milliseconds (default: 60000) */
|
|
25
|
-
timeout?: number
|
|
26
|
-
/** Optional deadline for command completion */
|
|
27
|
-
deadline?: Date
|
|
28
|
-
/** Optional idempotency key */
|
|
29
|
-
idempotencyKey?: string
|
|
30
|
-
/** Polling interval in milliseconds (default: 500) */
|
|
31
|
-
pollInterval?: number
|
|
32
|
-
/** Maximum polling interval in milliseconds (default: 5000) */
|
|
33
|
-
maxPollInterval?: number
|
|
34
|
-
/** Polling backoff multiplier (default: 1.5) */
|
|
35
|
-
pollBackoff?: number
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Configuration for CommandsClient
|
|
40
|
-
*/
|
|
41
|
-
export interface CommandsClientConfig {
|
|
42
|
-
/** Manager URL (e.g., "https://manager.example.com") */
|
|
43
|
-
managerUrl: string
|
|
44
|
-
/** Deployment ID to invoke commands on */
|
|
45
|
-
deploymentId: string
|
|
46
|
-
/** Authentication token (deployment token or workspace token) */
|
|
47
|
-
token: string
|
|
48
|
-
/** Default timeout in milliseconds (default: 60000) */
|
|
49
|
-
timeout?: number
|
|
50
|
-
/** Allow reading local files for storage responses (default: false, only for local dev) */
|
|
51
|
-
allowLocalStorage?: boolean
|
|
52
|
-
}
|
package/src/commands.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command handling for Alien bindings.
|
|
3
|
-
*
|
|
4
|
-
* Provides command registration and execution.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Command definition.
|
|
9
|
-
*/
|
|
10
|
-
export interface CommandDefinition {
|
|
11
|
-
/** Command name */
|
|
12
|
-
name: string
|
|
13
|
-
/** Handler function that receives params and returns a result */
|
|
14
|
-
handler: (params: unknown) => Promise<unknown>
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Internal storage for commands
|
|
18
|
-
const commands: Map<string, CommandDefinition> = new Map()
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Register a command.
|
|
22
|
-
*
|
|
23
|
-
* @param name - Command name
|
|
24
|
-
* @param handler - Command handler function that receives params and returns a result
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```typescript
|
|
28
|
-
* import { command } from "@alienplatform/sdk"
|
|
29
|
-
*
|
|
30
|
-
* command("echo", async ({ message }: { message: string }) => {
|
|
31
|
-
* return {
|
|
32
|
-
* message,
|
|
33
|
-
* timestamp: new Date().toISOString(),
|
|
34
|
-
* }
|
|
35
|
-
* })
|
|
36
|
-
*
|
|
37
|
-
* command("process-data", async ({ data }: { data: string[] }) => {
|
|
38
|
-
* const result = await processData(data)
|
|
39
|
-
* return { processed: result.length }
|
|
40
|
-
* })
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
export function command<TParams = unknown, TResult = unknown>(
|
|
44
|
-
name: string,
|
|
45
|
-
handler: (params: TParams) => Promise<TResult>,
|
|
46
|
-
): void {
|
|
47
|
-
commands.set(name, { name, handler: handler as (params: unknown) => Promise<unknown> })
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Get all registered commands.
|
|
52
|
-
*
|
|
53
|
-
* @internal
|
|
54
|
-
*/
|
|
55
|
-
export function getCommands(): Map<string, CommandDefinition> {
|
|
56
|
-
return commands
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Execute a command by name.
|
|
61
|
-
*
|
|
62
|
-
* @param name - Command name to execute
|
|
63
|
-
* @param params - Command parameters
|
|
64
|
-
* @returns Command result
|
|
65
|
-
*
|
|
66
|
-
* @internal
|
|
67
|
-
*/
|
|
68
|
-
export async function runCommand(name: string, params: unknown): Promise<unknown> {
|
|
69
|
-
const cmd = commands.get(name)
|
|
70
|
-
|
|
71
|
-
if (!cmd) {
|
|
72
|
-
throw new Error(`Unknown command: ${name}. Available: ${[...commands.keys()].join(", ")}`)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return await cmd.handler(params)
|
|
76
|
-
}
|
package/src/context.ts
DELETED
|
@@ -1,368 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AlienContext - Main entry point for Alien bindings.
|
|
3
|
-
*
|
|
4
|
-
* Provides access to all bindings and control plane functionality.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { StorageEvent } from "@alienplatform/core"
|
|
8
|
-
import { AlienError } from "@alienplatform/core"
|
|
9
|
-
import type { Channel } from "nice-grpc"
|
|
10
|
-
import { createClient } from "nice-grpc"
|
|
11
|
-
import { ArtifactRegistry } from "./bindings/artifact-registry.js"
|
|
12
|
-
import { Build } from "./bindings/build.js"
|
|
13
|
-
import { Kv } from "./bindings/kv.js"
|
|
14
|
-
import { Queue } from "./bindings/queue.js"
|
|
15
|
-
import { ServiceAccount } from "./bindings/service-account.js"
|
|
16
|
-
import { Storage } from "./bindings/storage.js"
|
|
17
|
-
import { Vault } from "./bindings/vault.js"
|
|
18
|
-
import { WorkerBinding } from "./bindings/worker.js"
|
|
19
|
-
import { createGrpcChannel, getOrCreateChannel } from "./channel.js"
|
|
20
|
-
import { command } from "./commands.js"
|
|
21
|
-
import { InvalidBindingConfigError } from "./errors.js"
|
|
22
|
-
import {
|
|
23
|
-
type CronEvent,
|
|
24
|
-
EventLoop,
|
|
25
|
-
type QueueMessageEvent,
|
|
26
|
-
onCronEvent,
|
|
27
|
-
onQueueMessage,
|
|
28
|
-
onStorageEvent,
|
|
29
|
-
} from "./events.js"
|
|
30
|
-
import { ControlServiceDefinition } from "./generated/control.js"
|
|
31
|
-
import { wrapGrpcCall } from "./grpc-utils.js"
|
|
32
|
-
import type { AlienBindingsConfig, AlienBindingsProvider } from "./types.js"
|
|
33
|
-
import { type WaitUntilManager, initWaitUntilManager, waitUntil } from "./wait-until.js"
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Instance ID for this worker process.
|
|
37
|
-
*/
|
|
38
|
-
function generateInstanceId(): string {
|
|
39
|
-
return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* AlienContext provides the main entry point for accessing Alien bindings
|
|
44
|
-
* and control plane functionality.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* ```typescript
|
|
48
|
-
* import { AlienContext } from "@alienplatform/sdk"
|
|
49
|
-
*
|
|
50
|
-
* // Create context from environment
|
|
51
|
-
* const ctx = AlienContext.fromEnv()
|
|
52
|
-
*
|
|
53
|
-
* // Access bindings
|
|
54
|
-
* const bucket = ctx.storage("my-bucket")
|
|
55
|
-
* await bucket.put("hello.txt", "Hello, World!")
|
|
56
|
-
*
|
|
57
|
-
* // Register event handlers
|
|
58
|
-
* ctx.onStorageEvent("uploads", async (event) => {
|
|
59
|
-
* console.log("File uploaded:", event.key)
|
|
60
|
-
* })
|
|
61
|
-
*
|
|
62
|
-
* // Start the runtime
|
|
63
|
-
* await ctx.run()
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export class AlienContext implements AlienBindingsProvider {
|
|
67
|
-
private readonly channel: Channel
|
|
68
|
-
private readonly instanceId: string
|
|
69
|
-
private readonly bindingCache = new Map<string, unknown>()
|
|
70
|
-
private eventLoop: EventLoop | undefined
|
|
71
|
-
private waitUntilManager: WaitUntilManager | undefined
|
|
72
|
-
|
|
73
|
-
private constructor(channel: Channel, instanceId?: string) {
|
|
74
|
-
this.channel = channel
|
|
75
|
-
this.instanceId = instanceId ?? generateInstanceId()
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Create a context from environment variables.
|
|
80
|
-
*
|
|
81
|
-
* Reads the ALIEN_BINDINGS_GRPC_ADDRESS environment variable.
|
|
82
|
-
*/
|
|
83
|
-
static async fromEnv(): Promise<AlienContext> {
|
|
84
|
-
const address = process.env.ALIEN_BINDINGS_GRPC_ADDRESS
|
|
85
|
-
|
|
86
|
-
if (!address) {
|
|
87
|
-
throw new AlienError(
|
|
88
|
-
InvalidBindingConfigError.create({
|
|
89
|
-
message: "ALIEN_BINDINGS_GRPC_ADDRESS environment variable is not set",
|
|
90
|
-
suggestion:
|
|
91
|
-
"Make sure you're running inside an Alien worker or set the variable manually",
|
|
92
|
-
}),
|
|
93
|
-
)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const channel = await getOrCreateChannel(address)
|
|
97
|
-
return new AlienContext(channel)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Create a context with explicit configuration.
|
|
102
|
-
*/
|
|
103
|
-
static async create(config: AlienBindingsConfig): Promise<AlienContext> {
|
|
104
|
-
if (!config.grpcAddress) {
|
|
105
|
-
throw new AlienError(
|
|
106
|
-
InvalidBindingConfigError.create({
|
|
107
|
-
message: "gRPC address is required",
|
|
108
|
-
suggestion: "Provide grpcAddress in the config",
|
|
109
|
-
}),
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const channel = await createGrpcChannel(config.grpcAddress)
|
|
114
|
-
return new AlienContext(channel)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Create a context for connecting to a remote agent.
|
|
119
|
-
*
|
|
120
|
-
* @param address - gRPC address of the remote agent
|
|
121
|
-
*/
|
|
122
|
-
// TODO: Implement remote agent connection
|
|
123
|
-
static async forRemoteAgent(address: string): Promise<AlienContext> {
|
|
124
|
-
const channel = await createGrpcChannel(address)
|
|
125
|
-
return new AlienContext(channel)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Get or create a cached binding instance.
|
|
130
|
-
*/
|
|
131
|
-
private getBinding<T>(key: string, factory: () => T): T {
|
|
132
|
-
let binding = this.bindingCache.get(key) as T | undefined
|
|
133
|
-
if (!binding) {
|
|
134
|
-
binding = factory()
|
|
135
|
-
this.bindingCache.set(key, binding)
|
|
136
|
-
}
|
|
137
|
-
return binding
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// ============================================================================
|
|
141
|
-
// Binding Accessors
|
|
142
|
-
// ============================================================================
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Get a storage binding.
|
|
146
|
-
*
|
|
147
|
-
* @param name - Binding name
|
|
148
|
-
* @returns Storage binding instance
|
|
149
|
-
*/
|
|
150
|
-
storage(name: string): Storage {
|
|
151
|
-
return this.getBinding(`storage:${name}`, () => new Storage(this.channel, name))
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Get a KV binding.
|
|
156
|
-
*
|
|
157
|
-
* @param name - Binding name
|
|
158
|
-
* @returns KV binding instance
|
|
159
|
-
*/
|
|
160
|
-
kv(name: string): Kv {
|
|
161
|
-
return this.getBinding(`kv:${name}`, () => new Kv(this.channel, name))
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Get a queue binding.
|
|
166
|
-
*
|
|
167
|
-
* @param name - Binding name
|
|
168
|
-
* @returns Queue binding instance
|
|
169
|
-
*/
|
|
170
|
-
queue(name: string): Queue {
|
|
171
|
-
return this.getBinding(`queue:${name}`, () => new Queue(this.channel, name))
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Get a vault binding.
|
|
176
|
-
*
|
|
177
|
-
* @param name - Binding name
|
|
178
|
-
* @returns Vault binding instance
|
|
179
|
-
*/
|
|
180
|
-
vault(name: string): Vault {
|
|
181
|
-
return this.getBinding(`vault:${name}`, () => new Vault(this.channel, name))
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Get a build binding.
|
|
186
|
-
*
|
|
187
|
-
* @param name - Binding name
|
|
188
|
-
* @returns Build binding instance
|
|
189
|
-
*/
|
|
190
|
-
build(name: string): Build {
|
|
191
|
-
return this.getBinding(`build:${name}`, () => new Build(this.channel, name))
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Get an artifact registry binding.
|
|
196
|
-
*
|
|
197
|
-
* @param name - Binding name
|
|
198
|
-
* @returns ArtifactRegistry binding instance
|
|
199
|
-
*/
|
|
200
|
-
artifactRegistry(name: string): ArtifactRegistry {
|
|
201
|
-
return this.getBinding(
|
|
202
|
-
`artifact-registry:${name}`,
|
|
203
|
-
() => new ArtifactRegistry(this.channel, name),
|
|
204
|
-
)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Get a worker binding.
|
|
209
|
-
*
|
|
210
|
-
* @param name - Binding name
|
|
211
|
-
* @returns Worker binding instance
|
|
212
|
-
*/
|
|
213
|
-
worker(name: string): WorkerBinding {
|
|
214
|
-
return this.getBinding(`worker:${name}`, () => new WorkerBinding(this.channel, name))
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Get a service account binding.
|
|
219
|
-
*
|
|
220
|
-
* @param name - Binding name
|
|
221
|
-
* @returns ServiceAccount binding instance
|
|
222
|
-
*/
|
|
223
|
-
serviceAccount(name: string): ServiceAccount {
|
|
224
|
-
return this.getBinding(`service-account:${name}`, () => new ServiceAccount(this.channel, name))
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// ============================================================================
|
|
228
|
-
// Event Handlers
|
|
229
|
-
// ============================================================================
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Register a storage event handler.
|
|
233
|
-
*
|
|
234
|
-
* @param bucket - Bucket name
|
|
235
|
-
* @param handler - Event handler
|
|
236
|
-
* @param options - Handler options
|
|
237
|
-
* @returns Unsubscribe function
|
|
238
|
-
*/
|
|
239
|
-
onStorageEvent(
|
|
240
|
-
bucket: string,
|
|
241
|
-
handler: (event: StorageEvent) => Promise<void>,
|
|
242
|
-
options?: { prefix?: string },
|
|
243
|
-
): () => void {
|
|
244
|
-
return onStorageEvent(bucket, handler, options)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Register a cron event handler.
|
|
249
|
-
*
|
|
250
|
-
* @param schedule - Cron schedule expression
|
|
251
|
-
* @param handler - Event handler
|
|
252
|
-
* @returns Unsubscribe function
|
|
253
|
-
*/
|
|
254
|
-
onCronEvent(schedule: string, handler: (event: CronEvent) => Promise<void>): () => void {
|
|
255
|
-
return onCronEvent(schedule, handler)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Register a queue message handler.
|
|
260
|
-
*
|
|
261
|
-
* @param queueName - Queue name
|
|
262
|
-
* @param handler - Message handler
|
|
263
|
-
* @returns Unsubscribe function
|
|
264
|
-
*/
|
|
265
|
-
onQueueMessage<T = unknown>(
|
|
266
|
-
queueName: string,
|
|
267
|
-
handler: (message: QueueMessageEvent<T>) => Promise<void>,
|
|
268
|
-
): () => void {
|
|
269
|
-
return onQueueMessage(queueName, handler)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// ============================================================================
|
|
273
|
-
// Commands
|
|
274
|
-
// ============================================================================
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Register a command.
|
|
278
|
-
*
|
|
279
|
-
* @param name - Command name
|
|
280
|
-
* @param handler - Command handler that receives params and returns a result
|
|
281
|
-
*/
|
|
282
|
-
command<TParams = unknown, TResult = unknown>(
|
|
283
|
-
name: string,
|
|
284
|
-
handler: (params: TParams) => Promise<TResult>,
|
|
285
|
-
): void {
|
|
286
|
-
command(name, handler)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// ============================================================================
|
|
290
|
-
// HTTP Server Registration
|
|
291
|
-
// ============================================================================
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Register an HTTP server with the control plane.
|
|
295
|
-
*
|
|
296
|
-
* @param port - Port the server is listening on
|
|
297
|
-
*/
|
|
298
|
-
async registerHttpServer(port: number): Promise<void> {
|
|
299
|
-
const client = createClient(ControlServiceDefinition, this.channel)
|
|
300
|
-
|
|
301
|
-
await wrapGrpcCall(
|
|
302
|
-
"ControlService",
|
|
303
|
-
"RegisterHttpServer",
|
|
304
|
-
async () => {
|
|
305
|
-
await client.registerHttpServer({ port })
|
|
306
|
-
},
|
|
307
|
-
{},
|
|
308
|
-
)
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// ============================================================================
|
|
312
|
-
// WaitUntil
|
|
313
|
-
// ============================================================================
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Register a background task.
|
|
317
|
-
*
|
|
318
|
-
* @param promise - The promise to track
|
|
319
|
-
*/
|
|
320
|
-
waitUntil(promise: Promise<unknown>): void {
|
|
321
|
-
waitUntil(promise)
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// ============================================================================
|
|
325
|
-
// Lifecycle
|
|
326
|
-
// ============================================================================
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Start the Alien runtime.
|
|
330
|
-
*
|
|
331
|
-
* This initializes event handlers, registers with the control plane,
|
|
332
|
-
* and starts processing events.
|
|
333
|
-
*/
|
|
334
|
-
async run(): Promise<void> {
|
|
335
|
-
// Initialize wait-until manager
|
|
336
|
-
this.waitUntilManager = initWaitUntilManager(this.channel, this.instanceId)
|
|
337
|
-
|
|
338
|
-
// Initialize event loop
|
|
339
|
-
this.eventLoop = new EventLoop(this.channel, this.instanceId)
|
|
340
|
-
|
|
341
|
-
// Register event handlers with the control plane
|
|
342
|
-
await this.eventLoop.registerHandlers()
|
|
343
|
-
|
|
344
|
-
// Start event loop (handles commands, events, etc.)
|
|
345
|
-
await this.eventLoop.start()
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Stop the runtime gracefully.
|
|
350
|
-
*/
|
|
351
|
-
async shutdown(): Promise<void> {
|
|
352
|
-
// Stop event loop
|
|
353
|
-
this.eventLoop?.stop()
|
|
354
|
-
|
|
355
|
-
// Wait for all background tasks
|
|
356
|
-
await this.waitUntilManager?.waitForAll()
|
|
357
|
-
|
|
358
|
-
// Notify drain complete
|
|
359
|
-
const tasks = this.waitUntilManager?.getTasks()
|
|
360
|
-
if (tasks) {
|
|
361
|
-
const taskArray = Array.from(tasks.values())
|
|
362
|
-
const tasksDrained = taskArray.length
|
|
363
|
-
const allSuccess = taskArray.every(t => !t.error)
|
|
364
|
-
const errorMessage = taskArray.find(t => t.error)?.error?.message
|
|
365
|
-
await this.waitUntilManager?.notifyDrainComplete(tasksDrained, allSuccess, errorMessage)
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|