Skip to content

Instantly share code, notes, and snippets.

Avatar

Jed Schmidt jed

View GitHub Profile
@jed
jed / README.md
Last active Nov 19, 2022
Making your Mastodon account discoverable from your domain, using Cloudflare page rules
View README.md

Making your Mastodon account discoverable from your own domain, using Cloudflare page rules

Are you (1) moving to Mastodon, but (2) want to use your own Cloudflare-hosted domain for discoverability, and (3) don't want the hassle of managing your own instance?

Well, here's a quick way to make sure that folks can find you when they search Mastodon with your domain. The UX is like this:

image

(If you're not on Cloudflare or would rather just host a file, use Maarten Balliauw's post, How to discover Mastodon account via custom domain, from which this technique was inspired.)

@jed
jed / resolve_tco.js
Last active Nov 19, 2022
t.co resolver for twitter archives
View resolve_tco.js
// this script replaces all t.co links in the data/tweets.js file of an unzipped twitter archive with their resolved urls.
// it replaces all text inline, so be sure to make a backup of the file before running.
// usage: deno run -A resolve_tco.js {path to data/tweets.js}
let file = Deno.args[0]
let text = await Deno.readTextFile(file)
let matches = text.match(/"https:\/\/t\.co\/\w+"/g)
let unique = [...new Set(matches)]
console.log('%s urls found.', unique.length)
if (unique.length) for (let match of matches) {
View iteratePromises.js
// per https://twitter.com/yoshuawuyts/status/1494119486429007879
// "In JavaScript, is there a function which takes N Promises, and returns an asyncIterator which yields N resolved values?"
let promises = Array.from({length: 10}, (n, i) => {
return new Promise(cb => setTimeout(cb, Math.random() * 1e3, i))
})
let iterator = iteratePromises(promises)
for await (let value of iterator) console.log(value)
View view-source.js
export default (build, namespace = 'view-source') => ({
name: namespace,
setup({initialOptions, onLoad, onResolve}) {
let options = {...initialOptions, write: false}
let filter = new RegExp(`^${namespace}:`)
onResolve({filter}, ({path, importer}) => {
path = path.replace(filter, '')
try { importer = new URL(importer) }
catch (e) { importer = new URL(`${namespace}://${importer}`) }
@jed
jed / tee.js
Last active Nov 24, 2020
Teeing an asynchronous iterator
View tee.js
function tee(asyncIterable) {
let source = asyncIterable[Symbol.asyncIterator]()
return [[], []].map((buffer, i, buffers) => ({
async next() {
if (0 in buffer) return buffer.shift()
let item = await source.next()
if (!item.done) buffers[1 - i].push(item)
@jed
jed / iterator.js
Last active Jan 21, 2021
Turning callbacks into async iterators, with a React hook-like API.
View iterator.js
// Example usage:
//
// void async function() {
// let [clicks, onclick] = iterator()
// document.querySelector('button').addEventListener('click', onclick)
// for await (let click of clicks) console.log(click)
// }()
export default function iterator() {
let done = false
@jed
jed / s3-etag.js
Last active Mar 5, 2018
Create an etag for an S3 object. Assumes object is uploaded with exact chunk size.
View s3-etag.js
const {createReadStream} = require('fs')
const {createHash} = require('crypto')
module.exports = (path, chunkSize = 5242880) => {
return new Promise((resolve, reject) => {
const hashes = []
const options = {highWaterMark: chunkSize}
const rs = createReadStream(path, options)
rs.on('error', reject)
@jed
jed / deploy.sh
Last active Nov 12, 2022
Using AWS CloudFormation to deploy an edge lambda
View deploy.sh
#!/bin/sh
aws cloudformation deploy \
--template-file stack.yaml \
--stack-name edge-lambda-test \
--capabilities CAPABILITY_IAM \
--parameter-overrides Nonce=$RANDOM
View template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
GetFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs6.10
CodeUri: index.js
Events: