qstd 0.3.86 → 0.3.87

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 * as _t from "./types";
2
+ export declare const create: (props: _t.CreateProps) => _t.Client;
3
+ export declare const createFromRequestContext: (props: _t.RequestContextProps) => _t.Client;
4
+ /**
5
+ * Bind connection lookup and stale cleanup once, then reuse the returned
6
+ * publisher for one-to-one sends and fan-out.
7
+ *
8
+ * Create your API Gateway client and any storage clients once, then create a
9
+ * publisher once and pass that publisher to nested helpers. This keeps the call
10
+ * sites focused on targets and payloads instead of threading the same
11
+ * dependencies through every send.
12
+ *
13
+ * `onGone` is where app-specific cleanup belongs. For example, a DynamoDB-backed
14
+ * app can close over `ddb` there without making the publisher itself depend on
15
+ * DynamoDB types.
16
+ *
17
+ * @example
18
+ * const ddb = DDB.create({ tableName: "app-main" });
19
+ * const apigw = ApiGw.create({ endpoint: process.env.WS_ENDPOINT! });
20
+ *
21
+ * const publisher = ApiGw.createPublisher<Connection, Event>(apigw, {
22
+ * getConnectionId: (connection) => connection.id,
23
+ * onGone: (connection) => removeConnection(ddb, connection.id),
24
+ * });
25
+ *
26
+ * await publisher.send(connection, {
27
+ * data: { type: "subscribed" },
28
+ * });
29
+ *
30
+ * await publisher.broadcast({
31
+ * targets: connections,
32
+ * data: { type: "refresh" },
33
+ * });
34
+ *
35
+ * @example
36
+ * type UploadSessionPublisher = ApiGw.Publisher<
37
+ * UploadSessionConnection,
38
+ * StreamEvent
39
+ * >;
40
+ *
41
+ * const publishSnapshot = async (
42
+ * publisher: UploadSessionPublisher,
43
+ * connection: UploadSessionConnection
44
+ * ) => {
45
+ * const event =
46
+ * connection.scope === "active"
47
+ * ? await createActiveSessionsEvent(ddb)
48
+ * : await createSessionEvent(ddb, connection.sessionId!);
49
+ *
50
+ * await publisher.send(connection, { data: event });
51
+ * };
52
+ */
53
+ export declare const createPublisher: <T, TData = unknown>(apigw: _t.Client, props: _t.CreatePublisherProps<T>) => _t.Publisher<T, TData>;
54
+ export declare const send: (apigw: _t.Client, props: _t.SendProps) => Promise<boolean>;
55
+ export declare const deleteConnection: (apigw: _t.Client, props: _t.DeleteConnectionProps) => Promise<import("@aws-sdk/client-apigatewaymanagementapi").DeleteConnectionCommandOutput>;
56
+ export declare const broadcast: <T, TData = unknown>(apigw: _t.Client, props: _t.BroadcastProps<T, TData>) => Promise<_t.BroadcastResult<T>>;
57
+ //# sourceMappingURL=domain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/apigw/domain.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,eAAO,MAAM,MAAM,GAAI,OAAO,EAAE,CAAC,WAAW,KAAG,EAAE,CAAC,MAKjD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,OAAO,EAAE,CAAC,mBAAmB,cAErE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,KAAK,GAAG,OAAO,EAChD,OAAO,EAAE,CAAC,MAAM,EAChB,OAAO,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,KAChC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAoBvB,CAAC;AAEF,eAAO,MAAM,IAAI,GAAU,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,SAAS,qBAiB/D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,EAAE,CAAC,MAAM,EAChB,OAAO,EAAE,CAAC,qBAAqB,6FAOhC,CAAC;AAEF,eAAO,MAAM,SAAS,GAAU,CAAC,EAAE,KAAK,GAAG,OAAO,EAChD,OAAO,EAAE,CAAC,MAAM,EAChB,OAAO,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,mCAgEnC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import * as _t from "./types";
2
+ export declare const getManagementEndpoint: (props: _t.RequestContextProps) => string;
3
+ export declare const isGoneConnectionError: (error: unknown) => boolean;
4
+ export declare const encodeData: (data: unknown) => _t.EncodedPayload;
5
+ export declare const runWithConcurrency: <T>(items: readonly T[], concurrency: number, fn: (item: T) => Promise<void>) => Promise<void>;
6
+ //# sourceMappingURL=fns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fns.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/apigw/fns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAI9B,eAAO,MAAM,qBAAqB,GAAI,OAAO,EAAE,CAAC,mBAAmB,WAgBlE,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,OAAO,OAAO,YAQnD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,OAAO,KAAG,EAAE,CAAC,cAmB7C,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,CAAC,EACxC,OAAO,SAAS,CAAC,EAAE,EACnB,aAAa,MAAM,EACnB,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,kBAc/B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./domain";
2
+ export * from "./types";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/apigw/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
@@ -0,0 +1,113 @@
1
+ import type { ApiGatewayManagementApiClient, DeleteConnectionCommandOutput } from "@aws-sdk/client-apigatewaymanagementapi";
2
+ import type { APIGatewayProxyEvent } from "aws-lambda";
3
+ export type RawClient = Pick<ApiGatewayManagementApiClient, "send">;
4
+ export type Client = {
5
+ client: RawClient;
6
+ endpoint: string;
7
+ };
8
+ export type CreateProps = {
9
+ endpoint: string;
10
+ };
11
+ export type RequestContextProps = Pick<APIGatewayProxyEvent["requestContext"], "domainName" | "stage"> & {
12
+ protocol?: "http" | "https";
13
+ basePath?: string;
14
+ };
15
+ export type EncodedPayload = string | Uint8Array;
16
+ export type SendProps = {
17
+ onGone?: (connectionId: string) => Promise<void> | void;
18
+ connectionId: string;
19
+ data: unknown;
20
+ };
21
+ export type DeleteConnectionProps = {
22
+ connectionId: string;
23
+ };
24
+ export type DeleteConnectionResult = DeleteConnectionCommandOutput;
25
+ export type BroadcastStale<T> = {
26
+ connectionId: string;
27
+ target: T;
28
+ };
29
+ export type BroadcastFailure<T> = {
30
+ connectionId: string;
31
+ error: unknown;
32
+ target: T;
33
+ };
34
+ export type BroadcastResult<T> = {
35
+ failed: BroadcastFailure<T>[];
36
+ stale: BroadcastStale<T>[];
37
+ sent: number;
38
+ };
39
+ type Awaitable<T> = T | PromiseLike<T>;
40
+ type BroadcastSharedProps<T> = {
41
+ getConnectionId: (target: T) => string;
42
+ onGone?: (target: T) => Promise<void> | void;
43
+ targets: readonly T[];
44
+ concurrency?: number;
45
+ };
46
+ export type BroadcastConstantDataProps<T> = BroadcastSharedProps<T> & {
47
+ getCacheKey?: never;
48
+ getData?: never;
49
+ data: unknown;
50
+ };
51
+ export type BroadcastDynamicDataProps<T, TData = unknown> = BroadcastSharedProps<T> & {
52
+ getData: (target: T) => Awaitable<TData>;
53
+ getCacheKey?: (target: T) => string | number | null | undefined;
54
+ data?: never;
55
+ };
56
+ export type BroadcastProps<T, TData = unknown> = BroadcastConstantDataProps<T> | BroadcastDynamicDataProps<T, TData>;
57
+ /**
58
+ * Configuration for a bound websocket publisher.
59
+ *
60
+ * `qstd` intentionally asks only for connection lookup and stale-target cleanup.
61
+ * Any storage details, such as DynamoDB removal, live in the `onGone` closure so
62
+ * the publisher can stay generic across apps and persistence layers.
63
+ */
64
+ export type CreatePublisherProps<T> = {
65
+ /** Extract the API Gateway connection ID from your app's target shape. */
66
+ getConnectionId: (target: T) => string;
67
+ /** Optional stale-target cleanup hook, eg remove a dead connection from DDB. */
68
+ onGone?: (target: T) => Promise<void> | void;
69
+ };
70
+ export type PublisherSendProps<TData = unknown> = {
71
+ data: TData;
72
+ };
73
+ type PublisherBroadcastSharedProps<T> = {
74
+ targets: readonly T[];
75
+ concurrency?: number;
76
+ };
77
+ export type PublisherBroadcastConstantDataProps<T, TData = unknown> = PublisherBroadcastSharedProps<T> & {
78
+ getCacheKey?: never;
79
+ getData?: never;
80
+ data: TData;
81
+ };
82
+ export type PublisherBroadcastDynamicDataProps<T, TData = unknown> = PublisherBroadcastSharedProps<T> & {
83
+ getData: (target: T) => Awaitable<TData>;
84
+ getCacheKey?: (target: T) => string | number | null | undefined;
85
+ data?: never;
86
+ };
87
+ export type PublisherBroadcastProps<T, TData = unknown> = PublisherBroadcastConstantDataProps<T, TData> | PublisherBroadcastDynamicDataProps<T, TData>;
88
+ /**
89
+ * Bound websocket publisher created once per invocation and passed to helpers.
90
+ *
91
+ * The type only needs to describe the target shape and payload shape. Any DDB,
92
+ * SQL, or cache clients used for stale cleanup stay hidden inside the closure
93
+ * captured by `createPublisher()`.
94
+ *
95
+ * @example
96
+ * type Connection = { id: string; roomId: string };
97
+ * type Event = { type: "message"; roomId: string; text: string };
98
+ *
99
+ * const publisher = ApiGw.createPublisher<Connection, Event>(apigw, {
100
+ * getConnectionId: (connection) => connection.id,
101
+ * onGone: (connection) => removeConnection(ddb, connection.id),
102
+ * });
103
+ *
104
+ * await publisher.send(connection, {
105
+ * data: { type: "message", roomId: "abc", text: "hello" },
106
+ * });
107
+ */
108
+ export type Publisher<T, TData = unknown> = {
109
+ send: (target: T, props: PublisherSendProps<TData>) => Promise<boolean>;
110
+ broadcast: (props: PublisherBroadcastProps<T, TData>) => Promise<BroadcastResult<T>>;
111
+ };
112
+ export {};
113
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/apigw/types.ts"],"names":[],"mappings":"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"}
@@ -6,13 +6,13 @@ import * as _t from "./types";
6
6
  * @param fn
7
7
  * @returns
8
8
  */
9
- export declare const createRestHandler: (fn: (event: import("aws-lambda").APIGatewayProxyEventV2) => Promise<_t.ApigwResult> | _t.ApigwResult) => (event: import("aws-lambda").APIGatewayProxyEventV2) => Promise<_t.Response | _t.ApigwResult>;
9
+ export declare const createRestHandler: _t.RestHandlerFactory;
10
10
  /**
11
11
  * Same as rest handler but just receives a websocket event.
12
12
  * @param fn
13
13
  * @returns
14
14
  */
15
- export declare const createWebsocketHandler: (fn: (event: import("aws-lambda").APIGatewayProxyEvent) => Promise<_t.ApigwResult> | _t.ApigwResult) => (event: import("aws-lambda").APIGatewayProxyEvent) => Promise<_t.Response | _t.ApigwResult>;
15
+ export declare const createWebsocketHandler: _t.WebsocketHandlerFactory;
16
16
  /**
17
17
  * Creates a batch failures tracker for SQS handlers.
18
18
  * Provides a simple `add(id)` method instead of pushing objects.
@@ -62,5 +62,5 @@ export declare const withBatchFailures: () => {
62
62
  * });
63
63
  * ```
64
64
  */
65
- export declare const createSqsHandler: (fn: _t.SqsHandlerFn) => _t.SqsHandlerFn;
65
+ export declare const createSqsHandler: _t.SqsHandlerFactory;
66
66
  //# sourceMappingURL=domain.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/lambda/domain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAG9B;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,6GA0EkC,kDAAO,0CA1EE,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,2GAmE6B,gDAAO,0CAlEzB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB;IAG1B,0GAA0G;0BACpF,MAAM;IAG5B,0CAA0C;;CAG7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gBAAgB,GAC1B,IAAI,EAAE,CAAC,YAAY,KAAG,EAAE,CAAC,YAazB,CAAC"}
1
+ {"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/lambda/domain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAG9B;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,kBACO,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,EAAE,CAAC,uBACM,CAAC;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB;IAG1B,0GAA0G;0BACpF,MAAM;IAG5B,0CAA0C;;CAG7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,iBAc/B,CAAC"}
@@ -30,5 +30,5 @@ responseBody?: T, opts?: _t.ResponseOptions) => _t.Response;
30
30
  * handle things like HTTP errors and Arktype validation errors,
31
31
  * @returns
32
32
  */
33
- export declare const createHandlerFactory: <T extends _t.ApigwEvent | _t.WebsocketEvent>() => (fn: (event: T) => Promise<_t.ApigwResult> | _t.ApigwResult) => (event: T) => Promise<_t.Response | _t.ApigwResult>;
33
+ export declare const createHandlerFactory: <T extends _t.ApigwEvent | _t.WebsocketEvent>() => _t.HandlerFactory<T>;
34
34
  //# sourceMappingURL=fns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fns.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/lambda/fns.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,OAAO,EAAE,UAAU,EAAE,CAAC,eAAe,KAAG,MAK3E,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAM,EAAE,CAAC,eAAoB;;;;;;CAU7D,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,OAAO;AAClC,qCAAqC;AACrC,eAAe,CAAC,EAChB,OAAO,EAAE,CAAC,eAAe,KACxB,EAAE,CAAC,QAWL,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC9B,CAAC,SAAS,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,cAAc,QAC3C,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,WAAW,MACpD,OAAO,CAAC,0CAsBd,CAAC"}
1
+ {"version":3,"file":"fns.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/lambda/fns.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,OAAO,EAAE,UAAU,EAAE,CAAC,eAAe,KAAG,MAK3E,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAM,EAAE,CAAC,eAAoB;;;;;;CAU7D,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,OAAO;AAClC,qCAAqC;AACrC,eAAe,CAAC,EAChB,OAAO,EAAE,CAAC,eAAe,KACxB,EAAE,CAAC,QAWL,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC9B,CAAC,SAAS,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,cAAc,OAAK,EAAE,CAAC,cAAc,CAAC,CAAC,CAwBnE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export { HttpError } from "./literals";
2
2
  export { response } from "./fns";
3
3
  export * from "./domain";
4
+ export * from "./types";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/lambda/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/lambda/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
@@ -26,10 +26,21 @@ export type Response = {
26
26
  export type WebsocketEvent = APIGatewayProxyEvent;
27
27
  export type ApigwEvent = APIGatewayProxyEventV2;
28
28
  export type ApigwResult = APIGatewayProxyResultV2;
29
+ export type HandlerResult = Response | ApigwResult;
30
+ export type HandlerFn<T extends ApigwEvent | WebsocketEvent> = (event: T) => Promise<ApigwResult> | ApigwResult;
31
+ export type Handler<T extends ApigwEvent | WebsocketEvent> = (event: T) => Promise<HandlerResult>;
32
+ export type HandlerFactory<T extends ApigwEvent | WebsocketEvent> = (fn: HandlerFn<T>) => Handler<T>;
33
+ export type RestHandlerFn = HandlerFn<ApigwEvent>;
34
+ export type RestHandler = Handler<ApigwEvent>;
35
+ export type RestHandlerFactory = HandlerFactory<ApigwEvent>;
36
+ export type WebsocketHandlerFn = HandlerFn<WebsocketEvent>;
37
+ export type WebsocketHandler = Handler<WebsocketEvent>;
38
+ export type WebsocketHandlerFactory = HandlerFactory<WebsocketEvent>;
29
39
  export type SqsEvent = SQSEvent;
30
40
  export type SqsContext = Context;
31
41
  export type SQSHandler = AwsSqsHandler;
32
42
  export type SqsCallback = Callback<SQSBatchResponse | void>;
43
+ export type SqsHandlerFactory = (fn: SqsHandlerFn) => SqsHandlerFn;
33
44
  export type ResponseOptions = {
34
45
  /**
35
46
  * `200` - **Ok**: request succeeded and there is a response payload.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/lambda/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,UAAU,IAAI,aAAa,EAC3B,mBAAmB,EACnB,gBAAgB,EAChB,QAAQ,EACR,OAAO,EACP,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB,yDAAyD;AACzD,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEhD,+DAA+D;AAC/D,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AAEtD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;IACtD,iBAAiB,EAAE,mBAAmB,EAAE,CAAC;CAC1C,CAAC,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,6BAA6B,EAAE,MAAM,CAAC;QACtC,8BAA8B,EAAE,MAAM,CAAC;QACvC,8BAA8B,EAAE,MAAM,CAAC;QACvC,kCAAkC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtD,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAChD,MAAM,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAElD,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAChC,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC;AACjC,MAAM,MAAM,UAAU,GAAG,aAAa,CAAC;AAEvC,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG;IAC5B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACzE,iBAAiB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAE9C,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAE/B,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;SAGK;IACL,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uGAAuG;IACvG,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/lambda/types.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ var dateFns = require('date-fns');
4
4
  var awaitSpawn = require('await-spawn');
5
5
  var fs = require('fs');
6
6
  var arktype = require('arktype');
7
+ var clientApigatewaymanagementapi = require('@aws-sdk/client-apigatewaymanagementapi');
7
8
  var libDynamodb = require('@aws-sdk/lib-dynamodb');
8
9
  var clientDynamodb = require('@aws-sdk/client-dynamodb');
9
10
  var signale = require('signale');
@@ -1348,6 +1349,176 @@ var createSqsHandler = (fn) => async (event) => {
1348
1349
  return result;
1349
1350
  };
1350
1351
 
1352
+ // src/server/aws/apigw/index.ts
1353
+ var apigw_exports = {};
1354
+ __export(apigw_exports, {
1355
+ broadcast: () => broadcast,
1356
+ create: () => create2,
1357
+ createFromRequestContext: () => createFromRequestContext,
1358
+ createPublisher: () => createPublisher,
1359
+ deleteConnection: () => deleteConnection,
1360
+ send: () => send
1361
+ });
1362
+
1363
+ // src/server/aws/apigw/fns.ts
1364
+ var normalizePath = (path) => path.replace(/^\/+|\/+$/g, "");
1365
+ var getManagementEndpoint = (props) => {
1366
+ const domainName = props.domainName;
1367
+ if (!domainName) {
1368
+ throw new Error("Missing websocket domain name");
1369
+ }
1370
+ const rawPath = props.basePath ?? props.stage;
1371
+ if (rawPath == null) {
1372
+ throw new Error("Missing websocket stage or base path");
1373
+ }
1374
+ const protocol = props.protocol ?? "https";
1375
+ const path = normalizePath(rawPath);
1376
+ return path ? `${protocol}://${domainName}/${path}` : `${protocol}://${domainName}`;
1377
+ };
1378
+ var isGoneConnectionError = (error2) => {
1379
+ return !!(error2 && typeof error2 === "object" && "$metadata" in error2 && error2.$metadata?.httpStatusCode === 410);
1380
+ };
1381
+ var encodeData = (data) => {
1382
+ if (typeof data === "string") {
1383
+ return data;
1384
+ }
1385
+ if (data instanceof Uint8Array) {
1386
+ return data;
1387
+ }
1388
+ if (data instanceof ArrayBuffer) {
1389
+ return new Uint8Array(data);
1390
+ }
1391
+ if (ArrayBuffer.isView(data)) {
1392
+ return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
1393
+ }
1394
+ const encoded = JSON.stringify(data);
1395
+ if (encoded === void 0) {
1396
+ throw new Error("Websocket payload must be JSON serializable");
1397
+ }
1398
+ return encoded;
1399
+ };
1400
+ var runWithConcurrency = async (items, concurrency, fn) => {
1401
+ const limit = Math.max(1, concurrency);
1402
+ let nextIndex = 0;
1403
+ await Promise.all(
1404
+ Array.from({ length: Math.min(limit, items.length) }, async () => {
1405
+ while (nextIndex < items.length) {
1406
+ const currentIndex = nextIndex;
1407
+ nextIndex += 1;
1408
+ await fn(items[currentIndex]);
1409
+ }
1410
+ })
1411
+ );
1412
+ };
1413
+
1414
+ // src/server/aws/apigw/domain.ts
1415
+ var create2 = (props) => {
1416
+ const client = new clientApigatewaymanagementapi.ApiGatewayManagementApiClient({
1417
+ endpoint: props.endpoint
1418
+ });
1419
+ return { client, endpoint: props.endpoint };
1420
+ };
1421
+ var createFromRequestContext = (props) => {
1422
+ return create2({ endpoint: getManagementEndpoint(props) });
1423
+ };
1424
+ var createPublisher = (apigw, props) => {
1425
+ const getConnectionId = props.getConnectionId;
1426
+ const onGone = props.onGone;
1427
+ return {
1428
+ send: (target, sendProps) => {
1429
+ return send(apigw, {
1430
+ connectionId: getConnectionId(target),
1431
+ data: sendProps.data,
1432
+ onGone: onGone ? () => onGone(target) : void 0
1433
+ });
1434
+ },
1435
+ broadcast: (broadcastProps) => {
1436
+ return broadcast(apigw, {
1437
+ ...broadcastProps,
1438
+ getConnectionId,
1439
+ onGone
1440
+ });
1441
+ }
1442
+ };
1443
+ };
1444
+ var send = async (apigw, props) => {
1445
+ try {
1446
+ await apigw.client.send(
1447
+ new clientApigatewaymanagementapi.PostToConnectionCommand({
1448
+ ConnectionId: props.connectionId,
1449
+ Data: encodeData(props.data)
1450
+ })
1451
+ );
1452
+ } catch (error2) {
1453
+ if (isGoneConnectionError(error2)) {
1454
+ await props.onGone?.(props.connectionId);
1455
+ return false;
1456
+ }
1457
+ throw error2;
1458
+ }
1459
+ return true;
1460
+ };
1461
+ var deleteConnection = (apigw, props) => {
1462
+ return apigw.client.send(
1463
+ new clientApigatewaymanagementapi.DeleteConnectionCommand({
1464
+ ConnectionId: props.connectionId
1465
+ })
1466
+ );
1467
+ };
1468
+ var broadcast = async (apigw, props) => {
1469
+ const result = {
1470
+ failed: [],
1471
+ stale: [],
1472
+ sent: 0
1473
+ };
1474
+ const sharedData = "data" in props ? encodeData(props.data) : null;
1475
+ const getData = "getData" in props ? props.getData : null;
1476
+ const getCacheKey = "getCacheKey" in props ? props.getCacheKey : void 0;
1477
+ const onGone = props.onGone;
1478
+ const cache = /* @__PURE__ */ new Map();
1479
+ const resolveData = async (target) => {
1480
+ if (sharedData !== null) {
1481
+ return sharedData;
1482
+ }
1483
+ if (!getData) {
1484
+ throw new Error("Missing websocket broadcast payload builder");
1485
+ }
1486
+ const cacheKey = getCacheKey?.(target);
1487
+ if (cacheKey == null) {
1488
+ return encodeData(await getData(target));
1489
+ }
1490
+ const existing = cache.get(cacheKey);
1491
+ if (existing) {
1492
+ return existing;
1493
+ }
1494
+ const promise = Promise.resolve(getData(target)).then(encodeData);
1495
+ cache.set(cacheKey, promise);
1496
+ return promise;
1497
+ };
1498
+ await runWithConcurrency(
1499
+ props.targets,
1500
+ props.concurrency ?? 25,
1501
+ async (target) => {
1502
+ const connectionId = props.getConnectionId(target);
1503
+ try {
1504
+ const delivered = await send(apigw, {
1505
+ connectionId,
1506
+ data: await resolveData(target),
1507
+ onGone: onGone ? () => onGone(target) : void 0
1508
+ });
1509
+ if (!delivered) {
1510
+ result.stale.push({ connectionId, target });
1511
+ return;
1512
+ }
1513
+ result.sent += 1;
1514
+ } catch (error2) {
1515
+ result.failed.push({ connectionId, error: error2, target });
1516
+ }
1517
+ }
1518
+ );
1519
+ return result;
1520
+ };
1521
+
1351
1522
  // src/server/aws/ddb/index.ts
1352
1523
  var ddb_exports = {};
1353
1524
  __export(ddb_exports, {
@@ -1355,7 +1526,7 @@ __export(ddb_exports, {
1355
1526
  batchGet: () => batchGet,
1356
1527
  batchWrite: () => batchWrite,
1357
1528
  copyTable: () => copyTable,
1358
- create: () => create2,
1529
+ create: () => create3,
1359
1530
  deleteTable: () => deleteTable,
1360
1531
  find: () => find,
1361
1532
  lsi1: () => lsi1,
@@ -1639,7 +1810,7 @@ var buildUpdateExpression = (ops, names, values) => {
1639
1810
  };
1640
1811
 
1641
1812
  // src/server/aws/ddb/domain.ts
1642
- var create2 = (props) => {
1813
+ var create3 = (props) => {
1643
1814
  const tableName = props?.tableName;
1644
1815
  const credentials = props?.credentials;
1645
1816
  const client = libDynamodb.DynamoDBDocumentClient.from(
@@ -2521,11 +2692,11 @@ var copyTable = async (props) => {
2521
2692
  // src/server/aws/sns/index.ts
2522
2693
  var sns_exports = {};
2523
2694
  __export(sns_exports, {
2524
- create: () => create3,
2695
+ create: () => create4,
2525
2696
  publish: () => publish,
2526
2697
  publishError: () => publishError
2527
2698
  });
2528
- var create3 = (props) => {
2699
+ var create4 = (props) => {
2529
2700
  const client = new clientSns.SNSClient({});
2530
2701
  return { client, topicArn: props?.topicArn };
2531
2702
  };
@@ -2560,8 +2731,8 @@ var publishError = (sns, props) => {
2560
2731
  // src/server/aws/sqs/index.ts
2561
2732
  var sqs_exports = {};
2562
2733
  __export(sqs_exports, {
2563
- create: () => create4,
2564
- send: () => send
2734
+ create: () => create5,
2735
+ send: () => send2
2565
2736
  });
2566
2737
 
2567
2738
  // src/server/aws/sqs/fns.ts
@@ -2575,12 +2746,12 @@ var getQueueUrlOrThrow = (...candidates) => {
2575
2746
  };
2576
2747
 
2577
2748
  // src/server/aws/sqs/domain.ts
2578
- var create4 = (props) => {
2749
+ var create5 = (props) => {
2579
2750
  const client = new clientSqs.SQSClient({});
2580
2751
  const queueUrl = props?.queueUrl;
2581
2752
  return { client, queueUrl };
2582
2753
  };
2583
- var send = (sqs, props) => sqs.client.send(
2754
+ var send2 = (sqs, props) => sqs.client.send(
2584
2755
  new clientSqs.SendMessageCommand({
2585
2756
  MessageBody: JSON.stringify(props.body),
2586
2757
  MessageGroupId: props.messageGroupId,
@@ -2591,16 +2762,16 @@ var send = (sqs, props) => sqs.client.send(
2591
2762
  // src/server/aws/ses/index.ts
2592
2763
  var ses_exports = {};
2593
2764
  __export(ses_exports, {
2594
- create: () => create5,
2595
- send: () => send2
2765
+ create: () => create6,
2766
+ send: () => send3
2596
2767
  });
2597
2768
 
2598
2769
  // src/server/aws/ses/fns.ts
2599
2770
  var stripHtml = (html) => html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<[^>]+>/g, " ").replace(/&nbsp;/g, " ").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/\s+/g, " ").trim();
2600
2771
 
2601
2772
  // src/server/aws/ses/index.ts
2602
- var create5 = () => new clientSes.SESClient({ apiVersion: "2010-12-01" });
2603
- var send2 = (ses, email) => {
2773
+ var create6 = () => new clientSes.SESClient({ apiVersion: "2010-12-01" });
2774
+ var send3 = (ses, email) => {
2604
2775
  const Source = `"${email.fromName}" <${email.from}>`;
2605
2776
  console.log(`[ses] Sending email to ${email.to} from ${email.from}`);
2606
2777
  const Destination = { ToAddresses: [email.to] };
@@ -2625,7 +2796,7 @@ var s3_exports = {};
2625
2796
  __export(s3_exports, {
2626
2797
  bucketExists: () => bucketExists,
2627
2798
  copyFile: () => copyFile,
2628
- create: () => create6,
2799
+ create: () => create7,
2629
2800
  createBucket: () => createBucket,
2630
2801
  createSignedUrl: () => createSignedUrl,
2631
2802
  deleteBucket: () => deleteBucket,
@@ -2652,7 +2823,7 @@ var getBucketNameOrThrow = (...candidates) => {
2652
2823
  };
2653
2824
 
2654
2825
  // src/server/aws/s3/domain.ts
2655
- var create6 = (props = {}) => {
2826
+ var create7 = (props = {}) => {
2656
2827
  const { cdn } = props;
2657
2828
  const client = new clientS3.S3Client({});
2658
2829
  const bucketName = getBucketNameOrThrow(props.bucketName);
@@ -2908,6 +3079,7 @@ var recordsFromSqs = (body) => {
2908
3079
  };
2909
3080
 
2910
3081
  exports.Api = api_exports;
3082
+ exports.ApiGw = apigw_exports;
2911
3083
  exports.DDB = ddb_exports;
2912
3084
  exports.Dict = dict_exports;
2913
3085
  exports.File = file_exports;
@@ -12,6 +12,7 @@ export * as LexoRank from "../shared/lexorank";
12
12
  export * as Os from "./os";
13
13
  export * as File from "./file";
14
14
  export * as Lambda from "./aws/lambda";
15
+ export * as ApiGw from "./aws/apigw";
15
16
  export * as DDB from "./aws/ddb";
16
17
  export * as SNS from "./aws/sns";
17
18
  export * as SQS from "./aws/sqs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,iBAAiB,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAC;AAG/C,OAAO,KAAK,EAAE,MAAM,MAAM,CAAC;AAC3B,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,iBAAiB,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAC;AAG/C,OAAO,KAAK,EAAE,MAAM,MAAM,CAAC;AAC3B,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC"}
@@ -2,6 +2,7 @@ import { parse, format, formatISO, formatDistanceToNow, isSameYear, isSameMonth,
2
2
  import awaitSpawn from 'await-spawn';
3
3
  import { promises } from 'fs';
4
4
  import { ArkErrors } from 'arktype';
5
+ import { ApiGatewayManagementApiClient, PostToConnectionCommand, DeleteConnectionCommand } from '@aws-sdk/client-apigatewaymanagementapi';
5
6
  import { DynamoDBDocumentClient, ScanCommand, QueryCommand, DeleteCommand, PutCommand, UpdateCommand, BatchGetCommand, TransactWriteCommand, BatchWriteCommand } from '@aws-sdk/lib-dynamodb';
6
7
  import { ReturnValue, DynamoDBClient, DeleteTableCommand, DescribeTableCommand, DynamoDBServiceException, CreateTableCommand, DescribeContinuousBackupsCommand, UpdateContinuousBackupsCommand, waitUntilTableExists } from '@aws-sdk/client-dynamodb';
7
8
  import signale from 'signale';
@@ -1340,6 +1341,176 @@ var createSqsHandler = (fn) => async (event) => {
1340
1341
  return result;
1341
1342
  };
1342
1343
 
1344
+ // src/server/aws/apigw/index.ts
1345
+ var apigw_exports = {};
1346
+ __export(apigw_exports, {
1347
+ broadcast: () => broadcast,
1348
+ create: () => create2,
1349
+ createFromRequestContext: () => createFromRequestContext,
1350
+ createPublisher: () => createPublisher,
1351
+ deleteConnection: () => deleteConnection,
1352
+ send: () => send
1353
+ });
1354
+
1355
+ // src/server/aws/apigw/fns.ts
1356
+ var normalizePath = (path) => path.replace(/^\/+|\/+$/g, "");
1357
+ var getManagementEndpoint = (props) => {
1358
+ const domainName = props.domainName;
1359
+ if (!domainName) {
1360
+ throw new Error("Missing websocket domain name");
1361
+ }
1362
+ const rawPath = props.basePath ?? props.stage;
1363
+ if (rawPath == null) {
1364
+ throw new Error("Missing websocket stage or base path");
1365
+ }
1366
+ const protocol = props.protocol ?? "https";
1367
+ const path = normalizePath(rawPath);
1368
+ return path ? `${protocol}://${domainName}/${path}` : `${protocol}://${domainName}`;
1369
+ };
1370
+ var isGoneConnectionError = (error2) => {
1371
+ return !!(error2 && typeof error2 === "object" && "$metadata" in error2 && error2.$metadata?.httpStatusCode === 410);
1372
+ };
1373
+ var encodeData = (data) => {
1374
+ if (typeof data === "string") {
1375
+ return data;
1376
+ }
1377
+ if (data instanceof Uint8Array) {
1378
+ return data;
1379
+ }
1380
+ if (data instanceof ArrayBuffer) {
1381
+ return new Uint8Array(data);
1382
+ }
1383
+ if (ArrayBuffer.isView(data)) {
1384
+ return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
1385
+ }
1386
+ const encoded = JSON.stringify(data);
1387
+ if (encoded === void 0) {
1388
+ throw new Error("Websocket payload must be JSON serializable");
1389
+ }
1390
+ return encoded;
1391
+ };
1392
+ var runWithConcurrency = async (items, concurrency, fn) => {
1393
+ const limit = Math.max(1, concurrency);
1394
+ let nextIndex = 0;
1395
+ await Promise.all(
1396
+ Array.from({ length: Math.min(limit, items.length) }, async () => {
1397
+ while (nextIndex < items.length) {
1398
+ const currentIndex = nextIndex;
1399
+ nextIndex += 1;
1400
+ await fn(items[currentIndex]);
1401
+ }
1402
+ })
1403
+ );
1404
+ };
1405
+
1406
+ // src/server/aws/apigw/domain.ts
1407
+ var create2 = (props) => {
1408
+ const client = new ApiGatewayManagementApiClient({
1409
+ endpoint: props.endpoint
1410
+ });
1411
+ return { client, endpoint: props.endpoint };
1412
+ };
1413
+ var createFromRequestContext = (props) => {
1414
+ return create2({ endpoint: getManagementEndpoint(props) });
1415
+ };
1416
+ var createPublisher = (apigw, props) => {
1417
+ const getConnectionId = props.getConnectionId;
1418
+ const onGone = props.onGone;
1419
+ return {
1420
+ send: (target, sendProps) => {
1421
+ return send(apigw, {
1422
+ connectionId: getConnectionId(target),
1423
+ data: sendProps.data,
1424
+ onGone: onGone ? () => onGone(target) : void 0
1425
+ });
1426
+ },
1427
+ broadcast: (broadcastProps) => {
1428
+ return broadcast(apigw, {
1429
+ ...broadcastProps,
1430
+ getConnectionId,
1431
+ onGone
1432
+ });
1433
+ }
1434
+ };
1435
+ };
1436
+ var send = async (apigw, props) => {
1437
+ try {
1438
+ await apigw.client.send(
1439
+ new PostToConnectionCommand({
1440
+ ConnectionId: props.connectionId,
1441
+ Data: encodeData(props.data)
1442
+ })
1443
+ );
1444
+ } catch (error2) {
1445
+ if (isGoneConnectionError(error2)) {
1446
+ await props.onGone?.(props.connectionId);
1447
+ return false;
1448
+ }
1449
+ throw error2;
1450
+ }
1451
+ return true;
1452
+ };
1453
+ var deleteConnection = (apigw, props) => {
1454
+ return apigw.client.send(
1455
+ new DeleteConnectionCommand({
1456
+ ConnectionId: props.connectionId
1457
+ })
1458
+ );
1459
+ };
1460
+ var broadcast = async (apigw, props) => {
1461
+ const result = {
1462
+ failed: [],
1463
+ stale: [],
1464
+ sent: 0
1465
+ };
1466
+ const sharedData = "data" in props ? encodeData(props.data) : null;
1467
+ const getData = "getData" in props ? props.getData : null;
1468
+ const getCacheKey = "getCacheKey" in props ? props.getCacheKey : void 0;
1469
+ const onGone = props.onGone;
1470
+ const cache = /* @__PURE__ */ new Map();
1471
+ const resolveData = async (target) => {
1472
+ if (sharedData !== null) {
1473
+ return sharedData;
1474
+ }
1475
+ if (!getData) {
1476
+ throw new Error("Missing websocket broadcast payload builder");
1477
+ }
1478
+ const cacheKey = getCacheKey?.(target);
1479
+ if (cacheKey == null) {
1480
+ return encodeData(await getData(target));
1481
+ }
1482
+ const existing = cache.get(cacheKey);
1483
+ if (existing) {
1484
+ return existing;
1485
+ }
1486
+ const promise = Promise.resolve(getData(target)).then(encodeData);
1487
+ cache.set(cacheKey, promise);
1488
+ return promise;
1489
+ };
1490
+ await runWithConcurrency(
1491
+ props.targets,
1492
+ props.concurrency ?? 25,
1493
+ async (target) => {
1494
+ const connectionId = props.getConnectionId(target);
1495
+ try {
1496
+ const delivered = await send(apigw, {
1497
+ connectionId,
1498
+ data: await resolveData(target),
1499
+ onGone: onGone ? () => onGone(target) : void 0
1500
+ });
1501
+ if (!delivered) {
1502
+ result.stale.push({ connectionId, target });
1503
+ return;
1504
+ }
1505
+ result.sent += 1;
1506
+ } catch (error2) {
1507
+ result.failed.push({ connectionId, error: error2, target });
1508
+ }
1509
+ }
1510
+ );
1511
+ return result;
1512
+ };
1513
+
1343
1514
  // src/server/aws/ddb/index.ts
1344
1515
  var ddb_exports = {};
1345
1516
  __export(ddb_exports, {
@@ -1347,7 +1518,7 @@ __export(ddb_exports, {
1347
1518
  batchGet: () => batchGet,
1348
1519
  batchWrite: () => batchWrite,
1349
1520
  copyTable: () => copyTable,
1350
- create: () => create2,
1521
+ create: () => create3,
1351
1522
  deleteTable: () => deleteTable,
1352
1523
  find: () => find,
1353
1524
  lsi1: () => lsi1,
@@ -1631,7 +1802,7 @@ var buildUpdateExpression = (ops, names, values) => {
1631
1802
  };
1632
1803
 
1633
1804
  // src/server/aws/ddb/domain.ts
1634
- var create2 = (props) => {
1805
+ var create3 = (props) => {
1635
1806
  const tableName = props?.tableName;
1636
1807
  const credentials = props?.credentials;
1637
1808
  const client = DynamoDBDocumentClient.from(
@@ -2513,11 +2684,11 @@ var copyTable = async (props) => {
2513
2684
  // src/server/aws/sns/index.ts
2514
2685
  var sns_exports = {};
2515
2686
  __export(sns_exports, {
2516
- create: () => create3,
2687
+ create: () => create4,
2517
2688
  publish: () => publish,
2518
2689
  publishError: () => publishError
2519
2690
  });
2520
- var create3 = (props) => {
2691
+ var create4 = (props) => {
2521
2692
  const client = new SNSClient({});
2522
2693
  return { client, topicArn: props?.topicArn };
2523
2694
  };
@@ -2552,8 +2723,8 @@ var publishError = (sns, props) => {
2552
2723
  // src/server/aws/sqs/index.ts
2553
2724
  var sqs_exports = {};
2554
2725
  __export(sqs_exports, {
2555
- create: () => create4,
2556
- send: () => send
2726
+ create: () => create5,
2727
+ send: () => send2
2557
2728
  });
2558
2729
 
2559
2730
  // src/server/aws/sqs/fns.ts
@@ -2567,12 +2738,12 @@ var getQueueUrlOrThrow = (...candidates) => {
2567
2738
  };
2568
2739
 
2569
2740
  // src/server/aws/sqs/domain.ts
2570
- var create4 = (props) => {
2741
+ var create5 = (props) => {
2571
2742
  const client = new SQSClient({});
2572
2743
  const queueUrl = props?.queueUrl;
2573
2744
  return { client, queueUrl };
2574
2745
  };
2575
- var send = (sqs, props) => sqs.client.send(
2746
+ var send2 = (sqs, props) => sqs.client.send(
2576
2747
  new SendMessageCommand({
2577
2748
  MessageBody: JSON.stringify(props.body),
2578
2749
  MessageGroupId: props.messageGroupId,
@@ -2583,16 +2754,16 @@ var send = (sqs, props) => sqs.client.send(
2583
2754
  // src/server/aws/ses/index.ts
2584
2755
  var ses_exports = {};
2585
2756
  __export(ses_exports, {
2586
- create: () => create5,
2587
- send: () => send2
2757
+ create: () => create6,
2758
+ send: () => send3
2588
2759
  });
2589
2760
 
2590
2761
  // src/server/aws/ses/fns.ts
2591
2762
  var stripHtml = (html) => html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<[^>]+>/g, " ").replace(/&nbsp;/g, " ").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/\s+/g, " ").trim();
2592
2763
 
2593
2764
  // src/server/aws/ses/index.ts
2594
- var create5 = () => new SESClient({ apiVersion: "2010-12-01" });
2595
- var send2 = (ses, email) => {
2765
+ var create6 = () => new SESClient({ apiVersion: "2010-12-01" });
2766
+ var send3 = (ses, email) => {
2596
2767
  const Source = `"${email.fromName}" <${email.from}>`;
2597
2768
  console.log(`[ses] Sending email to ${email.to} from ${email.from}`);
2598
2769
  const Destination = { ToAddresses: [email.to] };
@@ -2617,7 +2788,7 @@ var s3_exports = {};
2617
2788
  __export(s3_exports, {
2618
2789
  bucketExists: () => bucketExists,
2619
2790
  copyFile: () => copyFile,
2620
- create: () => create6,
2791
+ create: () => create7,
2621
2792
  createBucket: () => createBucket,
2622
2793
  createSignedUrl: () => createSignedUrl,
2623
2794
  deleteBucket: () => deleteBucket,
@@ -2644,7 +2815,7 @@ var getBucketNameOrThrow = (...candidates) => {
2644
2815
  };
2645
2816
 
2646
2817
  // src/server/aws/s3/domain.ts
2647
- var create6 = (props = {}) => {
2818
+ var create7 = (props = {}) => {
2648
2819
  const { cdn } = props;
2649
2820
  const client = new S3Client({});
2650
2821
  const bucketName = getBucketNameOrThrow(props.bucketName);
@@ -2899,4 +3070,4 @@ var recordsFromSqs = (body) => {
2899
3070
  }
2900
3071
  };
2901
3072
 
2902
- export { api_exports as Api, ddb_exports as DDB, dict_exports as Dict, file_exports as File, flow_exports as Flow, int_exports as Int, lambda_exports as Lambda, lexorank_exports as LexoRank, list_exports as List, log_exports as Log, money_exports as Money, os_exports as Os, random_exports as Random, s3_exports as S3, ses_exports as SES, sns_exports as SNS, sqs_exports as SQS, str_exports as Str, time_exports as Time };
3073
+ export { api_exports as Api, apigw_exports as ApiGw, ddb_exports as DDB, dict_exports as Dict, file_exports as File, flow_exports as Flow, int_exports as Int, lambda_exports as Lambda, lexorank_exports as LexoRank, list_exports as List, log_exports as Log, money_exports as Money, os_exports as Os, random_exports as Random, s3_exports as S3, ses_exports as SES, sns_exports as SNS, sqs_exports as SQS, str_exports as Str, time_exports as Time };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qstd",
3
- "version": "0.3.86",
3
+ "version": "0.3.87",
4
4
  "description": "Standard Block component and utilities library with Panda CSS",
5
5
  "author": "malin1",
6
6
  "license": "MIT",
@@ -66,6 +66,7 @@
66
66
  "react-dom": "^18.0.0 || ^19.0.0"
67
67
  },
68
68
  "dependencies": {
69
+ "@aws-sdk/client-apigatewaymanagementapi": "latest",
69
70
  "@aws-sdk/client-dynamodb": "latest",
70
71
  "@aws-sdk/client-s3": "latest",
71
72
  "@aws-sdk/client-ses": "latest",