sst 2.25.6 → 2.26.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.
Files changed (52) hide show
  1. package/bootstrap.js +3 -3
  2. package/bus.js +2 -2
  3. package/cache.js +2 -2
  4. package/cdk/deployments-wrapper.js +2 -2
  5. package/cli/commands/dev.js +6 -5
  6. package/cli/commands/plugins/kysely.js +2 -2
  7. package/cli/commands/plugins/pothos.js +2 -2
  8. package/cli/commands/plugins/warmer.js +2 -2
  9. package/cli/local/server.js +75 -26
  10. package/cli/spinner.js +2 -2
  11. package/constructs/App.js +4 -3
  12. package/constructs/Function.d.ts +2 -2
  13. package/constructs/Function.js +1 -1
  14. package/constructs/context.d.ts +2 -7
  15. package/constructs/context.js +26 -8
  16. package/context/context2.d.ts +16 -0
  17. package/context/context2.js +108 -0
  18. package/context/handler.js +3 -4
  19. package/credentials.d.ts +3 -10
  20. package/credentials.js +5 -5
  21. package/iot.js +3 -3
  22. package/logger.js +2 -2
  23. package/node/actor/index.d.ts +2 -2
  24. package/node/actor/index.js +3 -3
  25. package/node/api/index.js +7 -7
  26. package/node/auth/session.js +1 -1
  27. package/node/event-bus/index.js +0 -1
  28. package/node/future/auth/session.js +1 -1
  29. package/node/util/loader.js +4 -4
  30. package/package.json +20 -19
  31. package/project.d.ts +0 -5
  32. package/project.js +5 -5
  33. package/runtime/handlers/python.js +1 -3
  34. package/runtime/handlers.js +3 -3
  35. package/runtime/iot.js +2 -2
  36. package/runtime/server.js +3 -3
  37. package/runtime/workers.js +2 -2
  38. package/stacks/app-metadata.js +2 -3
  39. package/stacks/metadata.d.ts +1 -1
  40. package/stacks/metadata.js +2 -5
  41. package/support/bootstrap-metadata-function/index.mjs +41338 -45328
  42. package/support/bridge/bridge.mjs +55 -65
  43. package/support/custom-resources/index.mjs +90699 -90561
  44. package/support/event-bus-retrier/index.mjs +57 -27
  45. package/support/job-manager/index.mjs +22257 -7697
  46. package/support/rds-migrator/index.mjs +41 -17
  47. package/support/script-function/index.mjs +33731 -35450
  48. package/support/signing-function/index.mjs +578 -32
  49. package/support/ssr-warmer/index.mjs +26855 -26892
  50. package/util/lazy.d.ts +1 -0
  51. package/util/lazy.js +11 -0
  52. package/watcher.js +2 -2
package/bootstrap.js CHANGED
@@ -11,18 +11,18 @@ import { LambdaFunction } from "aws-cdk-lib/aws-events-targets";
11
11
  import { BlockPublicAccess, Bucket, BucketEncryption, } from "aws-cdk-lib/aws-s3";
12
12
  import { useProject } from "./project.js";
13
13
  import { createSpinner } from "./cli/spinner.js";
14
- import { Context } from "./context/context.js";
15
14
  import { useAWSClient, useAWSCredentials, useSTSIdentity, } from "./credentials.js";
16
15
  import { VisibleError } from "./error.js";
17
16
  import { Logger } from "./logger.js";
18
17
  import { Stacks } from "./stacks/index.js";
18
+ import { lazy } from "./util/lazy.js";
19
19
  const CDK_STACK_NAME = "CDKToolkit";
20
20
  const SST_STACK_NAME = "SSTBootstrap";
21
21
  const OUTPUT_VERSION = "Version";
22
22
  const OUTPUT_BUCKET = "BucketName";
23
23
  const LATEST_VERSION = "7.2";
24
24
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
25
- export const useBootstrap = Context.memo(async () => {
25
+ export const useBootstrap = lazy(async () => {
26
26
  Logger.debug("Initializing bootstrap context");
27
27
  let [cdkStatus, sstStatus] = await Promise.all([
28
28
  loadCDKStatus(),
@@ -53,7 +53,7 @@ export const useBootstrap = Context.memo(async () => {
53
53
  }
54
54
  Logger.debug("Bootstrap context initialized", sstStatus);
55
55
  return sstStatus;
56
- }, "Bootstrap");
56
+ });
57
57
  async function loadCDKStatus() {
58
58
  const { cdk } = useProject().config;
59
59
  const client = useAWSClient(CloudFormationClient);
package/bus.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import crypto from "crypto";
2
- import { Context } from "./context/context.js";
3
2
  import { Logger } from "./logger.js";
3
+ import { lazy } from "./util/lazy.js";
4
4
  const DO_NOT_LOG = new Set(["stacks.metadata"]);
5
- export const useBus = Context.memo(() => {
5
+ export const useBus = lazy(() => {
6
6
  const subscriptions = {};
7
7
  function subscribers(type) {
8
8
  let arr = subscriptions[type];
package/cache.js CHANGED
@@ -2,8 +2,8 @@ import path from "path";
2
2
  import fs from "fs/promises";
3
3
  import { useProject } from "./project.js";
4
4
  import { Logger } from "./logger.js";
5
- import { Context } from "./context/context.js";
6
- export const useCache = Context.memo(async () => {
5
+ import { lazy } from "./util/lazy.js";
6
+ export const useCache = lazy(async () => {
7
7
  const project = useProject();
8
8
  const cache = path.join(project.paths.out, "cache");
9
9
  await fs.mkdir(cache, {
@@ -9,7 +9,7 @@ import { publishAssets } from "sst-aws-cdk/lib/util/asset-publishing.js";
9
9
  import { AssetManifestBuilder } from "sst-aws-cdk/lib/util/asset-manifest-builder.js";
10
10
  import { Deployments, } from "./deployments.js";
11
11
  import { makeBodyParameter } from "./deploy-stack.js";
12
- import { Context } from "../context/context.js";
12
+ import { lazy } from "../util/lazy.js";
13
13
  export async function publishDeployAssets(sdkProvider, options) {
14
14
  const { deployment, toolkitInfo, stackSdk, resolvedEnvironment, cloudFormationRoleArn, } = await useDeployment().get(sdkProvider, options);
15
15
  // TODO
@@ -60,7 +60,7 @@ export async function publishDeployAssets(sdkProvider, options) {
60
60
  assetParallelism: options.assetParallelism,
61
61
  });
62
62
  }
63
- const useDeployment = Context.memo(() => {
63
+ const useDeployment = lazy(() => {
64
64
  const state = new Map();
65
65
  return {
66
66
  async get(sdkProvider, options) {
@@ -1,3 +1,4 @@
1
+ import { lazy } from "../../util/lazy.js";
1
2
  export const dev = (program) => program.command(["dev", "start"], "Work on your app locally", (yargs) => yargs.option("increase-timeout", {
2
3
  type: "boolean",
3
4
  description: "Increase function timeout",
@@ -29,7 +30,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
29
30
  const { useKyselyTypeGenerator } = await import("./plugins/kysely.js");
30
31
  const { useRDSWarmer } = await import("./plugins/warmer.js");
31
32
  const { useProject } = await import("../../project.js");
32
- const { useMetadata } = await import("../../stacks/metadata.js");
33
+ const { useMetadataCache } = await import("../../stacks/metadata.js");
33
34
  const { useIOT } = await import("../../iot.js");
34
35
  const { clear } = await import("../terminal.js");
35
36
  const { getCiInfo } = await import("../ci-info.js");
@@ -38,7 +39,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
38
39
  console.log(yellow(`Warning: ${bold(`sst start`)} has been renamed to ${bold(`sst dev`)}`));
39
40
  }
40
41
  const project = useProject();
41
- const useFunctionLogger = Context.memo(async () => {
42
+ const useFunctionLogger = lazy(async () => {
42
43
  const bus = useBus();
43
44
  const colors = ["#01cdfe", "#ff71ce", "#05ffa1", "#b967ff"];
44
45
  let index = 0;
@@ -138,7 +139,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
138
139
  }, 100);
139
140
  });
140
141
  });
141
- const useStackBuilder = Context.memo(async () => {
142
+ const useStackBuilder = lazy(async () => {
142
143
  const watcher = useWatcher();
143
144
  const scriptVersion = Date.now().toString();
144
145
  let lastDeployed;
@@ -277,7 +278,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
277
278
  });
278
279
  await build();
279
280
  });
280
- const useDisconnector = Context.memo(async () => {
281
+ const useDisconnector = lazy(async () => {
281
282
  const bus = useBus();
282
283
  const iot = await useIOT();
283
284
  bus.subscribe("cli.dev", async (evt) => {
@@ -338,7 +339,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
338
339
  useIOTBridge(),
339
340
  useRuntimeServer(),
340
341
  usePothosBuilder(),
341
- useMetadata(),
342
+ useMetadataCache(),
342
343
  useKyselyTypeGenerator(),
343
344
  useRDSWarmer(),
344
345
  useFunctionLogger(),
@@ -3,11 +3,11 @@ import { DataApiDialect } from "kysely-data-api";
3
3
  import { RDSData } from "@aws-sdk/client-rds-data";
4
4
  import * as fs from "fs/promises";
5
5
  import { PostgresDialect, MysqlDialect, Serializer, Transformer, } from "kysely-codegen";
6
- import { Context } from "../../../context/context.js";
7
6
  import { useBus } from "../../../bus.js";
8
7
  import { Logger } from "../../../logger.js";
9
8
  import { useAWSClient } from "../../../credentials.js";
10
- export const useKyselyTypeGenerator = Context.memo(async () => {
9
+ import { lazy } from "../../../util/lazy.js";
10
+ export const useKyselyTypeGenerator = lazy(async () => {
11
11
  let databases = [];
12
12
  const bus = useBus();
13
13
  const logger = Logger.debug.bind(null, "[kysely-codegen]");
@@ -1,5 +1,4 @@
1
1
  import { useBus } from "../../../bus.js";
2
- import { Context } from "../../../context/context.js";
3
2
  import { Pothos } from "../../../pothos.js";
4
3
  import fs from "fs/promises";
5
4
  import { exec } from "child_process";
@@ -7,7 +6,8 @@ import { promisify } from "util";
7
6
  const execAsync = promisify(exec);
8
7
  import path from "path";
9
8
  import { Colors } from "../../colors.js";
10
- export const usePothosBuilder = Context.memo(() => {
9
+ import { lazy } from "../../../util/lazy.js";
10
+ export const usePothosBuilder = lazy(() => {
11
11
  let routes = [];
12
12
  const bus = useBus();
13
13
  async function build(route) {
@@ -1,8 +1,8 @@
1
1
  import { useBus } from "../../../bus.js";
2
- import { Context } from "../../../context/context.js";
3
2
  import { RDSDataClient, ExecuteStatementCommand, } from "@aws-sdk/client-rds-data";
4
3
  import { useAWSClient } from "../../../credentials.js";
5
- export const useRDSWarmer = Context.memo(async () => {
4
+ import { lazy } from "../../../util/lazy.js";
5
+ export const useRDSWarmer = lazy(async () => {
6
6
  let interval;
7
7
  const bus = useBus();
8
8
  const client = useAWSClient(RDSDataClient);
@@ -12,9 +12,8 @@ import { sync } from "cross-spawn";
12
12
  import { useProject } from "../../project.js";
13
13
  import { useBus } from "../../bus.js";
14
14
  import getPort from "get-port";
15
- import { Context } from "../../context/context.js";
16
- export const useLocalServerConfig = Context.memo(async () => {
17
- const project = useProject();
15
+ import { lazy } from "../../util/lazy.js";
16
+ export const useLocalServerConfig = lazy(async () => {
18
17
  const port = await getPort({
19
18
  port: 13557,
20
19
  });
@@ -104,28 +103,29 @@ export async function useLocalServer(opts) {
104
103
  const wss = new WebSocketServer({ noServer: true });
105
104
  const wss2 = new WebSocketServer({ noServer: true });
106
105
  const sockets = new Set();
107
- let buffer = [
108
- {
109
- type: "cli.dev",
110
- properties: {
111
- stage: project.config.stage,
112
- app: project.config.name,
113
- },
114
- },
115
- ];
116
- function publish(type, properties) {
117
- const msg = {
118
- type,
119
- properties,
120
- };
121
- buffer.push(msg);
122
- const json = JSON.stringify(msg);
106
+ let invocations = [];
107
+ function publish(invocation) {
108
+ invocations.push(invocation);
109
+ const json = JSON.stringify({
110
+ type: "invocation",
111
+ properties: [invocation],
112
+ });
123
113
  [...sockets.values()].map((s) => s.send(json));
124
114
  }
125
115
  wss2.on("connection", (socket, req) => {
126
116
  sockets.add(socket);
127
- for (const msg of buffer) {
128
- socket.send(JSON.stringify(msg));
117
+ socket.send(JSON.stringify({
118
+ type: "cli.dev",
119
+ properties: {
120
+ app: project.config.name,
121
+ stage: project.config.stage,
122
+ },
123
+ }));
124
+ for (const invocation of invocations) {
125
+ socket.send(JSON.stringify({
126
+ type: "invocation",
127
+ properties: [invocation],
128
+ }));
129
129
  }
130
130
  socket.on("close", () => {
131
131
  sockets.delete(socket);
@@ -133,7 +133,11 @@ export async function useLocalServer(opts) {
133
133
  socket.on("message", (data) => {
134
134
  const parsed = JSON.parse(data.toString());
135
135
  if (parsed.type === "log.cleared") {
136
- buffer = buffer.filter((msg) => msg.properties?.functionID !== parsed.properties?.functionID);
136
+ if (parsed.properties.source === "all") {
137
+ invocations = [];
138
+ return;
139
+ }
140
+ invocations = invocations.filter((item) => item.source === parsed.properties.source);
137
141
  }
138
142
  });
139
143
  });
@@ -207,7 +211,15 @@ export async function useLocalServer(opts) {
207
211
  });
208
212
  }
209
213
  bus.subscribe("function.invoked", async (evt) => {
210
- publish("function.invoked", evt.properties);
214
+ publish({
215
+ start: Date.now(),
216
+ cold: false,
217
+ input: evt.properties.event,
218
+ id: evt.properties.requestID,
219
+ errors: [],
220
+ logs: [],
221
+ source: evt.properties.functionID,
222
+ });
211
223
  updateFunction(evt.properties.functionID, (draft) => {
212
224
  if (draft.invocations.length >= 25)
213
225
  draft.invocations.pop();
@@ -222,7 +234,15 @@ export async function useLocalServer(opts) {
222
234
  });
223
235
  });
224
236
  bus.subscribe("worker.stdout", (evt) => {
225
- publish("worker.stdout", evt.properties);
237
+ const invocation = invocations.findLast((i) => i.source === evt.properties.functionID);
238
+ if (invocation) {
239
+ invocation.logs.push({
240
+ id: Math.random().toString(),
241
+ message: evt.properties.message,
242
+ timestamp: Date.now(),
243
+ });
244
+ publish(invocation);
245
+ }
226
246
  updateFunction(evt.properties.functionID, (draft) => {
227
247
  const entry = draft.invocations.find((i) => i.id === evt.properties.requestID);
228
248
  if (!entry)
@@ -234,7 +254,18 @@ export async function useLocalServer(opts) {
234
254
  });
235
255
  });
236
256
  bus.subscribe("function.success", (evt) => {
237
- publish("function.success", evt.properties);
257
+ const invocation = invocations.findLast((i) => i.source === evt.properties.functionID);
258
+ if (invocation) {
259
+ invocation.end = Date.now();
260
+ invocation.report = {
261
+ duration: invocation.end - invocation.start,
262
+ size: 0,
263
+ xray: "",
264
+ memory: 0,
265
+ };
266
+ invocation.output = evt.properties.body;
267
+ publish(invocation);
268
+ }
238
269
  updateFunction(evt.properties.functionID, (draft) => {
239
270
  const invocation = draft.invocations.find((x) => x.id === evt.properties.requestID);
240
271
  if (!invocation)
@@ -247,7 +278,25 @@ export async function useLocalServer(opts) {
247
278
  });
248
279
  });
249
280
  bus.subscribe("function.error", (evt) => {
250
- publish("function.error", evt.properties);
281
+ const invocation = invocations.findLast((i) => i.source === evt.properties.functionID);
282
+ if (invocation) {
283
+ invocation.errors.push({
284
+ id: invocation.id,
285
+ error: evt.properties.errorType,
286
+ message: evt.properties.errorMessage,
287
+ stack: evt.properties.trace.map((t) => ({
288
+ raw: t,
289
+ })),
290
+ });
291
+ invocation.end = Date.now();
292
+ invocation.report = {
293
+ duration: invocation.end - invocation.start,
294
+ size: 0,
295
+ xray: "",
296
+ memory: 0,
297
+ };
298
+ publish(invocation);
299
+ }
251
300
  updateFunction(evt.properties.functionID, (draft) => {
252
301
  const invocation = draft.invocations.find((x) => x.id === evt.properties.requestID);
253
302
  if (!invocation)
package/cli/spinner.js CHANGED
@@ -1,7 +1,7 @@
1
- import { Context } from "../context/context.js";
2
1
  import ora from "ora";
3
2
  import { Colors } from "./colors.js";
4
- export const useSpinners = Context.memo(() => {
3
+ import { lazy } from "../util/lazy.js";
4
+ export const useSpinners = lazy(() => {
5
5
  const spinners = [];
6
6
  return spinners;
7
7
  });
package/constructs/App.js CHANGED
@@ -7,7 +7,7 @@ import { bindParameters, bindType } from "./util/functionBinding.js";
7
7
  import { stack } from "./FunctionalStack.js";
8
8
  import { Auth } from "./Auth.js";
9
9
  import { useDeferredTasks } from "./deferred_task.js";
10
- import { AppContext } from "./context.js";
10
+ import { provideApp } from "./context.js";
11
11
  import { useProject } from "../project.js";
12
12
  import { VisibleError } from "../error.js";
13
13
  import { Logger } from "../logger.js";
@@ -66,7 +66,7 @@ export class App extends CDKApp {
66
66
  */
67
67
  constructor(deployProps, props = {}) {
68
68
  super(props);
69
- AppContext.provide(this);
69
+ provideApp(this);
70
70
  this.appPath = process.cwd();
71
71
  this.mode = deployProps.mode;
72
72
  this.local = this.mode === "dev";
@@ -221,10 +221,11 @@ export class App extends CDKApp {
221
221
  stage: this.stage,
222
222
  bootstrap: bootstrap.bucket,
223
223
  bucket: sourcemaps[0].bucket.bucketName,
224
- functions: sourcemaps.map((s) => [s.arn, s.key]),
224
+ functions: sourcemaps.map((s) => [s.func.functionArn, s.key]),
225
225
  },
226
226
  });
227
227
  resource.node.addDependency(policy);
228
+ sourcemaps.forEach((s) => s.func.node.addDependency(resource));
228
229
  }
229
230
  }
230
231
  // Set removal policy
@@ -673,14 +673,14 @@ export declare class Function extends CDKFunction implements SSTConstruct {
673
673
  export declare const useFunctions: () => {
674
674
  sourcemaps: {
675
675
  add(stack: string, source: {
676
- arn: string;
677
676
  bucket: IBucket;
678
677
  key: string;
678
+ func: Function;
679
679
  }): void;
680
680
  forStack(stack: string): {
681
- arn: string;
682
681
  bucket: IBucket;
683
682
  key: string;
683
+ func: Function;
684
684
  }[];
685
685
  };
686
686
  fromID(id: string): FunctionProps | undefined;
@@ -259,7 +259,7 @@ export class Function extends CDKFunction {
259
259
  useFunctions().sourcemaps.add(stack.stackName, {
260
260
  bucket: asset.bucket,
261
261
  key: asset.s3ObjectKey,
262
- arn: this.functionArn,
262
+ func: this,
263
263
  });
264
264
  }
265
265
  // Update code
@@ -1,8 +1,3 @@
1
1
  import { App } from "./App.js";
2
- export declare const AppContext: {
3
- use(): App;
4
- reset(): void;
5
- provide(value: App): void;
6
- };
7
- export declare const useApp: () => App;
8
- export declare function createAppContext<C>(cb: () => C): () => C;
2
+ export declare function provideApp(app: App): void;
3
+ export declare const createAppContext: <C>(cb: () => C) => () => C;
@@ -1,9 +1,27 @@
1
- import { Context } from "../context/context.js";
2
- export const AppContext = Context.create();
3
- export const useApp = AppContext.use;
4
- export function createAppContext(cb) {
5
- return Context.memo(() => {
6
- AppContext.use();
7
- return cb();
8
- });
1
+ const AppContext = (() => {
2
+ let app;
3
+ const children = new Map();
4
+ return {
5
+ set(input) {
6
+ children.clear();
7
+ app = input;
8
+ },
9
+ get current() {
10
+ return app;
11
+ },
12
+ createAppContext(cb) {
13
+ return () => {
14
+ const exists = children.get(cb);
15
+ if (exists)
16
+ return exists;
17
+ const val = cb();
18
+ children.set(cb, val);
19
+ return val;
20
+ };
21
+ },
22
+ };
23
+ })();
24
+ export function provideApp(app) {
25
+ AppContext.set(app);
9
26
  }
27
+ export const createAppContext = AppContext.createAppContext;
@@ -0,0 +1,16 @@
1
+ export declare class ContextNotFoundError extends Error {
2
+ name: string;
3
+ constructor(name: string);
4
+ }
5
+ export type Context<T> = ReturnType<typeof create<T>>;
6
+ export declare function create<T>(name: string): {
7
+ name: string;
8
+ with<R>(value: T, cb: () => R): R;
9
+ use(): T;
10
+ version(): string;
11
+ };
12
+ export declare function memo<T>(cb: () => T): () => T;
13
+ export declare const Context: {
14
+ create: typeof create;
15
+ memo: typeof memo;
16
+ };
@@ -0,0 +1,108 @@
1
+ import { AsyncLocalStorage } from "async_hooks";
2
+ export class ContextNotFoundError extends Error {
3
+ name;
4
+ constructor(name) {
5
+ super(`${name} context was not provided. It is possible you have multiple versions of SST installed.`);
6
+ this.name = name;
7
+ }
8
+ }
9
+ let count = 0;
10
+ export function create(name) {
11
+ const storage = new AsyncLocalStorage();
12
+ const children = [];
13
+ // notify all memos to reset
14
+ function reset() {
15
+ for (const child of children) {
16
+ child();
17
+ }
18
+ }
19
+ const ctx = {
20
+ name,
21
+ with(value, cb) {
22
+ const version = (++count).toString();
23
+ return storage.run({ value, version }, () => {
24
+ return runWithCleanup(cb, () => reset());
25
+ });
26
+ },
27
+ use() {
28
+ const memo = ContextMemo.getStore();
29
+ // use is being called within a memo, so track dependency
30
+ if (memo) {
31
+ memo.deps.push(ctx);
32
+ children.push(memo.reset);
33
+ }
34
+ const result = storage.getStore();
35
+ if (result === undefined)
36
+ throw new ContextNotFoundError(name);
37
+ return result.value;
38
+ },
39
+ version() {
40
+ const result = storage.getStore();
41
+ if (result === undefined)
42
+ throw new ContextNotFoundError(name);
43
+ return result.version;
44
+ },
45
+ };
46
+ return ctx;
47
+ }
48
+ const ContextMemo = new AsyncLocalStorage();
49
+ export function memo(cb) {
50
+ const deps = [];
51
+ const cache = new Map();
52
+ const children = [];
53
+ let tracked = false;
54
+ function key() {
55
+ return deps.map((dep) => dep.version()).join(",");
56
+ }
57
+ function reset() {
58
+ cache.delete(key());
59
+ for (const child of children) {
60
+ child();
61
+ }
62
+ }
63
+ function save(value) {
64
+ cache.set(key(), value);
65
+ }
66
+ return () => {
67
+ const child = ContextMemo.getStore();
68
+ if (child) {
69
+ child.deps.push({ version: () => key() });
70
+ children.push(child.reset);
71
+ }
72
+ // Memo never run so build up dependency list
73
+ if (!tracked) {
74
+ return ContextMemo.run({ deps, reset }, () => {
75
+ return runWithCleanup(cb, (result) => {
76
+ tracked = true;
77
+ save(result);
78
+ });
79
+ });
80
+ }
81
+ const cached = cache.get(key());
82
+ if (cached) {
83
+ return cached;
84
+ }
85
+ const result = cb();
86
+ save(result);
87
+ return result;
88
+ };
89
+ }
90
+ function runWithCleanup(cb, cleanup) {
91
+ const result = cb();
92
+ if (result &&
93
+ typeof result === "object" &&
94
+ "then" in result &&
95
+ typeof result.then === "function") {
96
+ return result.then((value) => {
97
+ // cleanup
98
+ cleanup(result);
99
+ return value;
100
+ });
101
+ }
102
+ cleanup(result);
103
+ return result;
104
+ }
105
+ export const Context = {
106
+ create,
107
+ memo,
108
+ };
@@ -1,5 +1,5 @@
1
- import { Context } from "./context.js";
2
- const RequestContext = Context.create("RequestContext");
1
+ import { create } from "./context2.js";
2
+ const RequestContext = create("RequestContext");
3
3
  export function useContextType() {
4
4
  const ctx = RequestContext.use();
5
5
  return ctx.type;
@@ -16,7 +16,6 @@ export function useLambdaContext() {
16
16
  }
17
17
  export function Handler(type, cb) {
18
18
  return function handler(event, context) {
19
- RequestContext.provide({ type, event: event, context });
20
- return cb(event, context);
19
+ return RequestContext.with({ type, event: event, context }, () => cb(event, context));
21
20
  };
22
21
  }
package/credentials.d.ts CHANGED
@@ -1,16 +1,9 @@
1
- import { Client } from "@aws-sdk/smithy-client";
2
- import { RegionInputConfig } from "@aws-sdk/config-resolver";
3
- import { RetryInputConfig } from "@aws-sdk/middleware-retry";
4
- import { AwsAuthInputConfig } from "@aws-sdk/middleware-signing";
5
1
  import { SdkProvider } from "sst-aws-cdk/lib/api/aws-auth/sdk-provider.js";
6
- type Config = RegionInputConfig & RetryInputConfig & AwsAuthInputConfig & HostHeaderConditionConfig;
7
- export declare const useAWSCredentialsProvider: () => import("@aws-sdk/types").AwsCredentialIdentityProvider;
8
- export declare const useAWSCredentials: () => Promise<import("@aws-sdk/types").AwsCredentialIdentity>;
2
+ export declare const useAWSCredentialsProvider: () => import("@smithy/types").AwsCredentialIdentityProvider;
3
+ export declare const useAWSCredentials: () => Promise<import("@smithy/types").AwsCredentialIdentity>;
9
4
  export declare const useSTSIdentity: () => Promise<import("@aws-sdk/client-sts").GetCallerIdentityCommandOutput>;
10
- export declare function useAWSClient<C extends Client<any, any, any, any>>(client: new (config: Config) => C, force?: boolean): C;
11
- import { HostHeaderConditionConfig } from "aws-sdk/clients/elbv2.js";
5
+ export declare function useAWSClient<C extends any>(client: new (config: any) => C, force?: boolean): C;
12
6
  /**
13
7
  * Do not use this. It is only used for AWS CDK compatibility.
14
8
  */
15
9
  export declare const useAWSProvider: () => Promise<SdkProvider>;
16
- export {};
package/credentials.js CHANGED
@@ -1,10 +1,9 @@
1
- import { Context } from "./context/context.js";
2
1
  import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
3
2
  import { GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
4
3
  import { Logger } from "./logger.js";
5
4
  import { SdkProvider } from "sst-aws-cdk/lib/api/aws-auth/sdk-provider.js";
6
5
  import { StandardRetryStrategy } from "@aws-sdk/middleware-retry";
7
- export const useAWSCredentialsProvider = Context.memo(() => {
6
+ export const useAWSCredentialsProvider = lazy(() => {
8
7
  const project = useProject();
9
8
  Logger.debug("Using AWS profile", project.config.profile);
10
9
  const provider = fromNodeProviderChain({
@@ -39,13 +38,13 @@ export const useAWSCredentials = () => {
39
38
  const provider = useAWSCredentialsProvider();
40
39
  return provider();
41
40
  };
42
- export const useSTSIdentity = Context.memo(async () => {
41
+ export const useSTSIdentity = lazy(async () => {
43
42
  const sts = useAWSClient(STSClient);
44
43
  const identity = await sts.send(new GetCallerIdentityCommand({}));
45
44
  Logger.debug("Using identity", "Account:", identity.Account, "User:", identity.UserId);
46
45
  return identity;
47
46
  });
48
- const useClientCache = Context.memo(() => new Map());
47
+ const useClientCache = lazy(() => new Map());
49
48
  export function useAWSClient(client, force = false) {
50
49
  const cache = useClientCache();
51
50
  const existing = cache.get(client.name);
@@ -108,11 +107,12 @@ import stupid from "aws-sdk/lib/maintenance_mode_message.js";
108
107
  stupid.suppress = true;
109
108
  import aws from "aws-sdk";
110
109
  import { useProject } from "./project.js";
110
+ import { lazy } from "./util/lazy.js";
111
111
  const CredentialProviderChain = aws.CredentialProviderChain;
112
112
  /**
113
113
  * Do not use this. It is only used for AWS CDK compatibility.
114
114
  */
115
- export const useAWSProvider = Context.memo(async () => {
115
+ export const useAWSProvider = lazy(async () => {
116
116
  Logger.debug("Loading v2 AWS SDK");
117
117
  const project = useProject();
118
118
  const creds = await useAWSCredentials();