@alienplatform/sdk 1.14.1 → 2.0.0
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/events.ts
DELETED
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Event handling for Alien bindings.
|
|
3
|
-
*
|
|
4
|
-
* Provides handlers for storage events, cron/scheduled events, and queue messages.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Import canonical event types from core
|
|
8
|
-
import type {
|
|
9
|
-
QueueMessage,
|
|
10
|
-
ScheduledEvent,
|
|
11
|
-
StorageEvent,
|
|
12
|
-
StorageEventType,
|
|
13
|
-
} from "@alienplatform/core"
|
|
14
|
-
import { type Channel, createClient } from "nice-grpc"
|
|
15
|
-
import { createGrpcChannel, getGrpcEndpoint } from "./channel.js"
|
|
16
|
-
import { getCommands, runCommand } from "./commands.js"
|
|
17
|
-
import {
|
|
18
|
-
ControlServiceDefinition,
|
|
19
|
-
type ControlServiceClient as GeneratedClient,
|
|
20
|
-
type ArcCommand as ProtoArcCommand,
|
|
21
|
-
type CronEvent as ProtoCronEvent,
|
|
22
|
-
type QueueMessage as ProtoQueueMessage,
|
|
23
|
-
type StorageEvent as ProtoStorageEvent,
|
|
24
|
-
type Task,
|
|
25
|
-
} from "./generated/control.js"
|
|
26
|
-
import { wrapGrpcCall } from "./grpc-utils.js"
|
|
27
|
-
|
|
28
|
-
// Re-export core types for convenience
|
|
29
|
-
export type { StorageEvent, StorageEventType, ScheduledEvent, QueueMessage }
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Cron/scheduled event with schedule info.
|
|
33
|
-
* Extends ScheduledEvent with the schedule name.
|
|
34
|
-
*/
|
|
35
|
-
export interface CronEvent extends ScheduledEvent {
|
|
36
|
-
/** Schedule name */
|
|
37
|
-
scheduleName: string
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Queue message event with queue context.
|
|
42
|
-
*/
|
|
43
|
-
export interface QueueMessageEvent<T = unknown> {
|
|
44
|
-
/** Message ID */
|
|
45
|
-
id: string
|
|
46
|
-
/** Source queue name */
|
|
47
|
-
source: string
|
|
48
|
-
/** Receipt handle for acknowledgment */
|
|
49
|
-
receiptHandle: string
|
|
50
|
-
/** Message payload */
|
|
51
|
-
payload: T
|
|
52
|
-
/** Delivery attempt count */
|
|
53
|
-
attemptCount: number
|
|
54
|
-
/** Message timestamp */
|
|
55
|
-
timestamp: Date
|
|
56
|
-
/** Platform-specific message attributes */
|
|
57
|
-
attributes?: { [key: string]: string }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Event handler registration.
|
|
62
|
-
*/
|
|
63
|
-
export interface EventRegistration {
|
|
64
|
-
/** Handler ID */
|
|
65
|
-
id: string
|
|
66
|
-
/** Event type */
|
|
67
|
-
type: "storage" | "cron" | "queue"
|
|
68
|
-
/** Source filter (bucket name, queue name, etc.) */
|
|
69
|
-
source: string
|
|
70
|
-
/** Optional prefix filter (for storage events) */
|
|
71
|
-
prefix?: string
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Internal storage for event handlers
|
|
75
|
-
const eventHandlers: Map<
|
|
76
|
-
string,
|
|
77
|
-
{
|
|
78
|
-
registration: EventRegistration
|
|
79
|
-
handler: (event: unknown) => Promise<void>
|
|
80
|
-
}
|
|
81
|
-
> = new Map()
|
|
82
|
-
|
|
83
|
-
let handlerIdCounter = 0
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Register a storage event handler.
|
|
87
|
-
*
|
|
88
|
-
* @param bucket - Bucket name to listen for events
|
|
89
|
-
* @param handler - Handler function for storage events
|
|
90
|
-
* @param options - Handler options
|
|
91
|
-
* @returns Unsubscribe function
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```typescript
|
|
95
|
-
* import { onStorageEvent } from "@alienplatform/sdk"
|
|
96
|
-
*
|
|
97
|
-
* onStorageEvent("uploads", async (event) => {
|
|
98
|
-
* console.log("File uploaded:", event.objectKey)
|
|
99
|
-
* await processFile(event.bucketName, event.objectKey)
|
|
100
|
-
* })
|
|
101
|
-
* ```
|
|
102
|
-
*/
|
|
103
|
-
export function onStorageEvent(
|
|
104
|
-
bucket: string,
|
|
105
|
-
handler: (event: StorageEvent) => Promise<void>,
|
|
106
|
-
options?: { prefix?: string },
|
|
107
|
-
): () => void {
|
|
108
|
-
const id = `storage-${++handlerIdCounter}`
|
|
109
|
-
|
|
110
|
-
eventHandlers.set(id, {
|
|
111
|
-
registration: {
|
|
112
|
-
id,
|
|
113
|
-
type: "storage",
|
|
114
|
-
source: bucket,
|
|
115
|
-
prefix: options?.prefix,
|
|
116
|
-
},
|
|
117
|
-
handler: handler as (event: unknown) => Promise<void>,
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
return () => {
|
|
121
|
-
eventHandlers.delete(id)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Register a cron/scheduled event handler.
|
|
127
|
-
*
|
|
128
|
-
* @param scheduleName - Schedule name to listen for
|
|
129
|
-
* @param handler - Handler function for scheduled events
|
|
130
|
-
* @returns Unsubscribe function
|
|
131
|
-
*
|
|
132
|
-
* @example
|
|
133
|
-
* ```typescript
|
|
134
|
-
* import { onCronEvent } from "@alienplatform/sdk"
|
|
135
|
-
*
|
|
136
|
-
* onCronEvent("hourly-task", async (event) => {
|
|
137
|
-
* console.log("Scheduled run at:", event.timestamp)
|
|
138
|
-
* await runHourlyTask()
|
|
139
|
-
* })
|
|
140
|
-
* ```
|
|
141
|
-
*/
|
|
142
|
-
export function onCronEvent(
|
|
143
|
-
scheduleName: string,
|
|
144
|
-
handler: (event: CronEvent) => Promise<void>,
|
|
145
|
-
): () => void {
|
|
146
|
-
const id = `cron-${++handlerIdCounter}`
|
|
147
|
-
|
|
148
|
-
eventHandlers.set(id, {
|
|
149
|
-
registration: {
|
|
150
|
-
id,
|
|
151
|
-
type: "cron",
|
|
152
|
-
source: scheduleName,
|
|
153
|
-
},
|
|
154
|
-
handler: handler as (event: unknown) => Promise<void>,
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
return () => {
|
|
158
|
-
eventHandlers.delete(id)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Register a queue message handler.
|
|
164
|
-
*
|
|
165
|
-
* @param queueName - Queue name to listen for messages
|
|
166
|
-
* @param handler - Handler function for queue messages
|
|
167
|
-
* @returns Unsubscribe function
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```typescript
|
|
171
|
-
* import { onQueueMessage } from "@alienplatform/sdk"
|
|
172
|
-
*
|
|
173
|
-
* onQueueMessage("tasks", async (message) => {
|
|
174
|
-
* console.log("Processing task:", message.payload)
|
|
175
|
-
* await processTask(message.payload)
|
|
176
|
-
* })
|
|
177
|
-
* ```
|
|
178
|
-
*/
|
|
179
|
-
export function onQueueMessage<T = unknown>(
|
|
180
|
-
queueName: string,
|
|
181
|
-
handler: (message: QueueMessageEvent<T>) => Promise<void>,
|
|
182
|
-
): () => void {
|
|
183
|
-
const id = `queue-${++handlerIdCounter}`
|
|
184
|
-
|
|
185
|
-
eventHandlers.set(id, {
|
|
186
|
-
registration: {
|
|
187
|
-
id,
|
|
188
|
-
type: "queue",
|
|
189
|
-
source: queueName,
|
|
190
|
-
},
|
|
191
|
-
handler: handler as (event: unknown) => Promise<void>,
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
return () => {
|
|
195
|
-
eventHandlers.delete(id)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Get all registered event handlers.
|
|
201
|
-
*
|
|
202
|
-
* @internal
|
|
203
|
-
*/
|
|
204
|
-
export function getEventHandlers(): Map<
|
|
205
|
-
string,
|
|
206
|
-
{
|
|
207
|
-
registration: EventRegistration
|
|
208
|
-
handler: (event: unknown) => Promise<void>
|
|
209
|
-
}
|
|
210
|
-
> {
|
|
211
|
-
return eventHandlers
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Event loop runner for processing tasks from the control plane.
|
|
216
|
-
*
|
|
217
|
-
* @internal
|
|
218
|
-
*/
|
|
219
|
-
export class EventLoop {
|
|
220
|
-
private readonly client: GeneratedClient
|
|
221
|
-
private sendClient: GeneratedClient | undefined
|
|
222
|
-
private readonly applicationId: string
|
|
223
|
-
private running = false
|
|
224
|
-
|
|
225
|
-
constructor(channel: Channel, applicationId: string) {
|
|
226
|
-
this.client = createClient(ControlServiceDefinition, channel)
|
|
227
|
-
this.applicationId = applicationId
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Get or create a separate gRPC client for sending task results.
|
|
232
|
-
* Uses a dedicated channel to avoid HTTP/2 multiplexing issues
|
|
233
|
-
* with the long-lived waitForTasks stream on some runtimes (e.g. Bun).
|
|
234
|
-
*/
|
|
235
|
-
private async getSendClient(): Promise<GeneratedClient> {
|
|
236
|
-
if (!this.sendClient) {
|
|
237
|
-
const endpoint = getGrpcEndpoint()
|
|
238
|
-
const sendChannel = await createGrpcChannel(endpoint)
|
|
239
|
-
this.sendClient = createClient(ControlServiceDefinition, sendChannel)
|
|
240
|
-
}
|
|
241
|
-
return this.sendClient
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Register all event handlers with the control plane.
|
|
246
|
-
*/
|
|
247
|
-
async registerHandlers(): Promise<void> {
|
|
248
|
-
// Register event handlers
|
|
249
|
-
for (const { registration } of eventHandlers.values()) {
|
|
250
|
-
await wrapGrpcCall(
|
|
251
|
-
"ControlService",
|
|
252
|
-
"RegisterEventHandler",
|
|
253
|
-
async () => {
|
|
254
|
-
await this.client.registerEventHandler({
|
|
255
|
-
handlerType: registration.type,
|
|
256
|
-
resourceName: registration.source,
|
|
257
|
-
})
|
|
258
|
-
},
|
|
259
|
-
{},
|
|
260
|
-
)
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Register command handlers
|
|
264
|
-
for (const command of getCommands().values()) {
|
|
265
|
-
await wrapGrpcCall(
|
|
266
|
-
"ControlService",
|
|
267
|
-
"RegisterEventHandler",
|
|
268
|
-
async () => {
|
|
269
|
-
await this.client.registerEventHandler({
|
|
270
|
-
handlerType: "command",
|
|
271
|
-
resourceName: command.name,
|
|
272
|
-
})
|
|
273
|
-
},
|
|
274
|
-
{},
|
|
275
|
-
)
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Start the event loop.
|
|
281
|
-
*/
|
|
282
|
-
async start(): Promise<void> {
|
|
283
|
-
this.running = true
|
|
284
|
-
|
|
285
|
-
while (this.running) {
|
|
286
|
-
try {
|
|
287
|
-
await this.processTasks()
|
|
288
|
-
} catch (error) {
|
|
289
|
-
console.error("[alien:event-loop] processTasks threw:", error)
|
|
290
|
-
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Stop the event loop.
|
|
297
|
-
*/
|
|
298
|
-
stop(): void {
|
|
299
|
-
this.running = false
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
private async processTasks(): Promise<void> {
|
|
303
|
-
const stream = this.client.waitForTasks({
|
|
304
|
-
applicationId: this.applicationId,
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
for await (const task of stream) {
|
|
308
|
-
try {
|
|
309
|
-
await this.handleTask(task)
|
|
310
|
-
} catch (error) {
|
|
311
|
-
// Catch errors here so the for-await loop continues processing tasks
|
|
312
|
-
// instead of breaking and reconnecting (which could miss buffered tasks).
|
|
313
|
-
console.error(
|
|
314
|
-
`[alien:event-loop] handleTask threw (task will not break stream): id=${task.taskId} error=${error instanceof Error ? error.message : String(error)}`,
|
|
315
|
-
)
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
private async handleTask(task: Task): Promise<void> {
|
|
321
|
-
try {
|
|
322
|
-
// Handle commands
|
|
323
|
-
if (task.arcCommand) {
|
|
324
|
-
const result = await this.handleCommand(task.arcCommand)
|
|
325
|
-
await this.sendTaskResult(task.taskId, { success: true, data: result })
|
|
326
|
-
return
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Handle events (storage, cron, queue)
|
|
330
|
-
let matchedEntry: { handler: (event: unknown) => Promise<void> } | undefined
|
|
331
|
-
|
|
332
|
-
for (const entry of eventHandlers.values()) {
|
|
333
|
-
const src = entry.registration.source
|
|
334
|
-
if (task.storageEvent && entry.registration.type === "storage") {
|
|
335
|
-
if (src === "*" || src === task.storageEvent.bucket) {
|
|
336
|
-
matchedEntry = entry
|
|
337
|
-
break
|
|
338
|
-
}
|
|
339
|
-
} else if (task.cronEvent && entry.registration.type === "cron") {
|
|
340
|
-
if (src === "*" || src === task.cronEvent.scheduleName) {
|
|
341
|
-
matchedEntry = entry
|
|
342
|
-
break
|
|
343
|
-
}
|
|
344
|
-
} else if (task.queueMessage && entry.registration.type === "queue") {
|
|
345
|
-
if (src === "*" || src === task.queueMessage.source) {
|
|
346
|
-
matchedEntry = entry
|
|
347
|
-
break
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
if (!matchedEntry) {
|
|
353
|
-
console.warn(`No handler found for task: ${task.taskId}`)
|
|
354
|
-
return
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
if (task.storageEvent) {
|
|
358
|
-
const storageEvent = this.fromProtoStorageEvent(task.storageEvent)
|
|
359
|
-
await matchedEntry.handler(storageEvent)
|
|
360
|
-
} else if (task.cronEvent) {
|
|
361
|
-
const cronEvent = this.fromProtoCronEvent(task.cronEvent)
|
|
362
|
-
await matchedEntry.handler(cronEvent)
|
|
363
|
-
} else if (task.queueMessage) {
|
|
364
|
-
const queueEvent = this.fromProtoQueueMessage(task.queueMessage)
|
|
365
|
-
await matchedEntry.handler(queueEvent)
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// Report success
|
|
369
|
-
await this.sendTaskResult(task.taskId, { success: true })
|
|
370
|
-
} catch (error) {
|
|
371
|
-
// Report error
|
|
372
|
-
console.error(
|
|
373
|
-
`[alien:event-loop] Task error: id=${task.taskId} error=${error instanceof Error ? error.message : String(error)}`,
|
|
374
|
-
)
|
|
375
|
-
try {
|
|
376
|
-
await this.sendTaskResult(task.taskId, {
|
|
377
|
-
success: false,
|
|
378
|
-
error: error instanceof Error ? error.message : String(error),
|
|
379
|
-
})
|
|
380
|
-
} catch (sendError) {
|
|
381
|
-
console.error(
|
|
382
|
-
`[alien:event-loop] Failed to send error result: id=${task.taskId} sendError=${sendError instanceof Error ? sendError.message : String(sendError)}`,
|
|
383
|
-
)
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
private async handleCommand(command: ProtoArcCommand): Promise<unknown> {
|
|
389
|
-
// Parse command parameters
|
|
390
|
-
let params: unknown = {}
|
|
391
|
-
if (command.params && command.params.length > 0) {
|
|
392
|
-
try {
|
|
393
|
-
const text = new TextDecoder().decode(command.params)
|
|
394
|
-
params = JSON.parse(text)
|
|
395
|
-
} catch {
|
|
396
|
-
// If not valid JSON, use empty object
|
|
397
|
-
params = {}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// Run the command
|
|
402
|
-
return await runCommand(command.commandName, params)
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
private async sendTaskResult(
|
|
406
|
-
taskId: string,
|
|
407
|
-
result: { success: boolean; error?: string; data?: unknown },
|
|
408
|
-
): Promise<void> {
|
|
409
|
-
// Use a separate gRPC client (dedicated channel) to avoid HTTP/2
|
|
410
|
-
// multiplexing issues with the long-lived waitForTasks stream.
|
|
411
|
-
const client = await this.getSendClient()
|
|
412
|
-
// Use a 30-second timeout to prevent hanging if the gRPC response is delayed
|
|
413
|
-
const signal = AbortSignal.timeout(30_000)
|
|
414
|
-
await wrapGrpcCall(
|
|
415
|
-
"ControlService",
|
|
416
|
-
"SendTaskResult",
|
|
417
|
-
async () => {
|
|
418
|
-
if (result.success) {
|
|
419
|
-
const responseData = result.data
|
|
420
|
-
? new TextEncoder().encode(JSON.stringify(result.data))
|
|
421
|
-
: new Uint8Array()
|
|
422
|
-
await client.sendTaskResult(
|
|
423
|
-
{
|
|
424
|
-
taskId,
|
|
425
|
-
success: { responseData },
|
|
426
|
-
},
|
|
427
|
-
{ signal },
|
|
428
|
-
)
|
|
429
|
-
} else {
|
|
430
|
-
await client.sendTaskResult(
|
|
431
|
-
{
|
|
432
|
-
taskId,
|
|
433
|
-
error: { code: "ERROR", message: result.error ?? "Unknown error" },
|
|
434
|
-
},
|
|
435
|
-
{ signal },
|
|
436
|
-
)
|
|
437
|
-
}
|
|
438
|
-
},
|
|
439
|
-
{},
|
|
440
|
-
)
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* Transform proto StorageEvent to core StorageEvent type.
|
|
445
|
-
*/
|
|
446
|
-
private fromProtoStorageEvent(proto: ProtoStorageEvent): StorageEvent {
|
|
447
|
-
const eventTypeMap: Record<string, StorageEventType> = {
|
|
448
|
-
created: "created",
|
|
449
|
-
deleted: "deleted",
|
|
450
|
-
copied: "copied",
|
|
451
|
-
metadata_updated: "metadataUpdated",
|
|
452
|
-
restored: "restored",
|
|
453
|
-
tier_changed: "tierChanged",
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
return {
|
|
457
|
-
eventType: eventTypeMap[proto.eventType] ?? ("unknown" as StorageEventType),
|
|
458
|
-
bucketName: proto.bucket,
|
|
459
|
-
objectKey: proto.key,
|
|
460
|
-
timestamp: proto.timestamp?.toISOString() ?? new Date().toISOString(),
|
|
461
|
-
size: proto.size ? Number(proto.size) : undefined,
|
|
462
|
-
contentType: proto.contentType || undefined,
|
|
463
|
-
etag: proto.etag || undefined,
|
|
464
|
-
metadata:
|
|
465
|
-
proto.metadata && Object.keys(proto.metadata).length > 0 ? proto.metadata : undefined,
|
|
466
|
-
copySource: undefined,
|
|
467
|
-
previousTier: undefined,
|
|
468
|
-
currentTier: proto.currentTier || undefined,
|
|
469
|
-
region: proto.region || undefined,
|
|
470
|
-
versionId: proto.versionId || undefined,
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* Transform proto CronEvent to CronEvent type.
|
|
476
|
-
*/
|
|
477
|
-
private fromProtoCronEvent(proto: ProtoCronEvent): CronEvent {
|
|
478
|
-
return {
|
|
479
|
-
scheduleName: proto.scheduleName,
|
|
480
|
-
timestamp: proto.scheduledTime?.toISOString() ?? new Date().toISOString(),
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* Transform proto QueueMessage to QueueMessageEvent type.
|
|
486
|
-
*/
|
|
487
|
-
private fromProtoQueueMessage<T>(proto: ProtoQueueMessage): QueueMessageEvent<T> {
|
|
488
|
-
// Proto payload is Uint8Array (JSON bytes), parse it
|
|
489
|
-
let payload: unknown = null
|
|
490
|
-
if (proto.payload && proto.payload.length > 0) {
|
|
491
|
-
try {
|
|
492
|
-
const text = new TextDecoder().decode(proto.payload)
|
|
493
|
-
payload = JSON.parse(text)
|
|
494
|
-
} catch {
|
|
495
|
-
// If not valid JSON, use raw bytes
|
|
496
|
-
payload = proto.payload
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
return {
|
|
501
|
-
id: proto.id,
|
|
502
|
-
source: proto.source,
|
|
503
|
-
receiptHandle: proto.receiptHandle,
|
|
504
|
-
payload: payload as T,
|
|
505
|
-
attemptCount: proto.attemptCount,
|
|
506
|
-
timestamp: proto.timestamp ?? new Date(),
|
|
507
|
-
attributes:
|
|
508
|
-
proto.attributes && Object.keys(proto.attributes).length > 0 ? proto.attributes : undefined,
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
}
|