effortless-aws 0.36.0 → 0.37.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.
@@ -0,0 +1,57 @@
1
+ import {
2
+ lazyImport
3
+ } from "./chunk-U56MLLWP.js";
4
+
5
+ // src/runtime/queue-client.ts
6
+ var loadSdk = () => lazyImport("@aws-sdk/client-sqs");
7
+ var createQueueClient = async (queueName) => {
8
+ const { SQS: SQSClient } = await loadSdk();
9
+ let client = null;
10
+ const getClient = () => client ??= new SQSClient({});
11
+ let resolvedUrl;
12
+ const getQueueUrl = async () => {
13
+ if (resolvedUrl) return resolvedUrl;
14
+ const result = await getClient().getQueueUrl({ QueueName: `${queueName}.fifo` });
15
+ resolvedUrl = result.QueueUrl;
16
+ return resolvedUrl;
17
+ };
18
+ return {
19
+ queueName,
20
+ async send(input) {
21
+ const queueUrl = await getQueueUrl();
22
+ await getClient().sendMessage({
23
+ QueueUrl: queueUrl,
24
+ MessageBody: JSON.stringify(input.body),
25
+ MessageGroupId: input.groupId,
26
+ ...input.deduplicationId ? { MessageDeduplicationId: input.deduplicationId } : {},
27
+ ...input.messageAttributes ? {
28
+ MessageAttributes: Object.fromEntries(
29
+ Object.entries(input.messageAttributes).map(([k, v]) => [k, {
30
+ DataType: v.dataType,
31
+ StringValue: v.stringValue
32
+ }])
33
+ )
34
+ } : {}
35
+ });
36
+ },
37
+ async sendBatch(messages) {
38
+ const queueUrl = await getQueueUrl();
39
+ const entries = messages.map((msg, i) => ({
40
+ Id: String(i),
41
+ MessageBody: JSON.stringify(msg.body),
42
+ MessageGroupId: msg.groupId,
43
+ ...msg.deduplicationId ? { MessageDeduplicationId: msg.deduplicationId } : {}
44
+ }));
45
+ const result = await getClient().sendMessageBatch({
46
+ QueueUrl: queueUrl,
47
+ Entries: entries
48
+ });
49
+ if (result.Failed && result.Failed.length > 0) {
50
+ throw new Error(`Failed to send ${result.Failed.length} message(s): ${result.Failed.map((f) => f.Message).join(", ")}`);
51
+ }
52
+ }
53
+ };
54
+ };
55
+ export {
56
+ createQueueClient
57
+ };
@@ -1,7 +1,10 @@
1
1
  import {
2
- AUTH_COOKIE_NAME,
2
+ AUTH_COOKIE_NAME
3
+ } from "../chunk-4UKWMWM5.js";
4
+ import {
3
5
  createHandlerRuntime
4
- } from "../chunk-Q3ZDMZF3.js";
6
+ } from "../chunk-3NKYT4OX.js";
7
+ import "../chunk-VONNUUEN.js";
5
8
 
6
9
  // src/runtime/wrap-api.ts
7
10
  var CONTENT_TYPE_MAP = {
@@ -213,9 +216,11 @@ var wrapApi = (handler) => {
213
216
  if (isStream) {
214
217
  const streamify = globalThis.awslambda?.streamifyResponse;
215
218
  if (!streamify) {
216
- return async (event) => handleRequest(event);
219
+ const fn3 = async (event) => handleRequest(event);
220
+ fn3.__preload = () => rt.preload();
221
+ return fn3;
217
222
  }
218
- return streamify(async (event, rawStream) => {
223
+ const fn2 = streamify(async (event, rawStream) => {
219
224
  const HttpResponseStream = globalThis.awslambda?.HttpResponseStream;
220
225
  let streamUsed = false;
221
226
  let sseMode = false;
@@ -263,11 +268,15 @@ var wrapApi = (handler) => {
263
268
  rawStream.end();
264
269
  }
265
270
  });
271
+ fn2.__preload = () => rt.preload();
272
+ return fn2;
266
273
  }
267
- return async (event) => {
274
+ const fn = async (event) => {
268
275
  const result = await handleRequest(event);
269
276
  return result ?? notFound();
270
277
  };
278
+ fn.__preload = () => rt.preload();
279
+ return fn;
271
280
  };
272
281
  export {
273
282
  wrapApi
@@ -1,9 +1,14 @@
1
1
  import {
2
2
  createBucketClient,
3
- createBucketClientWithEntities,
4
- createHandlerRuntime,
3
+ createBucketClientWithEntities
4
+ } from "../chunk-UU3AKDJU.js";
5
+ import "../chunk-U56MLLWP.js";
6
+ import {
7
+ createHandlerRuntime
8
+ } from "../chunk-3NKYT4OX.js";
9
+ import {
5
10
  toSeconds
6
- } from "../chunk-Q3ZDMZF3.js";
11
+ } from "../chunk-VONNUUEN.js";
7
12
 
8
13
  // src/runtime/wrap-bucket.ts
9
14
  var ENV_DEP_SELF = "EFF_DEP_SELF";
@@ -34,7 +39,7 @@ var wrapBucket = (handler) => {
34
39
  return bucket ? { bucket } : {};
35
40
  });
36
41
  const handleError = handler.onError ?? (({ error }) => console.error(`[effortless:${rt.handlerName}]`, error));
37
- return async (event) => {
42
+ const fn = async (event) => {
38
43
  const startTime = Date.now();
39
44
  rt.patchConsole();
40
45
  let ctxProps = {};
@@ -83,6 +88,8 @@ var wrapBucket = (handler) => {
83
88
  rt.restoreConsole();
84
89
  }
85
90
  };
91
+ fn.__preload = () => rt.preload();
92
+ return fn;
86
93
  };
87
94
  export {
88
95
  wrapBucket
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  createHandlerRuntime
3
- } from "../chunk-Q3ZDMZF3.js";
3
+ } from "../chunk-3NKYT4OX.js";
4
+ import "../chunk-VONNUUEN.js";
4
5
 
5
6
  // src/runtime/wrap-cron.ts
6
7
  var wrapCron = (handler) => {
@@ -9,7 +10,7 @@ var wrapCron = (handler) => {
9
10
  }
10
11
  const rt = createHandlerRuntime(handler, "cron", handler.__spec.lambda?.logLevel ?? "info");
11
12
  const handleError = handler.onError ?? (({ error }) => console.error(`[effortless:${rt.handlerName}]`, error));
12
- return async () => {
13
+ const fn = async () => {
13
14
  const startTime = Date.now();
14
15
  rt.patchConsole();
15
16
  let ctxProps = {};
@@ -34,6 +35,8 @@ var wrapCron = (handler) => {
34
35
  rt.restoreConsole();
35
36
  }
36
37
  };
38
+ fn.__preload = () => rt.preload();
39
+ return fn;
37
40
  };
38
41
  export {
39
42
  wrapCron
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  createHandlerRuntime
3
- } from "../chunk-Q3ZDMZF3.js";
3
+ } from "../chunk-3NKYT4OX.js";
4
+ import "../chunk-VONNUUEN.js";
4
5
 
5
6
  // src/runtime/wrap-fifo-queue.ts
6
7
  var parseMessages = (rawRecords, schema) => {
@@ -34,7 +35,7 @@ var wrapFifoQueue = (handler) => {
34
35
  }
35
36
  const rt = createHandlerRuntime(handler, "fifo-queue", handler.__spec.lambda?.logLevel ?? "info");
36
37
  const handleError = handler.onError ?? (({ error }) => console.error(`[effortless:${rt.handlerName}]`, error));
37
- return async (event) => {
38
+ const fn = async (event) => {
38
39
  const startTime = Date.now();
39
40
  rt.patchConsole();
40
41
  let ctxProps = {};
@@ -98,6 +99,8 @@ var wrapFifoQueue = (handler) => {
98
99
  rt.restoreConsole();
99
100
  }
100
101
  };
102
+ fn.__preload = () => rt.preload();
103
+ return fn;
101
104
  };
102
105
  export {
103
106
  wrapFifoQueue
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  createHandlerRuntime
3
- } from "../chunk-Q3ZDMZF3.js";
3
+ } from "../chunk-3NKYT4OX.js";
4
+ import "../chunk-VONNUUEN.js";
4
5
 
5
6
  // src/runtime/wrap-mcp.ts
6
7
  var ErrorCode = {
@@ -77,7 +78,7 @@ var wrapMcp = (handler) => {
77
78
  const serverName = handler.__spec.name;
78
79
  const serverVersion = handler.__spec.version ?? "1.0.0";
79
80
  const instructions = handler.__spec.instructions;
80
- return async (event) => {
81
+ const fn = async (event) => {
81
82
  const startTime = Date.now();
82
83
  rt.patchConsole();
83
84
  let ctxProps = {};
@@ -135,6 +136,8 @@ var wrapMcp = (handler) => {
135
136
  rt.restoreConsole();
136
137
  }
137
138
  };
139
+ fn.__preload = () => rt.preload();
140
+ return fn;
138
141
  };
139
142
  async function handleMethod(req, ctx, tools, resourceMap, prompts, serverName, serverVersion, instructions) {
140
143
  switch (req.method) {
@@ -1,7 +1,11 @@
1
1
  import {
2
- createHandlerRuntime,
3
2
  createTableClient
4
- } from "../chunk-Q3ZDMZF3.js";
3
+ } from "../chunk-JFNBO4K3.js";
4
+ import "../chunk-U56MLLWP.js";
5
+ import {
6
+ createHandlerRuntime
7
+ } from "../chunk-3NKYT4OX.js";
8
+ import "../chunk-VONNUUEN.js";
5
9
 
6
10
  // src/runtime/wrap-table-stream.ts
7
11
  import { unmarshall } from "@aws-sdk/util-dynamodb";
@@ -44,20 +48,20 @@ var wrapTableStream = (handler) => {
44
48
  const tagField = handler.__spec.tagField ?? "tag";
45
49
  const concurrency = handler.__spec.concurrency ?? 1;
46
50
  let selfClient = null;
47
- const getSelfClient = () => {
51
+ const getSelfClient = async () => {
48
52
  if (selfClient) return selfClient;
49
53
  const raw = process.env[ENV_DEP_SELF];
50
54
  if (!raw) return void 0;
51
55
  const tableName = raw.startsWith("table:") ? raw.slice(6) : raw;
52
- selfClient = createTableClient(tableName, { tagField });
56
+ selfClient = await createTableClient(tableName, { tagField });
53
57
  return selfClient;
54
58
  };
55
- const rt = createHandlerRuntime(handler, "table", handler.__spec.lambda?.logLevel ?? "info", () => {
56
- const table = getSelfClient();
59
+ const rt = createHandlerRuntime(handler, "table", handler.__spec.lambda?.logLevel ?? "info", async () => {
60
+ const table = await getSelfClient();
57
61
  return table ? { table } : {};
58
62
  });
59
63
  const handleError = handler.onError ?? (({ error }) => console.error(`[effortless:${rt.handlerName}]`, error));
60
- return async (event) => {
64
+ const fn = async (event) => {
61
65
  const startTime = Date.now();
62
66
  rt.patchConsole();
63
67
  let ctxProps = {};
@@ -67,7 +71,8 @@ var wrapTableStream = (handler) => {
67
71
  const common = await rt.commonArgs();
68
72
  const ctx = common.ctx;
69
73
  ctxProps = ctx && typeof ctx === "object" ? { ...ctx } : {};
70
- const shared = { ...ctxProps };
74
+ const table = await getSelfClient();
75
+ const shared = { ...ctxProps, ...table ? { table } : {} };
71
76
  let records;
72
77
  let sequenceNumbers;
73
78
  try {
@@ -141,6 +146,8 @@ var wrapTableStream = (handler) => {
141
146
  rt.restoreConsole();
142
147
  }
143
148
  };
149
+ fn.__preload = () => rt.preload();
150
+ return fn;
144
151
  };
145
152
  export {
146
153
  wrapTableStream
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  buildDeps,
3
3
  buildParams
4
- } from "../chunk-Q3ZDMZF3.js";
4
+ } from "../chunk-3NKYT4OX.js";
5
+ import "../chunk-VONNUUEN.js";
5
6
 
6
7
  // src/runtime/wrap-worker.ts
7
8
  import { SQS } from "@aws-sdk/client-sqs";
@@ -0,0 +1,33 @@
1
+ import {
2
+ lazyImport
3
+ } from "./chunk-U56MLLWP.js";
4
+
5
+ // src/runtime/ssm-client.ts
6
+ var loadSdk = () => lazyImport("@aws-sdk/client-ssm");
7
+ var client = null;
8
+ var getClient = async () => {
9
+ if (!client) {
10
+ const { SSM: SSMCls } = await loadSdk();
11
+ client = new SSMCls({});
12
+ }
13
+ return client;
14
+ };
15
+ var getParameters = async (names) => {
16
+ const map = /* @__PURE__ */ new Map();
17
+ for (let i = 0; i < names.length; i += 10) {
18
+ const batch = names.slice(i, i + 10);
19
+ const result = await (await getClient()).getParameters({
20
+ Names: batch,
21
+ WithDecryption: true
22
+ });
23
+ for (const p of result.Parameters ?? []) {
24
+ if (p.Name && p.Value !== void 0) {
25
+ map.set(p.Name, p.Value);
26
+ }
27
+ }
28
+ }
29
+ return map;
30
+ };
31
+ export {
32
+ getParameters
33
+ };
@@ -0,0 +1,7 @@
1
+ import {
2
+ createTableClient
3
+ } from "./chunk-JFNBO4K3.js";
4
+ import "./chunk-U56MLLWP.js";
5
+ export {
6
+ createTableClient
7
+ };
@@ -0,0 +1,69 @@
1
+ import {
2
+ lazyImport
3
+ } from "./chunk-U56MLLWP.js";
4
+ import {
5
+ toSeconds
6
+ } from "./chunk-VONNUUEN.js";
7
+
8
+ // src/runtime/worker-client.ts
9
+ var loadSqs = () => lazyImport("@aws-sdk/client-sqs");
10
+ var loadEcs = () => lazyImport("@aws-sdk/client-ecs");
11
+ var createWorkerClient = async (depValue) => {
12
+ const [{ SQS: SQSCls }, { ECSClient: ECSCls, DescribeServicesCommand, UpdateServiceCommand }] = await Promise.all([
13
+ loadSqs(),
14
+ loadEcs()
15
+ ]);
16
+ const lastColon = depValue.lastIndexOf(":");
17
+ const workerName = depValue.slice(0, lastColon);
18
+ const idleTimeoutMs = Number(depValue.slice(lastColon + 1)) * 1e3;
19
+ const queueName = `${workerName}-worker`;
20
+ const cluster = workerName.replace(/-[^-]+$/, "");
21
+ const service = workerName;
22
+ let sqsClient = null;
23
+ const getSqs = () => sqsClient ??= new SQSCls({});
24
+ let ecsClient = null;
25
+ const getEcs = () => ecsClient ??= new ECSCls({});
26
+ let resolvedQueueUrl;
27
+ const getQueueUrl = async () => {
28
+ if (resolvedQueueUrl) return resolvedQueueUrl;
29
+ const result = await getSqs().getQueueUrl({ QueueName: queueName });
30
+ resolvedQueueUrl = result.QueueUrl;
31
+ return resolvedQueueUrl;
32
+ };
33
+ let awakeUntil = 0;
34
+ const ensureRunning = async () => {
35
+ if (Date.now() < awakeUntil) return;
36
+ const resp = await getEcs().send(new DescribeServicesCommand({ cluster, services: [service] }));
37
+ const svc = resp.services?.[0];
38
+ if (svc && svc.desiredCount === 0) {
39
+ await getEcs().send(new UpdateServiceCommand({ cluster, service, desiredCount: 1 }));
40
+ }
41
+ awakeUntil = Date.now() + idleTimeoutMs;
42
+ };
43
+ return {
44
+ async send(msg, options) {
45
+ const queueUrl = await getQueueUrl();
46
+ await getSqs().sendMessage({
47
+ QueueUrl: queueUrl,
48
+ MessageBody: JSON.stringify(msg),
49
+ ...options?.delay ? { DelaySeconds: toSeconds(options.delay) } : {}
50
+ });
51
+ if (options?.start !== false && !options?.delay) {
52
+ await ensureRunning();
53
+ }
54
+ },
55
+ async status() {
56
+ const resp = await getEcs().send(new DescribeServicesCommand({ cluster, services: [service] }));
57
+ const svc = resp.services?.[0];
58
+ if (svc && svc.runningCount && svc.runningCount > 0) return "running";
59
+ return "idle";
60
+ },
61
+ async stop() {
62
+ await getEcs().send(new UpdateServiceCommand({ cluster, service, desiredCount: 0 }));
63
+ awakeUntil = 0;
64
+ }
65
+ };
66
+ };
67
+ export {
68
+ createWorkerClient
69
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effortless-aws",
3
- "version": "0.36.0",
3
+ "version": "0.37.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Code-first AWS Lambda framework. Export handlers, deploy with one command.",