@ts-cloud/core 0.5.6 → 0.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +37 -25
- package/dist/runtime/adapter.ts +5 -0
- package/dist/runtime-assets/cli-runtime.php +5 -0
- package/dist/types.d.ts +9 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -45758,34 +45758,39 @@ function composeServerlessAppTemplate(opts) {
|
|
|
45758
45758
|
}
|
|
45759
45759
|
if (app.warm && app.warm > 0) {
|
|
45760
45760
|
const TARGETS_PER_RULE = 5;
|
|
45761
|
-
const
|
|
45762
|
-
|
|
45763
|
-
for (
|
|
45764
|
-
const
|
|
45765
|
-
|
|
45766
|
-
|
|
45761
|
+
const fnResource = { http: "HttpFunction", queue: "QueueFunction", cli: "CliFunction" };
|
|
45762
|
+
const warmModes = (app.warmFunctions ?? ["http"]).filter((m) => m !== "queue" || hasQueue);
|
|
45763
|
+
for (const mode of warmModes) {
|
|
45764
|
+
const cap = mode.charAt(0).toUpperCase() + mode.slice(1);
|
|
45765
|
+
const ruleCount = Math.ceil(app.warm / TARGETS_PER_RULE);
|
|
45766
|
+
let warmed = 0;
|
|
45767
|
+
for (let r = 0;r < ruleCount; r++) {
|
|
45768
|
+
const targets = Math.min(TARGETS_PER_RULE, app.warm - warmed);
|
|
45769
|
+
resources[`Warmer${cap}Rule${r}`] = {
|
|
45770
|
+
Type: "AWS::Events::Rule",
|
|
45771
|
+
Properties: {
|
|
45772
|
+
Name: `${slug}-${environment}-warmer-${mode}-${r}`,
|
|
45773
|
+
ScheduleExpression: "rate(5 minutes)",
|
|
45774
|
+
State: "ENABLED",
|
|
45775
|
+
Targets: Array.from({ length: targets }, (_, i) => ({
|
|
45776
|
+
Id: `warm-${mode}-${r}-${i}`,
|
|
45777
|
+
Arn: Fn2.getAtt(fnResource[mode], "Arn"),
|
|
45778
|
+
Input: JSON.stringify({ warmer: true })
|
|
45779
|
+
}))
|
|
45780
|
+
}
|
|
45781
|
+
};
|
|
45782
|
+
warmed += targets;
|
|
45783
|
+
}
|
|
45784
|
+
resources[`Warmer${cap}Permission`] = {
|
|
45785
|
+
Type: "AWS::Lambda::Permission",
|
|
45767
45786
|
Properties: {
|
|
45768
|
-
|
|
45769
|
-
|
|
45770
|
-
|
|
45771
|
-
|
|
45772
|
-
Id: `warm-${r}-${i}`,
|
|
45773
|
-
Arn: Fn2.getAtt("HttpFunction", "Arn"),
|
|
45774
|
-
Input: JSON.stringify({ warmer: true })
|
|
45775
|
-
}))
|
|
45787
|
+
FunctionName: Fn2.ref(fnResource[mode]),
|
|
45788
|
+
Action: "lambda:InvokeFunction",
|
|
45789
|
+
Principal: "events.amazonaws.com",
|
|
45790
|
+
SourceArn: Fn2.sub("arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/" + `${slug}-${environment}-warmer-${mode}-*`)
|
|
45776
45791
|
}
|
|
45777
45792
|
};
|
|
45778
|
-
warmed += targets;
|
|
45779
45793
|
}
|
|
45780
|
-
resources.WarmerPermission = {
|
|
45781
|
-
Type: "AWS::Lambda::Permission",
|
|
45782
|
-
Properties: {
|
|
45783
|
-
FunctionName: Fn2.ref("HttpFunction"),
|
|
45784
|
-
Action: "lambda:InvokeFunction",
|
|
45785
|
-
Principal: "events.amazonaws.com",
|
|
45786
|
-
SourceArn: Fn2.sub("arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/" + `${slug}-${environment}-warmer-*`)
|
|
45787
|
-
}
|
|
45788
|
-
};
|
|
45789
45794
|
}
|
|
45790
45795
|
if (cacheEnabled) {
|
|
45791
45796
|
resources.CacheTable = {
|
|
@@ -46042,7 +46047,10 @@ function composeServerlessAppTemplate(opts) {
|
|
|
46042
46047
|
DatabaseName: "app",
|
|
46043
46048
|
MasterUsername: Fn2.sub("{{resolve:secretsmanager:${DbSecret}:SecretString:username}}"),
|
|
46044
46049
|
MasterUserPassword: Fn2.sub("{{resolve:secretsmanager:${DbSecret}:SecretString:password}}"),
|
|
46045
|
-
ServerlessV2ScalingConfiguration: {
|
|
46050
|
+
ServerlessV2ScalingConfiguration: {
|
|
46051
|
+
MinCapacity: app.database?.minCapacity ?? 0.5,
|
|
46052
|
+
MaxCapacity: app.database?.maxCapacity ?? 4
|
|
46053
|
+
},
|
|
46046
46054
|
DBSubnetGroupName: Fn2.ref("DbSubnetGroup"),
|
|
46047
46055
|
VpcSecurityGroupIds: [Fn2.getAtt("DataSecurityGroup", "GroupId")]
|
|
46048
46056
|
}
|
|
@@ -46404,6 +46412,8 @@ function parseRecordBody(body) {
|
|
|
46404
46412
|
function createQueueHandler(handler8) {
|
|
46405
46413
|
return async (event) => {
|
|
46406
46414
|
const batchItemFailures = [];
|
|
46415
|
+
if (event.warmer)
|
|
46416
|
+
return { batchItemFailures };
|
|
46407
46417
|
if (!handler8)
|
|
46408
46418
|
return { batchItemFailures };
|
|
46409
46419
|
for (const record of event.Records ?? []) {
|
|
@@ -46418,6 +46428,8 @@ function createQueueHandler(handler8) {
|
|
|
46418
46428
|
}
|
|
46419
46429
|
function createCliHandler(handler8) {
|
|
46420
46430
|
return async (event) => {
|
|
46431
|
+
if (event.warmer)
|
|
46432
|
+
return { statusCode: 0, output: "warm" };
|
|
46421
46433
|
if (!handler8)
|
|
46422
46434
|
return { statusCode: 501, output: "No CLI handler configured" };
|
|
46423
46435
|
return handler8(event);
|
package/dist/runtime/adapter.ts
CHANGED
|
@@ -245,6 +245,9 @@ function parseRecordBody(body: string): unknown {
|
|
|
245
245
|
export function createQueueHandler(handler: JobHandler | undefined): LambdaQueueHandler {
|
|
246
246
|
return async (event: SqsEvent): Promise<SqsBatchResponse> => {
|
|
247
247
|
const batchItemFailures: Array<{ itemIdentifier: string }> = []
|
|
248
|
+
// Warmer pings invoke the function directly (no SQS Records) — keep the
|
|
249
|
+
// container warm without treating the ping as a job.
|
|
250
|
+
if ((event as unknown as { warmer?: boolean }).warmer) return { batchItemFailures }
|
|
248
251
|
if (!handler) return { batchItemFailures }
|
|
249
252
|
|
|
250
253
|
for (const record of event.Records ?? []) {
|
|
@@ -268,6 +271,8 @@ export function createQueueHandler(handler: JobHandler | undefined): LambdaQueue
|
|
|
268
271
|
*/
|
|
269
272
|
export function createCliHandler(handler: CommandHandler | undefined): LambdaCliHandler {
|
|
270
273
|
return async (event: CliEvent): Promise<CliResult> => {
|
|
274
|
+
// Warmer pings keep the container warm without running a command.
|
|
275
|
+
if ((event as unknown as { warmer?: boolean }).warmer) return { statusCode: 0, output: 'warm' }
|
|
271
276
|
if (!handler) return { statusCode: 501, output: 'No CLI handler configured' }
|
|
272
277
|
return handler(event)
|
|
273
278
|
}
|
|
@@ -36,6 +36,11 @@ while (true) {
|
|
|
36
36
|
|
|
37
37
|
function dispatch(array $event, string $artisan, string $queueCommand): array
|
|
38
38
|
{
|
|
39
|
+
// Warmer pings keep the container warm without running anything.
|
|
40
|
+
if (($event['warmer'] ?? false) === true) {
|
|
41
|
+
return ['warm' => true];
|
|
42
|
+
}
|
|
43
|
+
|
|
39
44
|
// SQS queue event.
|
|
40
45
|
if (isset($event['Records']) && is_array($event['Records'])) {
|
|
41
46
|
$failures = [];
|
package/dist/types.d.ts
CHANGED
|
@@ -1590,6 +1590,11 @@ export interface ServerlessAppConfig {
|
|
|
1590
1590
|
* 0/undefined disables warming.
|
|
1591
1591
|
*/
|
|
1592
1592
|
warm?: number;
|
|
1593
|
+
/**
|
|
1594
|
+
* Which functions the warmer keeps warm. @default ['http']
|
|
1595
|
+
* (queue/cli are async + latency-tolerant, so HTTP-only is the sensible default).
|
|
1596
|
+
*/
|
|
1597
|
+
warmFunctions?: Array<'http' | 'queue' | 'cli'>;
|
|
1593
1598
|
/** CloudWatch log retention (days) for all function log groups. @default 14 */
|
|
1594
1599
|
logRetention?: number;
|
|
1595
1600
|
/** CLI function memory in MB. @default 1024 */
|
|
@@ -1659,6 +1664,10 @@ export interface ServerlessAppConfig {
|
|
|
1659
1664
|
database?: {
|
|
1660
1665
|
connection?: 'rds-proxy' | 'aurora-serverless' | 'rds';
|
|
1661
1666
|
cluster?: string;
|
|
1667
|
+
/** Aurora Serverless v2 minimum capacity (ACUs). @default 0.5 */
|
|
1668
|
+
minCapacity?: number;
|
|
1669
|
+
/** Aurora Serverless v2 maximum capacity (ACUs). @default 4 */
|
|
1670
|
+
maxCapacity?: number;
|
|
1662
1671
|
};
|
|
1663
1672
|
/** Cache attachment. DynamoDB cache table is the zero-NAT default. */
|
|
1664
1673
|
cache?: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ts-cloud/core",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core CloudFormation generation library for ts-cloud",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.com>",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"typecheck": "tsc --noEmit"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ts-cloud/aws-types": "0.5.
|
|
34
|
+
"@ts-cloud/aws-types": "0.5.8"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"typescript": "^5.9.3"
|