@alienplatform/sdk 2.0.1 → 2.1.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 CHANGED
@@ -5119,6 +5119,43 @@ const AwsDynamoDbKvHeartbeatDataSchema = object({
5119
5119
  * Generated by Kubb (https://kubb.dev/).
5120
5120
  * Do not edit manually.
5121
5121
  */
5122
+ /**
5123
+ * @description A single Easy-DKIM CNAME record.
5124
+ */
5125
+ const AwsEmailDkimTokenImportDataSchema = object({
5126
+ "name": string().describe("CNAME record host name."),
5127
+ "value": string().describe("CNAME record value.")
5128
+ }).describe("A single Easy-DKIM CNAME record.");
5129
+ /**
5130
+ * Generated by Kubb (https://kubb.dev/).
5131
+ * Do not edit manually.
5132
+ */
5133
+ /**
5134
+ * @description Per-domain import payload for an AWS Email resource.
5135
+ */
5136
+ const AwsEmailDomainImportDataSchema = object({ get "dkimTokens"() {
5137
+ return array(AwsEmailDkimTokenImportDataSchema.describe("A single Easy-DKIM CNAME record.")).describe("Easy-DKIM CNAME tokens (three per domain). The domain is verified by\nSES once these records exist in its DNS configuration.");
5138
+ } }).describe("Per-domain import payload for an AWS Email resource.");
5139
+ object({
5140
+ "configurationSet": string().describe("SES configuration set name (used when sending)."),
5141
+ "domains": object({}).catchall(lazy(() => AwsEmailDomainImportDataSchema).describe("Per-domain import payload for an AWS Email resource.")).describe("Per-seed-domain DNS data, keyed by mail domain."),
5142
+ "ruleSetName": string().describe("SES receipt rule set name, present only when inbound mail is\nconfigured. Activating the rule set is a manual post-deploy step.").nullish()
5143
+ }).describe("AWS Email ImportData.\n\nMirrors the `emit_import_ref` payload of the AWS SES email emitter: the\nshared configuration set name, one entry per seed domain carrying its\nEasy-DKIM CNAME records, and — when inbound mail is configured — the\nreceipt rule set name. Identities created at runtime through the\n`email/manage-identities` grant are application data and never appear\nhere.");
5144
+ /**
5145
+ * Generated by Kubb (https://kubb.dev/).
5146
+ * Do not edit manually.
5147
+ */
5148
+ /**
5149
+ * @description AWS subnets grouped by their real availability zone.
5150
+ */
5151
+ const AwsFailureDomainSubnetsSchema = object({
5152
+ "privateSubnetIds": optional(array(string()).describe("Private subnet IDs in this availability zone.")),
5153
+ "publicSubnetIds": optional(array(string()).describe("Public subnet IDs in this availability zone."))
5154
+ }).describe("AWS subnets grouped by their real availability zone.");
5155
+ /**
5156
+ * Generated by Kubb (https://kubb.dev/).
5157
+ * Do not edit manually.
5158
+ */
5122
5159
  const ServiceAccountHeartbeatStatusSchema = object({
5123
5160
  get "collectionIssues"() {
5124
5161
  return array(HeartbeatCollectionIssueSchema);
@@ -5213,12 +5250,37 @@ object({
5213
5250
  "publicRouteTableId": string().describe("Public route table ID.").nullish(),
5214
5251
  "publicSubnetIds": array(string()).describe("Public subnet IDs."),
5215
5252
  "securityGroupId": string().describe("Security group ID for private workloads.").nullish(),
5253
+ "subnetsByFailureDomain": optional(object({}).catchall(lazy(() => AwsFailureDomainSubnetsSchema).describe("AWS subnets grouped by their real availability zone.")).describe("Exact subnet membership keyed by real availability zone.")),
5216
5254
  "vpcId": string().describe("VPC ID. Absent when default-VPC mode defers lookup to AWS at runtime.").nullish()
5217
5255
  }).describe("AWS Network ImportData.");
5218
5256
  /**
5219
5257
  * Generated by Kubb (https://kubb.dev/).
5220
5258
  * Do not edit manually.
5221
5259
  */
5260
+ /**
5261
+ * @description Workload type for an OpenSearch Serverless collection.\n\n`TIMESERIES` is intentionally not exposed: next-generation serverless\nscale-to-zero targets search and vector workloads.
5262
+ */
5263
+ const AwsOpenSearchCollectionTypeSchema = _enum(["search", "vectorSearch"]).describe("Workload type for an OpenSearch Serverless collection.\n\n`TIMESERIES` is intentionally not exposed: next-generation serverless\nscale-to-zero targets search and vector workloads.");
5264
+ object({
5265
+ "collectionArn": string().describe("ARN of the collection."),
5266
+ "collectionId": string().describe("Server-assigned collection id."),
5267
+ "collectionName": string().describe("Physical collection name (`{id}-{stack-suffix}`)."),
5268
+ "endpoint": string().describe("Collection endpoint (`https://<collectionId>.aoss.<region>.on.aws`).\nRequests must be SigV4-signed with service name `aoss`.")
5269
+ }).describe("AWS OpenSearch (`experimental/aws-opensearch`) ImportData.\n\nMirrors the `emit_import_ref` payload of the AWS OpenSearch Serverless\nemitter. Next-generation collections expose no Dashboards endpoint, so\nonly the data-plane endpoint and identifiers are carried.");
5270
+ object({
5271
+ "collectionArn": string().describe("ARN of the collection."),
5272
+ "endpoint": string().describe("Collection endpoint (`https://<collectionId>.aoss.<region>.on.aws`).\nRequests must be SigV4-signed with service name `aoss`.")
5273
+ }).describe("Outputs generated by a successfully provisioned AwsOpenSearch collection.\n\nNext-generation collections expose no OpenSearch Dashboards endpoint\n(the `DashboardEndpoint` attribute exists only for classic collections),\nso only the data-plane endpoint and ARN are surfaced.");
5274
+ object({
5275
+ get "collectionType"() {
5276
+ return AwsOpenSearchCollectionTypeSchema.describe("Workload type for an OpenSearch Serverless collection.\n\n`TIMESERIES` is intentionally not exposed: next-generation serverless\nscale-to-zero targets search and vector workloads.").optional();
5277
+ },
5278
+ "id": string().describe("Identifier for the collection. Becomes part of the physical collection\nname, so it must match `[a-z][a-z0-9-]*` and be at most 23 characters.")
5279
+ }).describe("An Amazon OpenSearch Serverless collection (next generation).\n\n# Experimental namespace\n\nThis is the first resource under the `experimental/` resource-type\nnamespace. Experimental resources are provider-specific (they do not\nabstract over clouds), may change or be promoted to a portable resource\nin a breaking way, and are only registered for the platforms they\nsupport. `AwsOpenSearch` registers an AWS CloudFormation emitter only;\ndeploying it to any other platform fails with a typed\n`ImportRegistrationMissing` error at generation time.\n\n# What gets provisioned\n\nThe AWS emitter provisions next-generation OpenSearch Serverless:\na collection group (`Generation: NEXTGEN`, compute/storage decoupled,\nscale-to-zero) plus a collection inside it, an AWS-owned-key encryption\nconfiguration, a public network policy, and a data-access policy for\nservice-account roles granted `experimental/aws-opensearch/data-access`.\nThe collection endpoint is public but every request must be SigV4-signed\nand pass both IAM (`aoss:APIAccessAll`) and the data-access policy.\n\n# Naming\n\nThe physical collection (and collection group) name is\n`{id}-{stack-suffix}` and must satisfy the AOSS name grammar, so `id`\nmust match `[a-z][a-z0-9-]*` and be at most 23 characters. The emitter\nrejects ids that don't fit.\n\n# Runtime access\n\nWorkers reach the collection over HTTPS with SigV4. The SigV4 signing\nservice name for OpenSearch Serverless is `aoss` (not `es`); the runtime\nbinding payload carries `\"service\": \"aoss\"` so clients sign correctly.\nRequests with a body must also send an `x-amz-content-sha256` header\n(the AOSS gateway rejects body-carrying requests without it with an\nempty 403); official OpenSearch clients with an `aoss` signer handle\nthis automatically.");
5280
+ /**
5281
+ * Generated by Kubb (https://kubb.dev/).
5282
+ * Do not edit manually.
5283
+ */
5222
5284
  const VaultHeartbeatStatusSchema = object({
5223
5285
  get "collectionIssues"() {
5224
5286
  return array(HeartbeatCollectionIssueSchema);
@@ -5601,6 +5663,7 @@ const AzureComputeClusterHeartbeatDataSchema = object({
5601
5663
  object({
5602
5664
  "clusterId": string().describe("Cluster identifier used by the controller."),
5603
5665
  "clusterIdentityPrincipalId": string().describe("AKS cluster identity principal id (system-assigned identity)."),
5666
+ "identityId": string().describe("Resource ID of the user-assigned identity attached to cluster VMs."),
5604
5667
  "kubeletIdentityClientId": string().describe("kubelet UAMI client id used by node pools.")
5605
5668
  }).describe("Azure ComputeCluster ImportData — AKS node pool identity / network.");
5606
5669
  /**
@@ -6700,20 +6763,39 @@ object({
6700
6763
  return array(CapacityGroupSchema.describe("Capacity group definition.\n\nA capacity group represents machines with identical hardware profiles.\nEach group becomes a separate Auto Scaling Group (AWS), Managed Instance Group (GCP),\nor VM Scale Set (Azure).")).describe("Capacity groups defining the machine pools for this cluster.\nEach group becomes a separate ASG/MIG/VMSS.");
6701
6764
  },
6702
6765
  "containerCidr": string().describe("Container CIDR block for internal container networking.\nAuto-generated as \"10.244.0.0/16\" if not specified.\nEach machine gets a /24 subnet from this range.").nullish(),
6703
- "id": string().describe("Unique identifier for the container cluster.\nMust contain only alphanumeric characters, hyphens, and underscores.")
6766
+ "failureDomainSpread": optional(object({}).catchall(int().min(0)).describe("Requested failure-domain spread keyed by capacity group.\nEmpty preserves the existing aggregate layout.")),
6767
+ "id": string().describe("Unique identifier for the container cluster.\nMust contain only alphanumeric characters, hyphens, and underscores."),
6768
+ "selectedFailureDomains": optional(object({}).catchall(array(string())).describe("Concrete provider failure domains selected during setup, keyed by capacity group.\nEmpty preserves the existing aggregate layout when no spread policy is configured."))
6704
6769
  }).describe("ComputeCluster resource for running long-running container workloads.\n\nA ComputeCluster provides the setup-owned machine boundary for containers.\nAlien may manage the worker fleet inside that boundary when setup grants\n`compute-cluster/management`.\n\n## Architecture\n\n- **Setup** creates cloud resources: ASGs/MIGs/VMSSs, IAM roles, security groups\n- **Alien** manages allowed fleet operations: machine count and runtime\n machine image rollout\n- A node agent runs on each machine from the selected runtime image channel\n\n## Example\n\n```rust\nuse alien_core::{CapacityGroup, ComputeCluster, MachineProfile};\n\nlet cluster = ComputeCluster::new(\"compute\".to_string())\n .capacity_group(CapacityGroup {\n group_id: \"general\".to_string(),\n instance_type: None,\n profile: Some(MachineProfile {\n cpu: \"4.0\".to_string(),\n memory_bytes: 16 * 1024 * 1024 * 1024,\n ephemeral_storage_bytes: 20 * 1024 * 1024 * 1024,\n architecture: None,\n gpu: None,\n }),\n min_size: 1,\n max_size: 5,\n scale_policy: None,\n nested_virtualization: None,\n })\n .build();\n```");
6705
6770
  /**
6706
6771
  * Generated by Kubb (https://kubb.dev/).
6707
6772
  * Do not edit manually.
6708
6773
  */
6709
6774
  /**
6775
+ * @description Failure-domain policy selected for a compute pool.
6776
+ */
6777
+ const FailureDomainSelectionSchema = object({
6778
+ "selectedFailureDomains": optional(array(string()).describe("Concrete provider domains selected during setup.\nEmpty delegates deterministic selection to the provider setup implementation.")),
6779
+ "spread": int().min(0).describe("Number of distinct failure domains across which new stateful replicas may be spread.")
6780
+ }).describe("Failure-domain policy selected for a compute pool.");
6781
+ /**
6782
+ * Generated by Kubb (https://kubb.dev/).
6783
+ * Do not edit manually.
6784
+ */
6785
+ /**
6710
6786
  * @description User-selected deployment settings for one compute pool.
6711
6787
  */
6712
6788
  const ComputePoolSelectionSchema = union([object({
6789
+ get "failure_domains"() {
6790
+ return union([FailureDomainSelectionSchema, _null()]).optional();
6791
+ },
6713
6792
  "machine": string().describe("Provider machine type selected for this deployment.").nullish(),
6714
6793
  "machines": int().min(0).describe("Number of machines to run."),
6715
6794
  "mode": _enum(["fixed"])
6716
6795
  }), object({
6796
+ get "failure_domains"() {
6797
+ return union([FailureDomainSelectionSchema, _null()]).optional();
6798
+ },
6717
6799
  "machine": string().describe("Provider machine type selected for this deployment.").nullish(),
6718
6800
  "max": int().min(0).describe("Maximum machine count."),
6719
6801
  "min": int().min(0).describe("Minimum machine count."),
@@ -7066,6 +7148,14 @@ const ContainerStatusSchema = _enum([
7066
7148
  * Do not edit manually.
7067
7149
  */
7068
7150
  /**
7151
+ * @description Protocol for public workload endpoints.
7152
+ */
7153
+ const ExposeProtocolSchema = _enum(["http", "tcp"]).describe("Protocol for public workload endpoints.");
7154
+ /**
7155
+ * Generated by Kubb (https://kubb.dev/).
7156
+ * Do not edit manually.
7157
+ */
7158
+ /**
7069
7159
  * @description Load balancer endpoint information for DNS management.\nThis is optional metadata used by the DNS controller to create domain mappings.
7070
7160
  */
7071
7161
  const LoadBalancerEndpointSchema = object({
@@ -7084,6 +7174,10 @@ const PublicEndpointOutputSchema = object({
7084
7174
  get "loadBalancerEndpoint"() {
7085
7175
  return union([LoadBalancerEndpointSchema, _null()]).optional();
7086
7176
  },
7177
+ "port": int().min(1).max(65535).describe("Public connection port."),
7178
+ get "protocol"() {
7179
+ return ExposeProtocolSchema.describe("Protocol for public workload endpoints.");
7180
+ },
7087
7181
  "url": string().describe("Base URL for this endpoint."),
7088
7182
  "wildcardHost": string().describe("Wildcard hostname routed to this endpoint, when configured.").nullish()
7089
7183
  }).describe("Runtime-resolved public endpoint metadata.");
@@ -7152,14 +7246,6 @@ const PersistentStorageSchema = object({
7152
7246
  * Do not edit manually.
7153
7247
  */
7154
7248
  /**
7155
- * @description Protocol for public workload endpoints.
7156
- */
7157
- const ExposeProtocolSchema = _enum(["http", "tcp"]).describe("Protocol for public workload endpoints.");
7158
- /**
7159
- * Generated by Kubb (https://kubb.dev/).
7160
- * Do not edit manually.
7161
- */
7162
- /**
7163
7249
  * @description Public endpoint configuration for port-backed workload resources.
7164
7250
  */
7165
7251
  const PublicEndpointSchema = object({
@@ -7575,6 +7661,62 @@ const DomainSettingsSchema = object({
7575
7661
  * Do not edit manually.
7576
7662
  */
7577
7663
  /**
7664
+ * @description A single DKIM CNAME record the operator must create in DNS.
7665
+ */
7666
+ const EmailDkimTokenSchema = object({
7667
+ "name": string().describe("CNAME record host name."),
7668
+ "value": string().describe("CNAME record value.")
7669
+ }).describe("A single DKIM CNAME record the operator must create in DNS.");
7670
+ /**
7671
+ * Generated by Kubb (https://kubb.dev/).
7672
+ * Do not edit manually.
7673
+ */
7674
+ /**
7675
+ * @description Per-domain DNS records the operator must create.
7676
+ */
7677
+ const EmailDomainOutputsSchema = object({ get "dkimTokens"() {
7678
+ return array(EmailDkimTokenSchema.describe("A single DKIM CNAME record the operator must create in DNS.")).describe("Easy-DKIM CNAME tokens (three per domain). The domain is verified once\nthese records exist in its DNS configuration.");
7679
+ } }).describe("Per-domain DNS records the operator must create.");
7680
+ /**
7681
+ * Generated by Kubb (https://kubb.dev/).
7682
+ * Do not edit manually.
7683
+ */
7684
+ /**
7685
+ * @description Sending-event configuration for an [`Email`] resource.
7686
+ */
7687
+ const EmailEventsSchema = object({ get "queue"() {
7688
+ return ResourceRefSchema.describe("Reference to a resource by its stable id and resource type.");
7689
+ } }).describe("Sending-event configuration for an [`Email`] resource.");
7690
+ /**
7691
+ * Generated by Kubb (https://kubb.dev/).
7692
+ * Do not edit manually.
7693
+ */
7694
+ /**
7695
+ * @description Inbound-mail configuration for an [`Email`] resource.
7696
+ */
7697
+ const EmailInboundSchema = object({ get "storage"() {
7698
+ return ResourceRefSchema.describe("Reference to a resource by its stable id and resource type.");
7699
+ } }).describe("Inbound-mail configuration for an [`Email`] resource.");
7700
+ object({
7701
+ "configurationSet": string().describe("The provisioned configuration set name (used when sending)."),
7702
+ "domains": object({}).catchall(lazy(() => EmailDomainOutputsSchema).describe("Per-domain DNS records the operator must create.")).describe("DNS records per mail domain."),
7703
+ "ruleSetName": string().describe("The inbound receipt rule set name, when `inbound` is configured.\nActivating it is a manual post-deploy step — CloudFormation cannot\nactivate a receipt rule set, and only one can be active per account.").nullish()
7704
+ }).describe("Outputs generated by a successfully provisioned Email resource.\n\nDomain verification status cannot be known at provisioning time — SES\nverifies a domain asynchronously once its DKIM records exist in DNS — so\nthe outputs carry the records the operator must create rather than a\nverification result.");
7705
+ object({
7706
+ "domains": optional(array(string()).describe("Seed mail domains provisioned at deploy time (one SES identity each).\nUseful for day-0 bootstrap and products with a static domain set.\nMay be empty (the default): products that create and verify domains\ndynamically should manage identities at runtime through the\n`email/manage-identities` grant instead of listing them here.")),
7707
+ get "events"() {
7708
+ return union([EmailEventsSchema, _null()]).optional();
7709
+ },
7710
+ "id": string().describe("Identifier for the email resource. Must contain only alphanumeric\ncharacters, hyphens, and underscores ([A-Za-z0-9-_]). Maximum 64 characters."),
7711
+ get "inbound"() {
7712
+ return union([EmailInboundSchema, _null()]).optional();
7713
+ }
7714
+ }).describe("Email infrastructure for sending and receiving mail on customer-owned\ndomains. On AWS this is backed by SES: a shared configuration set, optional\ninbound/event wiring, and one email identity (Easy DKIM) per seed domain.\n\n# Infrastructure vs runtime data\n\nThis resource owns the email *infrastructure* and the capability to use it,\nnot the domain lifecycle. Deployment manages the configuration set, the\nevent topology, the inbound receipt topology, and any seed identities\nlisted in `domains`. Email identities created at runtime through the\n`email/manage-identities` grant are application data: they are not tracked\nby the deployment, are not removed when the stack is deleted, and their\nlifecycle — including deletion — belongs to the application.\n\nThe operator (or the application, for runtime-created identities) owns DNS:\nthe per-domain DKIM CNAME records surfaced in [`EmailOutputs`] must be\ncreated before SES verifies a domain and allows sending from it.\n\n# Inbound mail (AWS)\n\nWhen `inbound` is set, a SES receipt rule set is provisioned that writes\nraw incoming mail into the linked Storage bucket. The receipt rule is a\ncatch-all (no recipient filter), so mail for identities verified at runtime\nlands in the bucket without any infrastructure change. Two caveats apply:\n\n* SES allows only **one active receipt rule set per AWS account**, and\n CloudFormation has no resource that activates a rule set. Activating the\n provisioned rule set is a documented post-deploy step:\n `aws ses set-active-receipt-rule-set --rule-set-name <ruleSetName>`.\n* SES email receiving is only available in a subset of AWS regions (see the\n SES endpoints documentation). Deploying `inbound` to an unsupported\n region fails at the CloudFormation layer.\n\n# Update semantics\n\n`domains` is append-friendly: adding a domain provisions a new identity,\nremoving a domain deletes its identity (and its DKIM verification state).\nThe list may be empty. `inbound` and `events` may be added, removed, or\nrepointed; removing them tears down the corresponding receipt rule set /\nevent destination wiring.");
7715
+ /**
7716
+ * Generated by Kubb (https://kubb.dev/).
7717
+ * Do not edit manually.
7718
+ */
7719
+ /**
7578
7720
  * @description Response handling configuration for deployments
7579
7721
  */
7580
7722
  const ResponseHandlingSchema = object({
@@ -5,6 +5,17 @@
5
5
  */
6
6
  import { type Channel } from "nice-grpc";
7
7
  import type { getControlServiceDefinition } from "./service-definitions.js";
8
+ /**
9
+ * Handlers register by the resource's logical name (the name given in the
10
+ * stack program), but cloud transports deliver events keyed by the provider's
11
+ * physical identifier — the S3 bucket name for storage events, the SQS queue
12
+ * name for queue messages. Resolve a registered source through its
13
+ * `ALIEN_<NAME>_BINDING` env payload so both spellings match. Local transports
14
+ * dispatch logical names directly, so this only widens the match.
15
+ */
16
+ export declare function physicalSourceNames(source: string): string[];
17
+ /** @internal exported for tests */
18
+ export declare function sourceMatches(src: string, physical: string): boolean;
8
19
  /**
9
20
  * Event loop runner for processing tasks from the runtime.
10
21
  *
@@ -1 +1 @@
1
- {"version":3,"file":"event-loop.d.ts","sourceRoot":"","sources":["../../src/worker-runtime/event-loop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,OAAO,EAAgB,MAAM,WAAW,CAAA;AAkBtD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAA;AAE3E;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgD;IACxE,OAAO,CAAC,OAAO,CAAQ;gBAGrB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC;IAQzD;;;;OAIG;YACW,aAAa;IAQ3B;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BvC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAYd,YAAY;YAaZ,UAAU;YA4DV,aAAa;YAyBb,cAAc;IAqB5B,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,qBAAqB;CA4B9B"}
1
+ {"version":3,"file":"event-loop.d.ts","sourceRoot":"","sources":["../../src/worker-runtime/event-loop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,OAAO,EAAgB,MAAM,WAAW,CAAA;AAkBtD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAA;AAE3E;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAe5D;AAED,mCAAmC;AACnC,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgD;IACxE,OAAO,CAAC,OAAO,CAAQ;gBAGrB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC;IAQzD;;;;OAIG;YACW,aAAa;IAQ3B;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BvC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAYd,YAAY;YAaZ,UAAU;YAmEV,aAAa;YAyBb,cAAc;IAqB5B,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,qBAAqB;CA4B9B"}
@@ -27539,6 +27539,32 @@ async function wrapGrpcCall(service, method, call) {
27539
27539
  //#endregion
27540
27540
  //#region src/worker-runtime/event-loop.ts
27541
27541
  /**
27542
+ * Handlers register by the resource's logical name (the name given in the
27543
+ * stack program), but cloud transports deliver events keyed by the provider's
27544
+ * physical identifier — the S3 bucket name for storage events, the SQS queue
27545
+ * name for queue messages. Resolve a registered source through its
27546
+ * `ALIEN_<NAME>_BINDING` env payload so both spellings match. Local transports
27547
+ * dispatch logical names directly, so this only widens the match.
27548
+ */
27549
+ function physicalSourceNames(source) {
27550
+ const raw = process.env[`ALIEN_${source.replaceAll("-", "_").toUpperCase()}_BINDING`];
27551
+ if (!raw) return [];
27552
+ try {
27553
+ const binding = JSON.parse(raw);
27554
+ return [
27555
+ binding.bucketName,
27556
+ binding.queueName,
27557
+ binding.queueUrl?.split("/").pop()
27558
+ ].filter((name) => typeof name === "string" && name.length > 0);
27559
+ } catch {
27560
+ return [];
27561
+ }
27562
+ }
27563
+ /** @internal exported for tests */
27564
+ function sourceMatches(src, physical) {
27565
+ return src === "*" || src === physical || physicalSourceNames(src).includes(physical);
27566
+ }
27567
+ /**
27542
27568
  * Event loop runner for processing tasks from the runtime.
27543
27569
  *
27544
27570
  * @internal
@@ -27621,7 +27647,7 @@ var EventLoop = class {
27621
27647
  for (const entry of getEventHandlers().values()) {
27622
27648
  const src = entry.registration.source;
27623
27649
  if (task.storageEvent && entry.registration.type === "storage") {
27624
- if (src === "*" || src === task.storageEvent.bucket) {
27650
+ if (sourceMatches(src, task.storageEvent.bucket)) {
27625
27651
  matchedEntry = entry;
27626
27652
  break;
27627
27653
  }
@@ -27631,7 +27657,7 @@ var EventLoop = class {
27631
27657
  break;
27632
27658
  }
27633
27659
  } else if (task.queueMessage && entry.registration.type === "queue") {
27634
- if (src === "*" || src === task.queueMessage.source) {
27660
+ if (sourceMatches(src, task.queueMessage.source)) {
27635
27661
  matchedEntry = entry;
27636
27662
  break;
27637
27663
  }
@@ -27639,6 +27665,10 @@ var EventLoop = class {
27639
27665
  }
27640
27666
  if (!matchedEntry) {
27641
27667
  console.warn(`No handler found for task: ${task.taskId}`);
27668
+ await this.sendTaskResult(task.taskId, {
27669
+ success: false,
27670
+ error: `No handler registered for task ${task.taskId}`
27671
+ });
27642
27672
  return;
27643
27673
  }
27644
27674
  if (task.storageEvent) await matchedEntry.handler(this.fromProtoStorageEvent(task.storageEvent));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alienplatform/sdk",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -53,8 +53,8 @@
53
53
  "nice-grpc": "^2.1.11",
54
54
  "nice-grpc-common": "^2.0.2",
55
55
  "zod": "4.3.2",
56
- "@alienplatform/bindings": "^2.0.1",
57
- "@alienplatform/core": "^2.0.1"
56
+ "@alienplatform/bindings": "^2.1.0",
57
+ "@alienplatform/core": "^2.1.0"
58
58
  },
59
59
  "scripts": {
60
60
  "build": "tsdown && tsc --emitDeclarationOnly",