Skip to content

Instantly share code, notes, and snippets.

View justsml's full-sized avatar
🔥
#BLM

Dan Levy justsml

🔥
#BLM
View GitHub Profile

Iterables, AsyncIterables, Observables, Oh My!

I know there is a lot of confusion around Observables, Iterables, AsyncIterables and AsyncObservables. Let's try to break this down and the reasons for each.

Pull versus Push Collections

When it comes to collections, you have two ways of thinking about collections, push versus pull. With pull, the consumer is in control of when you get the items, but with push, you get the values when the producer is ready.

Pull Based Collections

export type User = ReturnType<typeof verifyUser>;
// ^ Type defined for 'free'
// + Pro: Less wasted effort aligning types AND validation.
// + Pro: More 'honest', not obscured by layers, `any` or `as`
// - Con: Easy to accidentally change a public interface.
// (Prefer explicit definitions at your library/module boundaries.)
export function verifyUser(data: { [key: string]: unknown; }) {
if (!data || typeof data !== 'object')
throw new Error(`User must be a valid object.`);
@justsml
justsml / aws-client-options.js
Last active April 20, 2023 01:22
Using LocalStack with AWS SDK v3 - determine options for AWS client constructors.
const DEFAULT_LOCALSTACK_EDGE_PORT = 4566;
/**
* Get options for use in AWS client constructors.
*
* Configure the `AWS_ENDPOINT` environment variable to set an endpoint.
*
* ### Example
*
* To run tests w/ LocalStack: `AWS_ENDPOINT=http://127.0.0.1:4566 jest`
/**
* A **Smarter** retry wrapper with currying!
*/
function retryCurry(fn, retriesLeft = 5) {
const retryFn = (...args) => fn(...args)
.catch(err => retriesLeft > 0
? retryFn(fn, retriesLeft - 1)
: Promise.reject(err)
})
return retryFn
const checkForRedirect = (response) => {
// Check for temporary redirect (307), or permanent (308)
if (response.status === 307 || response.status === 308) {
const location = response.headers.get('location')
if (!location) {
return Promise.reject(new Error('Invalid HTTP Redirect! No Location header.'));
}
// You can change the behavior here to any custom logic:
// e.g. open a "confirm" modal, log the redirect url, etc.
return fetch(location)
@justsml
justsml / extensions.json
Last active November 22, 2022 18:57
VS Code Config
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"streetsidesoftware.code-spell-checker",
"kisstkondoros.vscode-codemetrics",
"ms-azuretools.vscode-docker",
"dbaeumer.vscode-eslint",
/**
* `filteredFlagFactory` supports 3 states of a feature flag:
* - True,
* - False,
* - and restricted by ID(s).
*
*/
export function filteredFlagFactory(
flagValue: string,
defaultIdField = 'userId'
@justsml
justsml / asyncIterable-stream-forAwaitOf-examples.ts
Created August 1, 2022 00:24
Examples of using for-await-of syntax to consume streams.
export const batchStream = (size: number) =>
async function* batchStream<TStreamType>(stream: AsyncIterable<TStreamType>) {
let buffer: TStreamType[] = [];
for await (const chunk of stream) {
buffer.push(chunk);
if (buffer.length >= size) {
yield buffer;
buffer = [];
}
}
@justsml
justsml / addSignalListener.mjs
Last active August 18, 2022 04:04
Nodejs snippet to handle `process` events (OS signals) easily with `addSignalListener()`
/**
* Handle process signal events easily with `addSignalListener()`.
*
* Automatically returns a convenient method to unregister your event handler(s), in case you need that functionality.
*
* ## Examples
*
* ```js
* addSignalListener(['SIGINT', 'SIGHUP', 'SIGUSR2'], (signal, event) =>
* console.log(`Process received a signal! ${signal}`, { event });
@justsml
justsml / settings.json
Created June 21, 2022 00:50
VS Code Recommended Settings
{
// TypeScript configuration
// Use the project-local typescript version / may be desired, comment out on old TS versions
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.preferences.importModuleSpecifier": "relative",
// Terminal settings
"terminal.integrated.scrollback": 100000, // Terminal scrollback line limit
// Set terminal font size to match VS Code font size. See: https://www.NerdFonts.com/
"terminal.integrated.fontFamily": "'MesloLGS NF', 'Hack Nerd Font', Menlo, Monaco, 'Courier New', monospace",