TABLE OF CONTENTS


Trying to start the week off right getting back into the swing of my personal note-taking and journaling. For all those steaming hot takes which I feel like publicizing, I'll continue to use this meandering thread.

For whatever reason, Tuesdays always jump out as just the right cadence of the week where I like to be productive and jump into the introspection.

minimize the apologies

As I come marching into my late 20s turning 26 this December, I feel like this is urgently one the biggest values to keep at the forefront. Minimize the amount of "sorrys" or apologies you make. IMO, an authentic sorry comes from some amount of shame at a past action. By minimizing the apologies I don't mean to try and minimize the amount of shame you incur from actions but rather to reduce the shame and resultant anxiety you might feel by avoiding actions which will cause those feelings.

In a way, this is what mindful meditation sets out to accomplish. Obviously meditation is supposed to work not just within the shameful feelings but I would say it's quite therapeutic against them. Also, an overused sorry leads to the boy who cried wolf scenario where an apology from your mouth is essentially worthless.

DUMBO

I'm so fortunate to work in DUMBO, Brooklyn. It's the perfect spot for when the sun is up. Active during the day and quiet at night. Touristy for when the friends come and visit but yet not as insane as Midtown vibes. Take a stop at Time Out Market with the folks or wander around West Elm. If you're ever in the area Monday through Friday be sure to hit me up!

work culture

Coming from the consulting hustle to Amplify, I found that I didn't do a good job transitioning from being a fly on the wall to a culture-center.

Always invest in building relationships wherever you spend your work hours.

Personally, I like to carve out a space on whatever chat service my company uses like Slack. Go make a channel and invite those people that might like whatever weird shit you want to put in that channel and find those peeps that will respond. This past week on #down-the-whole channel at Amplify we've talked about SpaceX, text encoding, audio analysis, macOS updates and much more.

optimizing the friend groups

Nowadays we have Facebook Events, GroupMe chats, WhatsApp groups and so many other various ways to keep up with the friends. At this moment there're a few GroupMe's that I'm a part of that're decent for sharing out activities but nowadays there really isn't any messaging platform thats ubiquitous between all my friends and this fact bums me out. Anyone have any good suggestions for how to communicate with 10+ people at once? Audio + video? I love Discord for what it is but I don't think people realize just how insanely capable it is.

podcasting and meaningful conversations

Going out with the friends is fun on the weekday/weekends but gotta be sure to get the meaningful conversations and life updates as well as the shoot the shit convos. Maybe my family is just super open that we'd always cut through the bullshit of a "how's the weather" conversation but I'm finding it's hard to accumulate the friends.

utility style

Making it in NYC means you look good and feel good all day long. I wanted put out some of the brands and resources I've been using to reach a good balance of work appropriate, nightlife appropriate, etc.

casual + work attire

Shoes:

Socks:

Pants:

Belts:

Shirts:

fitness attire

Socks:

Kindle clippings

Since 2015 I've been reading my Kindle and a little ways into heavy usage of the device I realized just how powerful the notes feature is. I often think back to the book How to Talk About Books You Haven't Read by Pierre Bayard and the context of a book is so dependent on who you were and what you were doing at the time you were reading it. A good book can have a big effect but we honestly can't trust ourselves to remember each and every novel we read no matter how good it might be.

That said, go find a proper micro USB cable and hook your Kindle up to your laptop and you'll see there's a tiny little file called My Clippings.txt at the root of the mounted filesystem and inside there are all your highlights from every book!

Me and my desire for learning and keeping up with what I've learned has led me to come up with a plug and play system for this starting with the search functionality at the "words" page and next with a searchable database of these highlights!

Time to break out some code and some notes on where I went.

I opened up the repo for this website and went into the module that already contained some of this work and started some refactoring. It'd been a bit since I've touched in here and I made a previous half-ass attempt to start converting to Typescript but somewhere along the way I fell short.

Typescript setup for production and development

For Typescript we're going to write ES6 as first order which means usage of the import keyword for modules. The way we do this is:

package.json

{
    "name": "cdbattaglia-web",
    "version": "2.0.0",
    "scripts": {
        "build:backend": "npm run clean:backend && babel ./src --out-dir ./lib --extensions \".ts,.js\" --copy-files --source-maps inline",
        "build:frontend": "./node_modules/gulp/bin/gulp.js --gulpfile ./src/modules/cdbattaglia/build/gulp-tasks --cwd \"./\" build",
        "check-types": "tsc",
        "clean:backend": "/bin/rm -rf ./lib",
        "clean:frontend": "./node_modules/gulp/bin/gulp.js --gulpfile ./src/modules/cdbattaglia/build/gulp-tasks --cwd \"./\" cleanup",
        "pm2:start": "node ./node_modules/pm2/bin/pm2 start ecosystem.config.js",
        "pm2:stop": "node ./node_modules/pm2/bin/pm2 stop cdbattaglia-web",
        "pm2:delete": "node ./node_modules/pm2/bin/pm2 delete cdbattaglia-web",
        "pm2:logs": "node ./node_modules/pm2/bin/pm2 logs cdbattaglia-web",
        "preinstall": "/bin/bash ./bin/preinstall.sh",
        "start:dev": "NODE_ENV=development node ./node_modules/nodemon/bin/nodemon.js --trace-warnings --exec babel-node ./src/app.ts --extensions \".ts,.js\" --source-maps inline",
        "start": "npm run build:backend && npm run pm2:start && npm run pm2:logs",
        "start:old": "./node_modules/gulp/bin/gulp.js --gulpfile ./src/modules/cdbattaglia/build/gulp-tasks --cwd \"./\" start",
        "stop": "npm run pm2:stop && npm run pm2:delete"
    }
}

The above is a little hard to parse through but the gist of it is that we're using babel-node locally and Node.js native through pm2 and clustering the max instance size.

The only other three files you need to know of are

tsconfig.json

{
    "compilerOptions": {
        // Target latest version of ECMAScript.
        "target": "esnext",
        // Search under node_modules for non-relative imports.
        "moduleResolution": "node",
        // Process & infer types from .js files.
        "allowJs": true,
        // Don't emit; allow Babel to transform files.
        "noEmit": true,
        // Disallow features that require cross-file information for emit.
        "isolatedModules": true,
        // Import non-ES modules as default imports.
        "esModuleInterop": true,
        // Resolve JSON
        "resolveJsonModule": true,
        // Others
        "noImplicitAny": false,
        "sourceMap": true,
        "typeRoots": [
            "node_modules/@types"
        ]
    },
    "include": [
        "src/*"
    ],
    "exclude": [
        "node_modules"
    ]
}

and

.babelrc

{
    "presets": [
        [
            "@babel/preset-env",
            { "modules": "commonjs" }
        ],
        "@babel/typescript"
    ],
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            { "regenerator": true }
        ]
    ]
}

and lastly

ecosystem.config.js

module.exports = {
    apps: [{
        name: "cdbattaglia-web",
        script: "./lib/app.js",
        env: {
            "NODE_ENV": "production",
        },
        instances: "max"
    }]
}

Woot! You're officially up and running writing using import or require and all the rest! I'll give a detailed article in a couple days hopefully about how to setup local babel-eslint with the latest Typescript linting errors which lets you use optional chaining as a first order feature!

Node.js file stream read

import fs from 'fs'
import path from 'path'
import moment from 'moment'
import _ from 'lodash'
import es from 'event-stream'
import execTime from 'execution-time'
import { Response, Request } from 'express' // types

const perf = execTime()

const parseClippings = async (res: Response, file: string) => {
    return new Promise(resolve => {
        perf.start()
        const s = fs.createReadStream(
                file,
                { encoding: 'utf8' }
        )
            .pipe(es.split('=========='))
            .pipe(es.mapSync((clipping) => {
                s.pause()

                const splitClipping = clipping.split('\n').filter((line: string) => line)

                const [ book, time, highlight ] = splitClipping

                if (time) {
                    const page = time.split(' | ')[0].split('page ')[1]

                    const dateForMoment = time
                        .split(' | Added on ')[1]
                        .split(', ')
                        .slice(1)

                    let toWrite = moment(dateForMoment.join(' '), 'MMMM-DD-YYYY-h-mm-ss-a').toString()

                    if (book) toWrite += ` | ${book}`
                    if (page) toWrite += ` | ${page}`
                    if (highlight) toWrite += ` | ${highlight}`

                    res.write(
                        toWrite + '\n',
                        'utf8'
                    )
                }

                s.resume()
            }))
            .on('error', (err) => {
                console.log('Error while reading clippings file.', err)
            })
            .on('end', () => {
                res.end()
                resolve()
            })
    })
}

export default async (req: Request, res: Response) => {
    res.set({
        'content-type': 'application/json; charset=utf-8'
    })

    parseClippings(
        res,
        path.join(__dirname, '../clippings/2019-11-05_my-clippings.txt')
    )
}

You can see this functioning here.

Share the love!

Thank y'all kindly for the read!