Skip to content

Commit 90ef0e0

Browse files
committed
chore: address feedbacks: prefer FP style
1 parent 7e50b36 commit 90ef0e0

File tree

9 files changed

+77
-109
lines changed

9 files changed

+77
-109
lines changed

packages/eventstream-serde-browser/src/EventStreamMarshaller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
Message,
77
EventStreamMarshaller as IEventStreamMarshaller
88
} from "@aws-sdk/types";
9-
import { ReadableStreamtoIterable, iterableToReadableStream } from "./utils";
9+
import { readableStreamtoIterable, iterableToReadableStream } from "./utils";
1010

1111
export interface EventStreamMarshaller extends IEventStreamMarshaller {}
1212

@@ -47,7 +47,7 @@ export class EventStreamMarshaller {
4747
deserializer: (input: { [event: string]: Message }) => Promise<T>
4848
): AsyncIterable<T> {
4949
const bodyIterable = isReadableStream(body)
50-
? ReadableStreamtoIterable(body)
50+
? readableStreamtoIterable(body)
5151
: body;
5252
return this.universalMarshaller.deserialize(bodyIterable, deserializer);
5353
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./provider";
22
export * from "./EventStreamMarshaller";
3+
export * from "./utils";
Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
11
/**
2-
* Convert ReadableStream into an async iterable.
2+
* A util function converting ReadableStream into an async iterable.
33
* Reference: https://jakearchibald.com/2017/async-iterators-and-generators/#making-streams-iterate
44
*/
5-
export async function* ReadableStreamtoIterable<T>(
5+
export const readableStreamtoIterable = <T>(
66
readableStream: ReadableStream<T>
7-
): AsyncIterable<T> {
8-
const reader = readableStream.getReader();
9-
try {
10-
while (true) {
11-
const { done, value } = await reader.read();
12-
if (done) return;
13-
yield value as T;
7+
): AsyncIterable<T> => ({
8+
[Symbol.asyncIterator]: async function* () {
9+
const reader = readableStream.getReader();
10+
try {
11+
while (true) {
12+
const { done, value } = await reader.read();
13+
if (done) return;
14+
yield value as T;
15+
}
16+
} finally {
17+
reader.releaseLock();
1418
}
15-
} finally {
16-
reader.releaseLock();
1719
}
18-
}
20+
});
1921

2022
/**
21-
* Convert async iterable to a ReadableStream.
23+
* A util function converting async iterable to a ReadableStream.
2224
*/
23-
export function iterableToReadableStream<T>(
25+
export const iterableToReadableStream = <T>(
2426
asyncIterable: AsyncIterable<T>
25-
): ReadableStream<T> {
27+
): ReadableStream<T> => {
2628
const iterator = asyncIterable[Symbol.asyncIterator]();
2729
return new ReadableStream({
28-
pull(constroller) {
29-
return iterator.next().then(({ done, value }) => {
30-
if (done) {
31-
return constroller.close();
32-
}
33-
constroller.enqueue(value);
34-
});
30+
async pull(controller) {
31+
const { done, value } = await iterator.next();
32+
if (done) {
33+
return controller.close();
34+
}
35+
controller.enqueue(value);
3536
}
3637
});
37-
}
38+
};

packages/middleware-sdk-transcribe-streaming/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
},
1919
"license": "Apache-2.0",
2020
"dependencies": {
21+
"@aws-sdk/eventstream-serde-browser": "1.0.0-gamma.1",
2122
"@aws-sdk/middleware-signing": "1.0.0-gamma.1",
2223
"@aws-sdk/protocol-http": "1.0.0-gamma.1",
2324
"@aws-sdk/signature-v4": "1.0.0-gamma.1",

packages/middleware-sdk-transcribe-streaming/src/configuration.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,25 @@ export interface WebSocketResolvedConfig {
1414
requestHandler: RequestHandler<any, any>;
1515
}
1616

17-
export function resolveWebSocketConfig<T>(
17+
export const resolveWebSocketConfig = <T>(
1818
input: T & WebSocketInputConfig & PreviouslyResolved
19-
): T & WebSocketResolvedConfig {
20-
if (input.requestHandler.metadata?.handlerProtocol === "websocket") {
21-
return {
22-
...input,
23-
signer: () =>
24-
input.signer().then(signerObj => {
19+
): T & WebSocketResolvedConfig =>
20+
input.requestHandler.metadata?.handlerProtocol !== "websocket"
21+
? input
22+
: {
23+
...input,
24+
signer: async () => {
25+
const signerObj = await input.signer();
2526
if (validateSigner(signerObj)) {
2627
return new SignatureV4({ signer: signerObj });
2728
}
2829
throw new Error(
2930
"Expected SignatureV4 signer, please check the client constructor."
3031
);
31-
})
32-
};
33-
} else {
34-
return input;
35-
}
36-
}
32+
}
33+
};
3734

38-
function validateSigner(signer: any): signer is BaseSignatureV4 {
35+
const validateSigner = (signer: any): signer is BaseSignatureV4 =>
3936
// We cannot use instanceof here. Because we might import the wrong SignatureV4
4037
// constructor here as multiple version of packages maybe installed here.
41-
return (signer.constructor.toString() as string).indexOf("SignatureV4") >= 0;
42-
}
38+
(signer.constructor.toString() as string).indexOf("SignatureV4") >= 0;

packages/middleware-sdk-transcribe-streaming/src/middleware-session-id.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type WithSession = {
1616
* Middleware that inject default sessionId for operations, and inject
1717
* the parameters from request to the response metadata. This is
1818
* necessary because the SDK cannot access any parameters other than
19-
* the result stream. So it copy the parameters from input to the same
19+
* the result stream. So it copies the parameters from input to the same
2020
* parameters in the output.
2121
*/
2222
export const injectSessionIdMiddleware = (config: {
@@ -40,9 +40,9 @@ export const injectSessionIdMiddleware = (config: {
4040
return response;
4141
};
4242

43-
function isWebSocket(config: { requestHandler: RequestHandler<any, any> }) {
43+
const isWebSocket = (config: { requestHandler: RequestHandler<any, any> }) => {
4444
return config.requestHandler.metadata?.handlerProtocol === "websocket";
45-
}
45+
};
4646

4747
export const injectSessionIdMiddlewareOptions: InitializeHandlerOptions = {
4848
step: "initialize",

packages/middleware-sdk-transcribe-streaming/src/signer.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ export class SignatureV4 implements RequestSigner, RequestPresigner {
2828
if (HttpRequest.isInstance(toSign)) {
2929
// Presign the endpoint url with empty body, otherwise
3030
// the payload hash would be UNSINGED_PAYLOAD
31-
const originalBody = toSign.body;
32-
toSign.body = "";
33-
const signedRequest = await this.signer.presign(toSign, {
31+
const signedRequest = await this.signer.presign({ ...toSign, body: "" }, {
3432
expiresIn: 5 * 60 // presigned url must be expired within 5 mins
3533
} as any);
36-
signedRequest.body = originalBody;
37-
return signedRequest;
34+
return {
35+
...signedRequest,
36+
body: toSign.body
37+
};
3838
} else {
3939
return this.signer.sign(toSign, options);
4040
}

packages/middleware-sdk-transcribe-streaming/src/websocket-handler.ts

Lines changed: 28 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import { HttpHandlerOptions, RequestHandlerMetadata } from "@aws-sdk/types";
22
import { HttpHandler, HttpRequest, HttpResponse } from "@aws-sdk/protocol-http";
33
import { formatUrl } from "@aws-sdk/util-format-url";
4-
/**
5-
* Base handler for websocket requests. By default, the request input and output
6-
* body will be in a ReadableStream, because of interface consistency among middleware.
7-
* If ReadableStream is not available, like in React-Native, the response body
8-
* will be an async iterable.
9-
*/
4+
import {
5+
iterableToReadableStream,
6+
readableStreamtoIterable
7+
} from "@aws-sdk/eventstream-serde-browser";
108

119
export interface WebSocketHandlerOptions {
1210
/**
@@ -16,6 +14,12 @@ export interface WebSocketHandlerOptions {
1614
connectionTimeout?: number;
1715
}
1816

17+
/**
18+
* Base handler for websocket requests. By default, the request input and output
19+
* body will be in a ReadableStream, because of interface consistency among middleware.
20+
* If ReadableStream is not available, like in React-Native, the response body
21+
* will be an async iterable.
22+
*/
1923
export class WebSocketHandler implements HttpHandler {
2024
public readonly metadata: RequestHandlerMetadata = {
2125
handlerProtocol: "websocket"
@@ -27,26 +31,24 @@ export class WebSocketHandler implements HttpHandler {
2731

2832
destroy(): void {}
2933

30-
handle(
34+
async handle(
3135
request: HttpRequest,
3236
options: HttpHandlerOptions = {}
3337
): Promise<{ response: HttpResponse }> {
3438
const url = formatUrl(request);
3539
const socket: WebSocket = new WebSocket(url);
3640
socket.binaryType = "arraybuffer";
37-
return waitForReady(socket, this.connectionTimeout)
38-
.then(() => {
39-
const { body } = request;
40-
const bodyStream = getIterator(body);
41-
return connect(socket, bodyStream);
41+
await waitForReady(socket, this.connectionTimeout);
42+
const { body } = request;
43+
const bodyStream = getIterator(body);
44+
const asyncIterable = connect(socket, bodyStream);
45+
const outputPayload = toReadableStream(asyncIterable);
46+
return {
47+
response: new HttpResponse({
48+
statusCode: 200, // indicates connection success
49+
body: outputPayload
4250
})
43-
.then(iterableToReadableStream)
44-
.then(bodyStream => ({
45-
response: new HttpResponse({
46-
statusCode: 200, // indicates connection success
47-
body: bodyStream
48-
})
49-
}));
51+
};
5052
}
5153
}
5254

@@ -128,29 +130,12 @@ const connect = (
128130
* the request body is ReadableStream, so we need to transfer it to AsyncIterable
129131
* to make the stream consumable by WebSocket.
130132
*/
131-
function getIterator(stream: any): AsyncIterable<any> {
133+
const getIterator = (stream: any): AsyncIterable<any> => {
132134
// Noop if stream is already an async iterable
133135
if (stream[Symbol.asyncIterator]) return stream;
134136
else if (isReadableStream(stream)) {
135137
//If stream is a ReadableStream, transfer the ReadableStream to async iterable.
136-
//Reference: https://jakearchibald.com/2017/async-iterators-and-generators/#making-streams-iterate
137-
const reader = stream.getReader();
138-
return {
139-
[Symbol.asyncIterator]: async function* () {
140-
try {
141-
while (true) {
142-
// Read from the stream
143-
const { done, value } = await reader.read();
144-
// Exit if we're done
145-
if (done) return;
146-
// Else yield the chunk
147-
yield value;
148-
}
149-
} finally {
150-
reader.releaseLock();
151-
}
152-
}
153-
};
138+
return readableStreamtoIterable(stream);
154139
} else {
155140
//For other types, just wrap them with an async iterable.
156141
return {
@@ -159,30 +144,16 @@ function getIterator(stream: any): AsyncIterable<any> {
159144
}
160145
};
161146
}
162-
}
147+
};
163148

164149
/**
165150
* Convert async iterable to a ReadableStream when ReadableStream API
166151
* is available(browsers). Otherwise, leave as it is(ReactNative).
167152
*/
168-
function iterableToReadableStream<T>(
169-
asyncIterable: AsyncIterable<T>
170-
): ReadableStream<T> | AsyncIterable<T> {
171-
if (typeof ReadableStream !== "function") {
172-
return asyncIterable;
173-
}
174-
const iterator = asyncIterable[Symbol.asyncIterator]();
175-
return new ReadableStream({
176-
pull(controller) {
177-
return iterator.next().then(({ done, value }) => {
178-
if (done) {
179-
return controller.close();
180-
}
181-
controller.enqueue(value);
182-
});
183-
}
184-
});
185-
}
153+
const toReadableStream = <T>(asyncIterable: AsyncIterable<T>) =>
154+
typeof ReadableStream === "function"
155+
? iterableToReadableStream(asyncIterable)
156+
: asyncIterable;
186157

187158
const isReadableStream = (payload: any): payload is ReadableStream =>
188159
typeof ReadableStream === "function" && payload instanceof ReadableStream;

scripts/generate-clients/code-gen.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ const generateClients = async models => {
4141
if (!lstatSync(file).isFile()) return;
4242
const name = path.basename(file);
4343
console.log(`copying model ${name}...`);
44-
copyFileSync(file, path.join(TEMP_CODE_GEN_INPUT_DIR, name), {
45-
overwrite: true
46-
});
44+
copyFileSync(file, path.join(TEMP_CODE_GEN_INPUT_DIR, name));
4745
});
4846
});
4947
} else {

0 commit comments

Comments
 (0)