├── .gitignore ├── ui.md ├── reason.md ├── _notes ├── 2017-07 │ ├── 26-017.md │ ├── 26-016.md │ ├── 31-018.md │ ├── 03-001.md │ ├── 03-002.md │ ├── 04-007.md │ ├── 25-013.md │ ├── 24-012.md │ ├── 04-008.md │ ├── 01-000.md │ ├── 04-003.md │ ├── 05-009.md │ ├── 26-015.md │ ├── 25-014.md │ ├── 24-013.md │ ├── 04-005.md │ └── 04-004.md ├── 2017-06 │ ├── 30-030.md │ ├── 30-035.md │ ├── 30-073.md │ ├── 30-065.md │ ├── 30-064.md │ ├── 30-031.md │ ├── 30-044.md │ ├── 30-024.md │ ├── 30-013.md │ ├── 30-068.md │ ├── 30-028.md │ ├── 30-037.md │ ├── 30-003.md │ ├── 30-014.md │ ├── 30-012.md │ ├── 30-053.md │ ├── 30-000.md │ ├── 30-022.md │ ├── 30-015.md │ ├── 30-042.md │ ├── 30-019.md │ ├── 30-052.md │ ├── 30-056.md │ ├── 30-033.md │ ├── 30-001.md │ ├── 30-016.md │ ├── 30-039.md │ ├── 30-071.md │ ├── 30-041.md │ ├── 30-018.md │ ├── 30-027.md │ ├── 30-043.md │ ├── 30-010.md │ ├── 30-009.md │ ├── 30-054.md │ ├── 30-061.md │ ├── 30-038.md │ ├── 30-029.md │ ├── 30-049.md │ ├── 30-011.md │ ├── 30-040.md │ ├── 30-050.md │ ├── 30-007.md │ ├── 30-072.md │ ├── 30-036.md │ ├── 30-059.md │ ├── 30-047.md │ ├── 30-005.md │ ├── 30-017.md │ ├── 30-075.md │ ├── 30-051.md │ ├── 30-046.md │ ├── 30-060.md │ ├── 30-006.md │ ├── 30-032.md │ ├── 30-025.md │ ├── 30-066.md │ ├── 30-020.md │ ├── 30-034.md │ ├── 30-070.md │ ├── 30-063.md │ ├── 30-045.md │ ├── 30-026.md │ ├── 30-062.md │ ├── 30-008.md │ ├── 30-023.md │ ├── 30-004.md │ ├── 30-048.md │ ├── 30-021.md │ ├── 30-074.md │ ├── 30-067.md │ ├── 30-057.md │ ├── 30-069.md │ ├── 30-055.md │ └── 30-058.md ├── 2017-09 │ ├── 12-021.md │ ├── 12-022.md │ ├── 12-020.md │ ├── 04-011.md │ ├── 12-017.md │ ├── 01-003.md │ ├── 04-010.md │ ├── 04-009.md │ ├── 01-004.md │ ├── 12-014.md │ ├── 12-018.md │ ├── 01-001.md │ ├── 12-016.md │ ├── 01-006.md │ ├── 04-007.md │ ├── 12-015.md │ ├── 01-005.md │ ├── 20-023.md │ ├── 12-012.md │ ├── 12-019.md │ ├── 01-002.md │ ├── 12-013.md │ ├── 01-000.md │ └── 25-024.md ├── 2017-08 │ ├── 15-014.md │ ├── 11-010.md │ ├── 15-013.md │ ├── 04-001.md │ ├── 11-009.md │ ├── 04-002.md │ ├── 11-011.md │ ├── 04-003.md │ ├── 10-008.md │ ├── 18-017.md │ ├── 17-016.md │ ├── 10-007.md │ ├── 03-000.md │ ├── 14-012.md │ ├── 07-004.md │ ├── 21-019.md │ ├── 08-005.md │ ├── 10-006.md │ └── 17-015.md ├── 2017-10 │ ├── 12-005.md │ ├── 11-004.md │ ├── 17-007.md │ └── 19-008.md └── 2017-11 │ └── 01-000.md ├── gardening.md ├── open-source.md ├── npm.md ├── emacs.md ├── teams.md ├── coding-with-kids.md ├── flowtype.md ├── creative-process.md ├── images └── ballmer-developers.gif ├── jest.md ├── code-viz.md ├── cooking.md ├── docs.md ├── git.md ├── writing.md ├── css.md ├── node.md ├── electron.md ├── babel.md ├── README.md ├── productivity.md ├── ffmpeg.md ├── react.md ├── docker.md ├── github-prs.md ├── portfolios.md ├── tech-goals-for-2017.md └── collaboration.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /ui.md: -------------------------------------------------------------------------------- 1 | # ui 2 | 3 | - [junk food ui](_notes/2017-06/30-037.md) 4 | -------------------------------------------------------------------------------- /reason.md: -------------------------------------------------------------------------------- 1 | # reason 2 | 3 | - [noob notes](_notes/2017-06/30-049.md) 4 | -------------------------------------------------------------------------------- /_notes/2017-07/26-017.md: -------------------------------------------------------------------------------- 1 | > You can make anything by writing. 2 | ― C.S. Lewis 3 | -------------------------------------------------------------------------------- /gardening.md: -------------------------------------------------------------------------------- 1 | # gardening 2 | 3 | - [growing salad](_notes/2017-06/30-032.md) 4 | -------------------------------------------------------------------------------- /open-source.md: -------------------------------------------------------------------------------- 1 | # open source 2 | 3 | - [opinions](_notes/2017-06/30-043.md) 4 | -------------------------------------------------------------------------------- /npm.md: -------------------------------------------------------------------------------- 1 | # npm 2 | 3 | - [passing args into npm run-scripts](_notes/2017-06/30-042.md) 4 | -------------------------------------------------------------------------------- /emacs.md: -------------------------------------------------------------------------------- 1 | # emacs 2 | 3 | - [opening files / bookmarks with sudo](_notes/2017-06/30-018.md) 4 | -------------------------------------------------------------------------------- /teams.md: -------------------------------------------------------------------------------- 1 | # teams 2 | 3 | - [different approaches to communication](_notes/2017-06/30-075.md) 4 | -------------------------------------------------------------------------------- /_notes/2017-06/30-030.md: -------------------------------------------------------------------------------- 1 | # github: show a diff without whitespace 2 | 3 | Add `?w=0` to the URL 4 | -------------------------------------------------------------------------------- /coding-with-kids.md: -------------------------------------------------------------------------------- 1 | # coding with kids 2 | 3 | - [frozen-themed scratch](_notes/2017-06/30-005.md) 4 | -------------------------------------------------------------------------------- /flowtype.md: -------------------------------------------------------------------------------- 1 | # flowtype 2 | 3 | - [covariance / contravariance error](_notes/2017-09/20-023.md) 4 | -------------------------------------------------------------------------------- /creative-process.md: -------------------------------------------------------------------------------- 1 | # creative process 2 | 3 | - [john cleese on creativity](_notes/2017-07/25-014.md) 4 | -------------------------------------------------------------------------------- /_notes/2017-07/26-016.md: -------------------------------------------------------------------------------- 1 | > A nail is driven out by another nail; habit is overcome by habit. 2 | ― Erasmus 3 | -------------------------------------------------------------------------------- /images/ballmer-developers.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshwnj/knowledge/HEAD/images/ballmer-developers.gif -------------------------------------------------------------------------------- /jest.md: -------------------------------------------------------------------------------- 1 | # jest 2 | 3 | - [a few little gotchas I found after using jest this week](_notes/2017-08/18-017.md) 4 | -------------------------------------------------------------------------------- /_notes/2017-06/30-035.md: -------------------------------------------------------------------------------- 1 | [Frank Zappa - Dupree's Paradise (1973)](https://www.youtube.com/watch?v=qr6mTloYJJs) 2 | -------------------------------------------------------------------------------- /_notes/2017-06/30-073.md: -------------------------------------------------------------------------------- 1 | [Modern Jazz Quartet - Live in Japan (1981)](https://www.youtube.com/watch?v=v4ZWw9X2EMM) 2 | -------------------------------------------------------------------------------- /_notes/2017-07/31-018.md: -------------------------------------------------------------------------------- 1 | # pull down a directory of files over ssh 2 | 3 | ``` 4 | rsync -arv host:/path/to/files . 5 | ``` 6 | -------------------------------------------------------------------------------- /code-viz.md: -------------------------------------------------------------------------------- 1 | # code viz 2 | 3 | Thoughts on different ways to visualise code. 4 | 5 | - [execution paths](_notes/2017-08/11-009.md) 6 | -------------------------------------------------------------------------------- /cooking.md: -------------------------------------------------------------------------------- 1 | # cooking 2 | 3 | - [self-saucing chocalate pudding](_notes/2017-08/11-010.md) 4 | - [steak](_notes/2017-08/11-011.md) 5 | -------------------------------------------------------------------------------- /docs.md: -------------------------------------------------------------------------------- 1 | # docs 2 | 3 | - [auto-generate all screenshots](_notes/2017-09/12-022.md) 4 | - [categories of docs](_notes/2017-10/11-004.md) 5 | -------------------------------------------------------------------------------- /_notes/2017-06/30-065.md: -------------------------------------------------------------------------------- 1 | # webm quirk 2 | 3 | it seems that chrome will show a blank video if a webm has a height that is not divisible by 2? 4 | -------------------------------------------------------------------------------- /_notes/2017-09/12-021.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 09:02:34 GMT+1000 (AEST) 3 | --- 4 | 5 | lib idea: `vape` (virtual audio param emulator) 6 | -------------------------------------------------------------------------------- /git.md: -------------------------------------------------------------------------------- 1 | # git 2 | 3 | - [create a branch from a tag](_notes/2017-06/30-028.md) 4 | - [working with github prs locally](_notes/2017-06/30-029.md) 5 | -------------------------------------------------------------------------------- /_notes/2017-06/30-064.md: -------------------------------------------------------------------------------- 1 | mucking around with some ideas for non-repeating audio, within a set of constraints: 2 | -------------------------------------------------------------------------------- /_notes/2017-08/15-014.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Aug 15 2017 14:42:02 GMT+1000 (AEST) 3 | --- 4 | 5 | trying out https://github.com/electron/electron-compile 6 | 7 | 8 | -------------------------------------------------------------------------------- /_notes/2017-07/03-001.md: -------------------------------------------------------------------------------- 1 | # idea: personal docket system 2 | 3 | - not only keeping track of stuff that needs to be done, but also looking for patterns, ways to batch & optimise 4 | -------------------------------------------------------------------------------- /_notes/2017-07/03-002.md: -------------------------------------------------------------------------------- 1 | # high-brain, low-brain 2 | 3 | tip: have some things set aside that you can do even when you're tired and uninspired. Don't waste your high-brain time on these. 4 | -------------------------------------------------------------------------------- /writing.md: -------------------------------------------------------------------------------- 1 | # writing 2 | 3 | - [types of journal entries](_notes/2017-06/30-067.md) 4 | - [comparison of writing tools](_notes/2017-06/30-069.md) 5 | - [goal to write more](_notes/2017-06/30-069.md) 6 | -------------------------------------------------------------------------------- /_notes/2017-06/30-031.md: -------------------------------------------------------------------------------- 1 | # octolinker 2 | 3 | 4 | 5 | Browser extension that turns js packages (in `package.json` or `require / import`) into clickable links. 6 | -------------------------------------------------------------------------------- /_notes/2017-06/30-044.md: -------------------------------------------------------------------------------- 1 | # orchestral music 2 | 3 | - [Britten - Four Sea Interludes](https://www.youtube.com/watch?v=ht9mQE6X0C0) 4 | - [Saint-Saens: Symphony No. 3 "Organ" - Finale](https://youtu.be/eW-7S9fjyfU?t=32s) 5 | -------------------------------------------------------------------------------- /_notes/2017-08/11-010.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Aug 11 2017 12:30:17 GMT+1000 (AEST) 3 | --- 4 | 5 | As far as quick desserts go this one is not bad: http://www.domesblissity.com/2017/07/30-sec-self-saucing-chocolate-pudding.html 6 | -------------------------------------------------------------------------------- /_notes/2017-06/30-024.md: -------------------------------------------------------------------------------- 1 | # flow: add definitions for common libraries 2 | 3 | 4 | 5 | - install the cli: `npm install -g flow-typed` 6 | - then in your project directory, run `flow-typed install` 7 | -------------------------------------------------------------------------------- /css.md: -------------------------------------------------------------------------------- 1 | # css 2 | 3 | - [immutable css with cmz](_notes/2017-06/30-034.md) 4 | - [writing a postcss plugin](_notes/2017-06/30-068.md) 5 | - [css variables](_notes/2017-07/04-007.md) 6 | - [minimum viable css component](_notes/2017-10/17-007.md) 7 | -------------------------------------------------------------------------------- /_notes/2017-06/30-013.md: -------------------------------------------------------------------------------- 1 | # docker npm3 issue 2 | 3 | [Using Node with Docker](http://blog.cloud66.com/using-node-with-docker) 4 | 5 | Has a solution for the `EXDEV: cross-device link not permitted` error that you might see from an `npm install` 6 | -------------------------------------------------------------------------------- /_notes/2017-06/30-068.md: -------------------------------------------------------------------------------- 1 | # writing a postcss plugin 2 | 3 | - 4 | 5 | - Tutorial: 6 | -------------------------------------------------------------------------------- /_notes/2017-09/12-022.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 09:08:44 GMT+1000 (AEST) 3 | --- 4 | 5 | idea: all screenshots in your docs should be auto-generated. That way you can regen later if there are UI changes, and also use it to find regressions. 6 | 7 | -------------------------------------------------------------------------------- /_notes/2017-07/04-007.md: -------------------------------------------------------------------------------- 1 | very helpful screencast to get your head around css variables and how they change the way we structure css: https://www.youtube.com/watch?v=bpo1WwKa9bg 2 | 3 | [source](https://twitter.com/MikeRiethmuller/status/881747451253735424) 4 | -------------------------------------------------------------------------------- /_notes/2017-06/30-028.md: -------------------------------------------------------------------------------- 1 | # git: create a branch from a tag 2 | 3 | `git checkout -b ` 4 | 5 | where: 6 | 7 | - `` is the name of the branch you want to create 8 | - `` is the name of the tag. (Must match something from the output of `git tag`) 9 | -------------------------------------------------------------------------------- /_notes/2017-08/15-013.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Aug 15 2017 11:56:48 GMT+1000 (AEST) 3 | --- 4 | 5 | one day I'd like to try to set up something with dokku. Keeping these for future reference: 6 | 7 | - https://github.com/dokku/dokku 8 | - https://github.com/dokku/dokku-letsencrypt 9 | -------------------------------------------------------------------------------- /node.md: -------------------------------------------------------------------------------- 1 | # node 2 | 3 | ## env 4 | 5 | - [nvm slow startup time](_notes/2017-08/10-007.md) 6 | 7 | ## streams 8 | 9 | - [concating files with multistream](_notes/2017-06/30-041.md) 10 | 11 | ## principles 12 | 13 | - [app design principles](_notes/2017-08/17-015.md) 14 | -------------------------------------------------------------------------------- /_notes/2017-06/30-037.md: -------------------------------------------------------------------------------- 1 | # junk food ui 2 | 3 | - 4 | - why it's important to spend time getting the UI right, even when it's a non-graphical UI intended for programmers to use. 5 | - this is still just as much a design task requiring design exploration. 6 | -------------------------------------------------------------------------------- /_notes/2017-06/30-003.md: -------------------------------------------------------------------------------- 1 | # bottlenecks 2 | 3 | I'm realizing over & again that my biggest bottlenecks to productivity are: 4 | 5 | - being able to prototype a solution, without necessarily coding something. 6 | - being able to pass on a vision, high-level goals and constraints to a group. 7 | -------------------------------------------------------------------------------- /_notes/2017-09/12-020.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 09:00:04 GMT+1000 (AEST) 3 | --- 4 | 5 | # electron 6 | 7 | Q. under what conditions does `require` work in a frontend js module? 8 | 9 | - seems to work when I load the page over `file:///` but not `http://localhost` (dynamic page) 10 | -------------------------------------------------------------------------------- /_notes/2017-06/30-014.md: -------------------------------------------------------------------------------- 1 | # volumes in docker-compose.yml 2 | 3 | - when you specify a `volumes` field it creates a mapping between a directory on the host, and a counterpart directory in the container 4 | - 2-way sync: any changes to files are reflected in both places, regardless of where they originated 5 | -------------------------------------------------------------------------------- /_notes/2017-09/04-011.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Mon Sep 04 2017 15:28:48 GMT+1000 (AEST) 3 | --- 4 | 5 | # connect to mysql running in docker 6 | 7 | Seems like to get this working you need to specify `--protocol=tcp`: 8 | 9 | ``` 10 | mysql -u$USER -p --host=localhost --port=3307 --protocol=tcp 11 | ``` 12 | -------------------------------------------------------------------------------- /_notes/2017-09/12-017.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 08:09:36 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | might think about adding `x.Self` and `x.Parent`, which provide placeholders for PropRefs 8 | 9 | although this depends on getters, so might hold on that until it's really needed. 10 | 11 | -------------------------------------------------------------------------------- /electron.md: -------------------------------------------------------------------------------- 1 | # electron 2 | 3 | - [executing js in a BrowserWindow](_notes/2017-06/30-017.md) 4 | - [learning about remote debugger](_notes/2017-08/07-004.md) 5 | - [using `require` in a BrowserWindow's script](_notes/2017-09/12-020.md) 6 | - [notes while upgrading `electron-hot`](_notes/2017-10/19-008.md) 7 | -------------------------------------------------------------------------------- /_notes/2017-08/04-001.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Aug 04 2017 09:55:28 GMT+1000 (AEST) 3 | --- 4 | 5 | https://github.com/s3ththompson/md-directory looks like just what I need for publishing journals. 6 | 7 | also should try https://github.com/cerebral/marksy to see whether it's an easier way to parse / manipulate. 8 | -------------------------------------------------------------------------------- /_notes/2017-06/30-012.md: -------------------------------------------------------------------------------- 1 | # builder pattern 2 | 3 | Reading about the docker "builder pattern": 4 | 5 | - http://blog.alexellis.io/mutli-stage-docker-builds/ 6 | - https://github.com/adobe-platform/porter/blob/master/docs/detailed_design/docker-builder-pattern.md 7 | - https://codefresh.io/blog/node_docker_multistage/ 8 | -------------------------------------------------------------------------------- /_notes/2017-08/11-009.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Aug 11 2017 12:08:26 GMT+1000 (AEST) 3 | --- 4 | 5 | would be cool to visualise code by showing multiple execution paths in a function. Eg. highlight a missing return 6 | 7 | this is something that is often visually not obvious, yet can lead to really hard-to-find bugs. 8 | 9 | -------------------------------------------------------------------------------- /_notes/2017-06/30-053.md: -------------------------------------------------------------------------------- 1 | # sitespeed 2 | 3 | https://github.com/sitespeedio/sitespeed.io 4 | 5 | Using docker it's really easy to create a sitespeed report: 6 | 7 | ``` 8 | docker run --privileged --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io --video --speedIndex https://www.sitespeed.io/ 9 | ``` 10 | -------------------------------------------------------------------------------- /_notes/2017-06/30-000.md: -------------------------------------------------------------------------------- 1 | reading [A story of a woman in the tech industry](https://medium.com/@fox/a-story-of-a-woman-in-the-tech-industry-5637ea19788) 2 | 3 | I have to ask myself: when that moment arrives and I am faced with the opportunity to either add to this problem or to fight it, what will I do? How can I make myself prepared? 4 | -------------------------------------------------------------------------------- /_notes/2017-08/04-002.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Aug 04 2017 10:38:04 GMT+1000 (AEST) 3 | --- 4 | 5 | - trying [`react-json-graph`](https://github.com/antonKalinin/react-json-graph) for journal viz 6 | - I really like the look of it but haven't been able to get it working after a few quick tries, so I'll move on for now, and maybe try again later. 7 | -------------------------------------------------------------------------------- /_notes/2017-08/11-011.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Aug 11 2017 12:50:00 GMT+1000 (AEST) 3 | --- 4 | 5 | some interesting stuff about cooking steak: http://www.seriouseats.com/2015/05/food-lab-how-to-grill-steak-cuts-of-steak-marbling-salting-charcoal-technique-resting-tips.html 6 | 7 | I haven't tried out any of these tips yet, will see how we go. 8 | -------------------------------------------------------------------------------- /_notes/2017-10/12-005.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Thu Oct 12 2017 16:45:35 GMT+1100 (AEDT) 3 | --- 4 | 5 | # debugging mailgun 6 | 7 | To get template vars working with mailgun I needed to set the `X-Mailgun-Recipient-Variables` header, rather than setting `recipient-variables` as recommended in the docs. 8 | 9 | More to come on this as I dig deeper... 10 | -------------------------------------------------------------------------------- /_notes/2017-06/30-022.md: -------------------------------------------------------------------------------- 1 | # Wrapping a function with falafel 2 | 3 | ```js 4 | function walk (node) { 5 | if (node.type === 'FunctionDeclaration') { 6 | if (node.id.name === 'findWord') { 7 | const orig = node.source.toString() 8 | node.body.update('{ return 99 }') 9 | } 10 | } 11 | } 12 | ``` 13 | -------------------------------------------------------------------------------- /babel.md: -------------------------------------------------------------------------------- 1 | # babel 2 | 3 | ## What's the difference between a preset and a plugin? 4 | 5 | - plugin: tells babel how to transform code 6 | - preset: a collection of plugins and config 7 | 8 | ## working with AST 9 | 10 | this is so useful to help with understanding the javascript Abstract Syntax Tree, and trying out transformations: 11 | -------------------------------------------------------------------------------- /_notes/2017-09/01-003.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Sep 01 2017 17:14:15 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | - removing css from the picture for now, and trying to figure out how to avoid ripple renders 8 | 9 | - note: we can't avoid which props are added to the outer component. But inner components we can decide how to render them based on what props they need. 10 | -------------------------------------------------------------------------------- /_notes/2017-09/04-010.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Mon Sep 04 2017 14:44:02 GMT+1000 (AEST) 3 | --- 4 | 5 | Avoid fat-arrowd and `.bind` in render functions: https://medium.freecodecamp.org/why-arrow-functions-and-bind-in-reacts-render-are-problematic-f1c08b060e36 6 | 7 | For maximum efficiency, render functions should be free of side-effects, and in this case even creating a new function can be considered a side-effect. 8 | -------------------------------------------------------------------------------- /_notes/2017-06/30-015.md: -------------------------------------------------------------------------------- 1 | # what's the `version: '2'` bit I sometimes see at the top of a `docker-compose.yml`? 2 | 3 | At first I was confused by this. Is "version 2" an upgrade, or a downgrade, from where I am now?? 4 | 5 | Answer: version 3 is the latest, and is the default if you don't specify a version. So don't worry about version 2. 6 | 7 | Ref: 8 | -------------------------------------------------------------------------------- /_notes/2017-06/30-042.md: -------------------------------------------------------------------------------- 1 | # passing args into npm run-scripts 2 | 3 | If you've got a package.json like: 4 | 5 | ``` 6 | ... 7 | "scripts": { 8 | "lint": "eslint src" 9 | } 10 | ... 11 | ``` 12 | 13 | and you want to run `eslint` with a different formatter, use the `--` separator followed by the args you want to run `eslint` with: 14 | 15 | ``` 16 | npm run lint -- --format unix 17 | ``` 18 | -------------------------------------------------------------------------------- /_notes/2017-06/30-019.md: -------------------------------------------------------------------------------- 1 | # erase a cdrw 2 | 3 | I had to erase a CD-RW in MacOs today, and Disk Utility was not giving an option to do it. Finally found there's a way to do it via command line. Even better! 4 | 5 | ``` 6 | drutil -drive 1 erase quick 7 | ``` 8 | 9 | There's also the option to use `full` instead of `quick`. Not 100% sure what that means, I guess maybe you want it if there is any sensitive data on the CD. 10 | -------------------------------------------------------------------------------- /_notes/2017-06/30-052.md: -------------------------------------------------------------------------------- 1 | # screenshots 2 | 3 | - does a good job of waiting until the page has loaded / redirected before taking the screenshot 4 | - doesn't give a way to set request headers or cookies, so adding that myself 5 | 6 | - [nightmare](https://github.com/segmentio/nightmare) also looks good, need to compare. 7 | - nice companion: 8 | -------------------------------------------------------------------------------- /_notes/2017-06/30-056.md: -------------------------------------------------------------------------------- 1 | # tcomb: custom fail handler 2 | 3 | By default, when a type validation fails `tcomb` throws a `TypeError`. In local development it can be useful to override this behaviour and start the debugger instead. Then we can easily browse up the stack to identify where the data came from: 4 | 5 | ```js 6 | const t = require('tcomb') 7 | 8 | t.fail = function fail (message) { 9 | debugger 10 | } 11 | ``` 12 | -------------------------------------------------------------------------------- /_notes/2017-06/30-033.md: -------------------------------------------------------------------------------- 1 | # idea: headless backend 2 | 3 | - create the data models and business logic etc, and then step through all functionality 4 | - at each step it asks you questions: 5 | - _"has the user exceeded their quota?"_ 6 | - _"was there a payment error?"_ 7 | - and the response can also contain new URLs to complete various follow-up actions 8 | - the goal is that we present a graph of possible next-steps and outcomes 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # knowledge 2 | 3 | Repository for recording knowledge about things I'm learning and things I'm interested in. Inspired by @yoshuawuyts [knowledge repository](https://github.com/yoshuawuyts/knowledge) 4 | 5 | ## web ring 6 | 7 | There are a few other knowledge lists. Join us here: https://github.com/RichardLitt/meta-knowledge/blob/master/README.md 8 | 9 | ## License 10 | 11 | [MIT](https://tldrlegal.com/license/mit-license) 12 | -------------------------------------------------------------------------------- /_notes/2017-08/04-003.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Aug 04 2017 10:43:26 GMT+1000 (AEST) 3 | --- 4 | 5 | [Kevlin Henney - Seven Ineffective Coding Habits of Many Programmers](https://vimeo.com/97329157) 6 | 7 | - "weird ways of looking at code, to understand it better". Some cool ideas about how visualising code. 8 | - I like this idea of a tag cloud as a way of surfacing information. Not sure if it's useful for every case, but there's something there... 9 | -------------------------------------------------------------------------------- /_notes/2017-06/30-001.md: -------------------------------------------------------------------------------- 1 | problem: often I have multiple things to cover with a person, but because of timezone difference I have to do it via text. I am mindful of overloading people and things being missed as a result. There's a limit to the number of questions you can ask in one go. 2 | 3 | So I need to find a way to open (and continue) several ongoing topics / threads 4 | 5 | ## possible solutions 6 | 7 | - private gists? 8 | - self-hosted etherpad? (is this still a thing?) 9 | -------------------------------------------------------------------------------- /_notes/2017-06/30-016.md: -------------------------------------------------------------------------------- 1 | # efficient process 2 | 3 | One of the ways I know about improving efficiency is to batch operations. So if you have to make 10 sandwiches you don't make 1 sandwich then start on the next. You slice 20 pieces of bread, butter 20 pieces of bread, etc. 4 | 5 | This leads to less context switching, and also highlights opportunities for automation or abstraction. Like what if there was such a thing as pre-sliced bread? That would be the best thing ever. 6 | -------------------------------------------------------------------------------- /productivity.md: -------------------------------------------------------------------------------- 1 | # productivity 2 | 3 | ## notes 4 | 5 | - [bottlenecks](_notes/2017-06/30-003.md) 6 | - [clarity](_notes/2017-06/30-004.md) 7 | - [batching for efficiency](_notes/2017-06/30-016.md) 8 | - [time limit on tasks](_notes/2017-06/30-058.md) 9 | - [today VS tomorrow](_notes/2017-06/30-059.md) 10 | - [types of work](_notes/2017-06/30-061.md) 11 | - [idea: personal docket system](_notes/2017-07/03-001.md) 12 | - [high-brain, low-brain](_notes/2017-07/03-002.md) 13 | -------------------------------------------------------------------------------- /_notes/2017-06/30-039.md: -------------------------------------------------------------------------------- 1 | # idea: mdx 2 | 3 | A variant of markdown which can include jsx components. 4 | 5 | the vision: modular web pages which export both content and data 6 | 7 | ## why? 8 | 9 | - might be a useful way to write documents that contain a mixture of prose & data, and that can be used in rich visualizations. 10 | - i always run into walls when trying to stretch markdown too far. In a lot of cases I'd rather just use plain markdown, and use jsx for more complicated things. 11 | -------------------------------------------------------------------------------- /_notes/2017-07/25-013.md: -------------------------------------------------------------------------------- 1 | # gwen 2 | 3 | Trying it out: 4 | 5 | - installed latest binary following these instructions: https://github.com/gwen-interpreter/gwen-web/wiki/Installation 6 | - installed geckodriver: https://github.com/mozilla/geckodriver/releases/tag/v0.18.0 7 | - configured gwen to use it: https://github.com/gwen-interpreter/gwen-web/wiki/Runtime-Settings 8 | - ran the example: 9 | 10 | ``` 11 | ./gwen -b features/todo/tables/TodoTable.feature 12 | ``` 13 | 14 | seems to work well 15 | -------------------------------------------------------------------------------- /_notes/2017-07/24-012.md: -------------------------------------------------------------------------------- 1 | webaudio pain points 2 | 3 | - creating a source, and then multiple filters / gains / etc. 4 | - you have to create each one in turn, and then connect them all together. And then elsewhere in code you have to remember which one was the last, so you can connect to the ac destination 5 | - would be easier if you could just create-and-connect in one operation 6 | - could also have a convention of `volumeIn` and `volumeOut` gains at either end of the pipe. Could be useful, could be wasteful, not sure yet. 7 | -------------------------------------------------------------------------------- /_notes/2017-10/11-004.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Wed Oct 11 2017 14:37:25 GMT+1100 (AEDT) 3 | --- 4 | 5 | # categories of docs 6 | 7 | I'm doing a big review / cleanup / refactor of all documentation for one of our projects today, and noticing some distinct categories: 8 | 9 | - **Product**: info about the product itself, and rationale behind our approach 10 | - **Process**: how we work together as a team 11 | - **Code**: specific implementation details 12 | - **Dev Environment**: Tools & Tips that can improve team productivity 13 | -------------------------------------------------------------------------------- /_notes/2017-06/30-071.md: -------------------------------------------------------------------------------- 1 | # ffmpeg with concatdemuxer 2 | 3 | Stitch together frames to make a video: 4 | 5 | ``` 6 | file '/path/to/dog.png' 7 | duration 5 8 | file '/path/to/cat.png' 9 | duration 1 10 | file '/path/to/rat.png' 11 | duration 3 12 | file '/path/to/tapeworm.png' 13 | duration 2 14 | file '/path/to/tapeworm.png' 15 | ``` 16 | 17 | https://ffmpeg.org/ffmpeg-formats.html#concat 18 | https://trac.ffmpeg.org/wiki/Slideshow#Concatdemuxer 19 | 20 | Thanks to [@zhewison](https://github.com/zhewison) for this nice tip :) 21 | -------------------------------------------------------------------------------- /_notes/2017-10/17-007.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Oct 17 2017 21:10:49 GMT+1100 (AEDT) 3 | --- 4 | 5 | # minimum viable css component 6 | 7 | completely arbitrary and useless :) but helpful to think through some different approaches: 8 | 9 | ``` 10 | .circle { 11 | width: var(--size); 12 | height: var(--size); 13 | border-radius: var(--size); 14 | } 15 | ``` 16 | 17 | ``` 18 | import circle from 'circle-css' 19 | 20 |
21 | 22 |
23 | ``` 24 | -------------------------------------------------------------------------------- /_notes/2017-06/30-041.md: -------------------------------------------------------------------------------- 1 | # multistream 2 | 3 | 4 | 5 | > A stream that emits multiple other streams one after another (streams2) 6 | 7 | Handy for concating several files together, eg. 8 | 9 | ```js 10 | const fs = require('fs') 11 | const multistream = require('multistream') 12 | 13 | // concat file1.txt and file2.txt, and write the result to all.txt 14 | const streams = ['file1.txt', 'file2.txt'].map(filename => fs.createReadStream(filename)) 15 | multistream(streams) 16 | .pipe(fs.createWriteStream('all.txt')) 17 | ``` 18 | -------------------------------------------------------------------------------- /_notes/2017-09/04-009.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Mon Sep 04 2017 13:10:51 GMT+1000 (AEST) 3 | --- 4 | 5 | # react components 6 | 7 | There's 2 ways to think about pure components in react: 8 | 9 | - A. takes some props as input, and returns some virtual dom 10 | - B. takes some props as input, and returns a set of new props 11 | 12 | I feel like there's a nice conceptual simplicity in the second approach. If we define the props and their dependencies, computer should be able to infer a lot about how to create the virtual dom without needing to specify everything by hand. 13 | -------------------------------------------------------------------------------- /ffmpeg.md: -------------------------------------------------------------------------------- 1 | # ffmpeg 2 | 3 | ## rotate a video 90 degrees 4 | 5 | ffmpeg -i in.mov -vf "transpose=1" out.mov 6 | 7 | ## resize a gif 8 | 9 | Resize `in.gif` to be 320 px wide and maintain aspect ratio. 10 | 11 | ffmpeg -i in.gif -vf scale=320:-1 out.gif 12 | 13 | ## concat gifs 14 | 15 | Note: might need to convert gifs to another format first, and then convert 16 | them back again at the end. 17 | 18 | ffmpeg -f concat -i files.txt -codec copy all.mov 19 | 20 | ## make a video from frames 21 | 22 | - [with concatdemuxer](_notes/2017-06/30-071.md) 23 | -------------------------------------------------------------------------------- /_notes/2017-06/30-018.md: -------------------------------------------------------------------------------- 1 | # opening files with `sudo` 2 | 3 | When you open a file, if you start the path with `/sudo:root@localhost:` you'll get a prompt for your user's `sudo` password. After entering a correct password, you enter the file path. 4 | 5 | So `/sudo:root@localhost:/some/protected/file` is a more convenient way to edit the file, rather than quitting and running `sudo emacs /some/protected/file`. 6 | 7 | ## bookmarking with `sudo` 8 | 9 | You can also use `/sudo:` in bookmarks. I've got a bookmark called "hosts" which jumps to `/sudo:root@localhost:/etc/hosts` 10 | -------------------------------------------------------------------------------- /_notes/2017-08/10-008.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Thu Aug 10 2017 14:17:30 GMT+1000 (AEST) 3 | --- 4 | 5 | # trying virtual-audio-graph 6 | 7 | - seems to be a bug in the example, creating multiple AudioContext's 8 | - fixed when I just let `ag` create its own 9 | 10 | - couple of times I misspelled `frequency` as `freqency`. And my code failed silently. Would be good to warn about unexpected params 11 | 12 | - need to make sure we don't mutate the `graph` when calling `ag.update()` subsequent times 13 | 14 | ``` 15 | ag.update(Object.assign({}, graph, { lfo: ha.osc('mod', { frequency: 1 }) })) 16 | ``` 17 | -------------------------------------------------------------------------------- /react.md: -------------------------------------------------------------------------------- 1 | # react 2 | 3 | - [conditions in react](_notes/2017-06/30-048.md) 4 | - [custom jsx elements](_notes/2017-06/30-047.md) 5 | - [refactoring a function to limit knowledge](_notes/2017-07/24-013.md) 6 | - [2 concepts of pure components](_notes/2017-09/04-009.md) 7 | - [avoid fat-arrows in render](_notes/2017-09/04-010.md) 8 | 9 | ## drx 10 | 11 | - [experimental declarative react](_notes/2017-08/21-019.md) 12 | - [thoughts on catch-22](_notes/2017-09/01-005.md) 13 | - [prop references](_notes/2017-09/04-007.md) 14 | 15 | ## redux 16 | 17 | - [actions and stores](_notes/2017-06/30-050.md) 18 | -------------------------------------------------------------------------------- /_notes/2017-09/01-004.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Sep 01 2017 17:15:15 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | - stuff is generally computed outside `DrxComponent` and then passed in 8 | - find out whether it's actually more performant to do `shouldRender` checks inside (does it prevent rerender of other things?) 9 | 10 | ``` 11 | const Root = x.div() 12 | 13 | const Image = Root.x.img() 14 | 15 | const Text = Root.x.span() 16 | ``` 17 | 18 | ``` 19 | 20 | 21 | 24 | 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /_notes/2017-09/12-014.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 08:08:41 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | Originally I was thinking that when a component depends on a prop from an ancestor higher than the direct parent, we would walk up the render tree to find the value. I was going to use `context` to keep track of parents. 8 | 9 | Problem I found with this is that since the direct parent is a PureComponent, it might not re-render even though the prop changed. 10 | 11 | I think if we were going to do this, we'd need to render all children up front. Not sure yet how that will effect re-renders. 12 | 13 | -------------------------------------------------------------------------------- /_notes/2017-06/30-027.md: -------------------------------------------------------------------------------- 1 | # fundamentalist 2 | 3 | I have a theory: everyone is a fundamentalist. 4 | 5 | Your fundamentals are your inner-most core values. In fact they go so deep that, until they are threatened, you often don't even identify what they are exactly. 6 | 7 | Yet they nonetheless shape one's actions, and are the lens through which one sees the world and fits it into a narrative. 8 | 9 | Being a "fundamentalist" is usually associated with being at best uptight, and at worst dangerous. But I'd like to suggest that it's neither good nor bad in itself - that is entirely determined by what one's fundamentals are. 10 | -------------------------------------------------------------------------------- /docker.md: -------------------------------------------------------------------------------- 1 | # docker 2 | 3 | - [builder pattern](_notes/2017-06/30-012.md) 4 | - [docker npm3 issue](_notes/2017-06/30-013.md) 5 | - [docker-compose volumes and syncing](_notes/2017-06/30-014.md) 6 | - [docker-compose version 2](_notes/2017-06/30-015.md) 7 | - [notes on caching](_notes/2017-07/26-015.md) 8 | - [connect to mysql](_notes/2017-09/04-011.md) 9 | 10 | ## env vars 11 | 12 | I usually have a file that sets the env vars of a container, using `env_file`: https://docs.docker.com/compose/environment-variables/ 13 | 14 | Sometimes it's helpful to also be able to [export these vars in the host](_notes/2017-08/14-012.md) 15 | -------------------------------------------------------------------------------- /_notes/2017-07/04-008.md: -------------------------------------------------------------------------------- 1 | # portfolio self-critique 2 | 3 | Here are a couple I wrote awhile back: 4 | 5 | - [Testing reducers](04-004.md) 6 | - [Agile methodology](04-005.md) 7 | 8 | To give more context on what I look for in a portfolio piece, the big difference between these 2 is that the "testing reducers" one gives a specific example from a project I worked on, whereas the "agile" one only gives a hypothetical example. 9 | 10 | This is what I mean when I talk about portfolio pieces that connect knowledge with experience. he more specific detail you can add about solving a real problem, the stronger it speaks of your experience. 11 | -------------------------------------------------------------------------------- /_notes/2017-09/12-018.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 08:10:05 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | one issue I've noticed: because I'm overwriting `DrxComponent.children` from a PropRef to a function, it can no longer be used as a propref. So there's no way to say "use the original children of the parent for the value of this prop". 8 | 9 | Is that even a thing you would want to do? Probably at times it's a valid use case. So at very least we need to give a helpful error message, at the moment it will just blow up. 10 | 11 | Maybe the solution is to make _all_ prop refs functions (setters) that also have metadata attached. 12 | -------------------------------------------------------------------------------- /_notes/2017-06/30-043.md: -------------------------------------------------------------------------------- 1 | # opinions in opensource 2 | 3 | one of the things I've been learning over the last few years is the importantance of opinions in opensource. Especially as you move from lower-level libraries to higher-level applications. 4 | 5 | I think this is one of the secrets of opensource: 6 | 7 | - don't build "for everyone", build "for yourself" 8 | - spend time crafting your opinions about how things should work, until they are strong opinions 9 | - make your opinions very clear. put them in the readme 10 | - then sometimes, others will see them and say _"hey, i can get behind those opinions"_. It's the seed from which a community grows. 11 | -------------------------------------------------------------------------------- /_notes/2017-09/01-001.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Sep 01 2017 17:12:31 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | - at the moment I'm creating sub-components that accept the props of the parent component. 8 | - would be better if the sub-components had little to no knowledge of the parent, and put the onus on the parent to map to the child 9 | 10 | ``` 11 | const Parent = x.div() 12 | .content( 13 | x(Child1).props({ ... }), 14 | x(Child2).props({ ... }) 15 | ) 16 | 17 | ``` 18 | 19 | - maybe add a `.select('prop1', 'prop2')` form 20 | - `.select('*')` or `.selectAll()` 21 | - or does it make more sense for "select all" to be the default? 22 | -------------------------------------------------------------------------------- /_notes/2017-06/30-010.md: -------------------------------------------------------------------------------- 1 | # debugging node 2 | 3 | Recent node versions (eg. v7.9.0) have some great debugging tools built in: https://nodejs.org/api/debugger.html 4 | 5 | You can run `node --inspect=9222 my-script.js` and use the interactive debugger in chrome devtools. 6 | 7 | You can also use the `--inspect-brk` flag which sets a breakpoint on the first line. For example, if you want to debug a monobrow build: 8 | 9 | ``` 10 | node --inspect-brk=9222 node_modules/.bin/monobrow 11 | ``` 12 | 13 | Once you have the devtools open, you can search the source and set new breakpoints, inspect values, etc. Really helpful way to see what is happening under the hood. 14 | -------------------------------------------------------------------------------- /_notes/2017-06/30-009.md: -------------------------------------------------------------------------------- 1 | # css-modulesify with postcss-copy-assets 2 | 3 | Goal: combine [css-modulesify](https://github.com/css-modules/css-modulesify/) with [postcss-copy-assets](https://github.com/shutterstock/postcss-copy-assets) so that any assets (like svg, images, fonts) referenced from css files can be automatically copied to the output directory. 4 | 5 | After a quick trial it looks like this will work, but we need to update `loader-core` to set a proper `from` and `to` when running the postcss chain (these are necessary to rewrite asset urls). 6 | 7 | ## other things to check 8 | 9 | - [ ] interop with watchify (updating an asset should trigger a re-copy) 10 | -------------------------------------------------------------------------------- /_notes/2017-09/12-016.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 08:09:18 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | need to change the logic a bit. At the moment we're saying: 8 | 9 | - if the component is an element, render it diretly as an element, with all selected props 10 | - automatically select props from the parent if any children have dependencies on a parent's props 11 | 12 | combining these 2 together, we can end up with a lot of unsupported attributes on elements. 13 | 14 | instead, we need to say: 15 | 16 | - look at whether the component is an element, and whether it is supporting any child dependencies, to determine whether to render the element alone, or a wrapper component around it. 17 | -------------------------------------------------------------------------------- /_notes/2017-07/01-000.md: -------------------------------------------------------------------------------- 1 | # laptop research 2 | 3 | - what do I mostly do? 4 | - writing 5 | - web 6 | - video conf 7 | - video / audio recording 8 | 9 | - probably want a power pack for flights / trips with no power: 10 | - http://www.macworld.com/article/3028132/consumer-electronics/best-usb-c-battery-pack-review.html 11 | - http://www.techradar.com/news/mobile-computing/a-laptop-battery-pack-is-your-dream-travel-companion-1309777 12 | 13 | - what's the diff between macbook, macbook-pro and macbook-air 14 | - i think out of the 3 mbp base model (don't care about touchbar) is going to be the best option 15 | 16 | - to find out: does extended applecare count if you're traveling overseas? 17 | -------------------------------------------------------------------------------- /_notes/2017-06/30-054.md: -------------------------------------------------------------------------------- 1 | # generosity in scarcity 2 | 3 | 4 | 5 | talk by [Tim Keller](http://www.timothykeller.com/) 6 | 7 | - "where your treasure is, there your heart will be also" ([matthew 6:21](https://www.biblegateway.com/passage/?search=Matthew+6&version=NIV)) 8 | - the things we most easily give our resources to are the things we treasure the most. 9 | - if someone considers themselves a christian: 10 | - you are called to give first and then figure out the practicality (rather than giving out of leftovers, after securing your own comfort). 11 | - you are called to check your privilege: you didn't earn money or status with hard work, it was given to you. 12 | -------------------------------------------------------------------------------- /_notes/2017-06/30-061.md: -------------------------------------------------------------------------------- 1 | # types of work 2 | 3 | In my day-to-day work I observe 4 main types of work, and I try to plan my day so that there will be elements of each, with a time of context-switch in between (even like a 5 minute walk is good). 4 | 5 | ## big-picture 6 | 7 | - planning, brainstorming, creating proposals 8 | 9 | ## small-picture 10 | 11 | - implementing & executing 12 | - can still be exploratory work: you don't always know exactly what needs to be done at this point, but you're getting into the details of a single aspect of a plan. 13 | 14 | ## review 15 | 16 | - taking stock of new information 17 | - searching for patterns 18 | 19 | ## social 20 | 21 | - following up people 22 | - meetings 23 | -------------------------------------------------------------------------------- /_notes/2017-06/30-038.md: -------------------------------------------------------------------------------- 1 | # left and right 2 | 3 | Q. What are some of the ways that both sides fail? These things aren't so obvious in the middle, but become more apparent as you get to the edges. 4 | 5 | ## right 6 | 7 | - emphasis on objective moral code means that some are inevitably born into positions of power, while others into positions of seemingly inescapable vulnerability. 8 | - the more confident we become in the idea of absolute "right and wrong" ways to live, the more we set ourselves up for hypocrisy. 9 | 10 | ## left 11 | 12 | - the left avoids hypocrisy by avoiding the idea of an objective moral code. 13 | - But this leads to absurdity. We recognise evil in the world, but who are we to judge "good" from "evil"? By what standard? 14 | -------------------------------------------------------------------------------- /github-prs.md: -------------------------------------------------------------------------------- 1 | # working with github pull requests locally 2 | 3 | Useful if someone submits a PR on your github project, and you want to try it out locally. Append this line to the `[remote "origin"]` section in your `.git/config` file: 4 | 5 | ``` 6 | fetch = +refs/pull/*/head:refs/remotes/origin/pr/* 7 | ``` 8 | 9 | So the whole section will now look something like this: 10 | 11 | ``` 12 | [remote "origin"] 13 | url = git@github.com:joshwnj/monobrow.git 14 | fetch = +refs/heads/*:refs/remotes/origin/* 15 | fetch = +refs/pull/*/head:refs/remotes/origin/pr/* 16 | ``` 17 | 18 | Now when you `git pull`, you'll see a bunch of "pr" branches. You can switch to a PR branch with it's ID, like this: 19 | 20 | ``` 21 | git checkout pr/9 22 | ``` 23 | -------------------------------------------------------------------------------- /_notes/2017-06/30-029.md: -------------------------------------------------------------------------------- 1 | # working with github pull requests locally 2 | 3 | Useful if someone submits a PR on your github project, and you want to try it out locally. Append this line to the `[remote "origin"]` section in your `.git/config` file: 4 | 5 | ``` 6 | fetch = +refs/pull/*/head:refs/remotes/origin/pr/* 7 | ``` 8 | 9 | So the whole section will now look something like this: 10 | 11 | ``` 12 | [remote "origin"] 13 | url = git@github.com:joshwnj/monobrow.git 14 | fetch = +refs/heads/*:refs/remotes/origin/* 15 | fetch = +refs/pull/*/head:refs/remotes/origin/pr/* 16 | ``` 17 | 18 | Now when you `git pull`, you'll see a bunch of "pr" branches. You can switch to a PR branch with it's ID, like this: 19 | 20 | ``` 21 | git checkout pr/9 22 | ``` 23 | -------------------------------------------------------------------------------- /_notes/2017-06/30-049.md: -------------------------------------------------------------------------------- 1 | # reason noob 2 | 3 | ^ it me 4 | 5 | ## modules and functions 6 | 7 | Coming from a node background, I'm used to thinking of a module as the basic building block of a program. Reason has modules, but it seems slightly different in concept: https://facebook.github.io/reason/modules.html 8 | 9 | From what I can see so far, a good place to start is to just declare functions straight up. I mayb find a need for "reason modules" later, but not there yet :) 10 | 11 | Looking at the bucklescript output, this: 12 | 13 | ```reason 14 | let sayHi name => "hello " ^ name ^ "!"; 15 | ``` 16 | 17 | produces this: 18 | 19 | ```js 20 | function sayHi(name) { 21 | return "hello " + (name + "!"); 22 | } 23 | 24 | exports.sayHi = sayHi; 25 | ``` 26 | -------------------------------------------------------------------------------- /_notes/2017-06/30-011.md: -------------------------------------------------------------------------------- 1 | # discipline 2 | 3 | - there is "skill" and then there is "discipline" 4 | - as with any habit-forming, consistency is greater than quantity. Everyone can start with _something_ and build upon that. 5 | - just like in physical training there are things we can do to help people form that discipline. A clear guideline that's easy to follow, and someone who will check up on you, that you are accountable to. 6 | - these 2 things (clear guideline & accountability) will also help us to avoid "the slump". As a project matures or deadlines encroach, disciplines can slip. Or a dev might spend 8 hours debugging something, which only equates to 1 line of code. Somebody needs to be there alongside them pushing through the tough patch. But the end result is growth. 7 | -------------------------------------------------------------------------------- /_notes/2017-08/18-017.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Aug 18 2017 17:12:07 GMT+1000 (AEST) 3 | --- 4 | 5 | # jest 6 | 7 | - don't `import jest`. Otherwise you get weird stuff like `jest.fn()` not working. The `jest` object is injected as a global when you run the `jest` cli. 8 | 9 | - if you're using `afterAll`, make sure any tests with promises return the promise (to ensure `afterAll` waits for things to finish) 10 | 11 | - when doing integration tests, make sure you `--runInBand` (because otherwise changes to db will happen in an unpredictable order) 12 | 13 | - if you're used to using `tape`, like me, beware that `test('...', (t) => { ... })` will hang because the first arg is a callback to signify done-ness: https://facebook.github.io/jest/docs/en/asynchronous.html#content 14 | -------------------------------------------------------------------------------- /portfolios.md: -------------------------------------------------------------------------------- 1 | # developer portfolios 2 | 3 | - actual code is less important than you might think. If you dump 1000 lines in front of a reviewer, they might skim it and miss the most important parts :) Keep code samples as small as you can, to highlight the best bits. 4 | 5 | - pseudocode can often be more useful than real code. And this is also a helpful way of getting around NDAs, IP ownership, etc. As long as you're not including any sensitive information. 6 | 7 | - a portfolio should tell a story that not only illustrates your experience, but shows how you gained it. Eg: 8 | - here's how I started doing `` 9 | - then I learned `` 10 | - now it looks like `` 11 | 12 | ## notes 13 | 14 | - [self-critique](_notes/2017-07/04-008.md) 15 | -------------------------------------------------------------------------------- /_notes/2017-06/30-040.md: -------------------------------------------------------------------------------- 1 | # modeling drafts 2 | 3 | When modeling "drafts" of something (eg. a form with a "save draft" / "resume draft" feature), consider making a _separate model_ altogether for the draft. Rather than adding a `isDraft` flag to the original model. 4 | 5 | ## Reasons 6 | 7 | - validation is different. A draft doesn't need to include required fields, or have intact relationships with linked entities 8 | - you want to be able to safely save the model without accidentally triggering an action you shouldn't. Eg. if there's an `afterSave` hook which sends an email, or adds the model to a processing queue, you probably don't want to do that for drafts. Case in point is Bugwolf. There was logic which said _"when a project model is saved, send email invitations to all testers."_ 9 | -------------------------------------------------------------------------------- /_notes/2017-06/30-050.md: -------------------------------------------------------------------------------- 1 | # redux 2 | 3 | ## atomic actions 4 | 5 | - each action represents an atomic change to the state 6 | - rather than naming by what makes most sense from a user's point of view, name the action according to the atomic change it makes 7 | - atomic, meaning that the state "makes sense" before and after 8 | - sometimes atomic also means "smallest possible". In this case I think it's ok to start with bigger atoms and split them later. 9 | 10 | ## binding action creators 11 | 12 | - tip: always bind action creators 13 | - [Idiomatic Redux: Why use action creators?](http://blog.isquaredsoftware.com/2016/10/idiomatic-redux-why-use-action-creators/) 14 | 15 | ## prefer flat stores 16 | 17 | I usually find if I have to nest a lot of stuff in a store, it really belongs in multiple stores 18 | -------------------------------------------------------------------------------- /tech-goals-for-2017.md: -------------------------------------------------------------------------------- 1 | # tech goals for 2017 2 | 3 | Some things I want to focus on in 2017: 4 | 5 | ## components components components components 6 | 7 | ![](./images/ballmer-developers.gif) 8 | 9 | The web has become component-shaped, and I want to learn how to get the most out of this. 10 | 11 | ## declarative languages 12 | 13 | I want to better understand the elements of good design when it comes to purely declarative languages, and where the strengths & weaknesses are. 14 | 15 | ## business rules 16 | 17 | No matter how well I think I know programming, there's always an unusual business rule from a real-world project that makes me question everything :) 18 | 19 | So I want to get better at writing code that doesn't buckle under real-world conditions, and learn the underlying principles at play. 20 | -------------------------------------------------------------------------------- /_notes/2017-06/30-007.md: -------------------------------------------------------------------------------- 1 | # core values 2 | 3 | Everybody has "core values". 4 | 5 | These values are what you _optimise your life towards_, and they influence every decision you make, though often subconsciously. Most of the time I am privileged to live in a performance surplus, so optimisation is not even a question. But when the chips come down I'm forced to choose: what is more important to me? A or B? These are the times you begin to see clearly what your core values are. 6 | 7 | _"Wisdom is proved right by her actions"_ 8 | 9 | **Experiment:** you probably have an idea of what your core values are, as they are wrapped up in what you aspire to and call "best". Think about some decisions you made today, or recently. Do they align with the values you expected them to? If not, this may be a time to learn something new about yourself. 10 | -------------------------------------------------------------------------------- /_notes/2017-06/30-072.md: -------------------------------------------------------------------------------- 1 | # js arrow functions 2 | 3 | TIL: arrow functions have no `arguments`: 4 | 5 | eg. 6 | 7 | ```js 8 | const arrowFunc = (a, b) => { 9 | // this doesn't work! 10 | console.log(arguments) 11 | } 12 | 13 | arrowFunc(1, 2) 14 | 15 | // ReferenceError: arguments is not defined 16 | ``` 17 | 18 | However, sometimes you might be tricked into thinking it _does_ exist, if your arrow function is inside a normal function: 19 | 20 | ```js 21 | function normalFunc (arg1) { 22 | const arrowFunc = (a, b) => { 23 | // this does work, but gives arguments of `func1`! 24 | console.log(arguments) 25 | } 26 | 27 | arrowFunc(1, 2) 28 | } 29 | 30 | normalFunc('yay') 31 | // { '0': 'yay' } 32 | ``` 33 | -------------------------------------------------------------------------------- /_notes/2017-06/30-036.md: -------------------------------------------------------------------------------- 1 | # jest snapshot testing 2 | 3 | I've tried using jest on 2 separate occasions before, and both times found it was either too weird or buggy. This was a while back. 4 | 5 | Seems to be a lot more stable now, so maybe 3rd time's the charm? I'm most interested in incorporating snapshot testing into my workflow. 6 | 7 | - https://facebook.github.io/jest/docs/tutorial-react.html 8 | - works with plain functions as well as react components. nice. 9 | 10 | - ava also has support for snapshot tests (uses jest-snapshot under the hood): https://github.com/avajs/ava#snapshot-testing 11 | - works well too, although when I tried to compare a snapshot I got an error with no stacktrace: `[TypeError: Cannot read property 'split' of null]` 12 | - worthwhile digging into this more later on. But for now might try jest some more and see where that leads. 13 | -------------------------------------------------------------------------------- /_notes/2017-06/30-059.md: -------------------------------------------------------------------------------- 1 | # Today VS Tomorrow 2 | 3 | I can categorise my work between **today stuff** and **tomorrow stuff**. In other words: 4 | 5 | - **today**: everyday management, admin, followups, checkins, etc. Small-picture details to keep things moving. 6 | - **tomorrow**: planning, investigating new opportunities. Big-picture value. 7 | 8 | Ideally I want to be spending the majority of my time in tomorrow-land. And that means finding ways to deal with the today-stuff so I'm not bogged down. 9 | 10 | This is where "creating time" comes in. The time I can create is _time for tomorrow stuff_. Time is created by reducing today stuff: 11 | 12 | - **do it more efficiently.** Can things be batched or automated? 13 | - **do less.** Are these things really necessary? What is their value in relation to other things? 14 | - **delegate.** Can someone else do it? 15 | -------------------------------------------------------------------------------- /_notes/2017-06/30-047.md: -------------------------------------------------------------------------------- 1 | # custom elements in react 2 | 3 | To make a custom jsx element, one easy way is to wrap it as a single-function component: 4 | 5 | ```js 6 | const React = require('react') 7 | 8 | const MyTag = function (props) { 9 | return React.createElement(props.inline ? 'span' : 'div', props) 10 | } 11 | 12 | // then we can use it in jsx: 13 | 14 |
15 | This is rendered as a div 16 | This is rendererd as a span 17 |
18 | ``` 19 | 20 | I like the approach of declaring a react component as a set of custom meaningful elements. Eg. 21 | 22 | ```js 23 | 24 | 25 | 26 | 27 | ``` 28 | 29 | is much better to work with than: 30 | 31 | ```js 32 |
33 | 34 |
35 |
36 | ``` 37 | -------------------------------------------------------------------------------- /_notes/2017-06/30-005.md: -------------------------------------------------------------------------------- 1 | # scratch: Code with Anna and Elsa 2 | 3 | 4 | 5 | - started this with my daughter (6), and she is really loving it after the first few puzzles. 6 | - there's some nice intro to geometry & angles, as well as thinking in patterns. 7 | - i like how it works with experimental play (eg. "What happens if i change this?") as well as encouraging to run the simulation in your head, and then use the computer to confirm your expectations. 8 | 9 | ## summary 10 | 11 | - I was helping my daughter at first, but after the first few I just let her experiment with it. When she got stuck, rather than telling her what to do, I gave her an idea of a different way to experiment (eg. "what if you change _that_ value?") 12 | - by the end she was figuring out the solutions without any help from me at all, and was so excited and proud of the achievement. 13 | -------------------------------------------------------------------------------- /_notes/2017-07/04-003.md: -------------------------------------------------------------------------------- 1 | # css-modulesify windows bug 2 | 3 | - taking a look at this issue: https://github.com/css-modules/css-modulesify/issues/74 4 | - the problem (or at least part of it) is that we're using `newPath[0] !== '/'` to tell if a path is absolute, but this is a false assumption on windows (as pointed out here https://github.com/css-modules/css-modulesify/issues/74#issuecomment-193521440) 5 | - WIP branch: `fix-windows-abs-path` using the `path-is-absolute` package 6 | - running `npm test` shows a failing test... output is correct, but order is different. 7 | - doing a clean install on master to track it down. 8 | - it's the upgrade to `css-modules-loader-core` behind it. Downgrading to 1.0.0 sees tests passing again 9 | - weird: upgraded back to 1.1.0 but now the bug is gone. maybe a phantom bug caused by a version mismatch 10 | - PR: https://github.com/css-modules/css-modulesify/pull/117 11 | -------------------------------------------------------------------------------- /_notes/2017-09/01-006.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Sep 01 2017 17:17:58 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | - decision: should props be opt-in or opt-out by default? 8 | - leaning towards opt-in... 9 | 10 | - Q. what would it look like if we didn't try to combine wrappers with elements? 11 | 12 | - innerProps are used on the element 13 | - if something is an innerProp, it will always be needed as an outerProp 14 | 15 | - we never need an outerProp unless it's used by .style / .props / .content 16 | 17 | - problem: when we set props with `.props({ ... })` it sticks for future renders... 18 | - perhaps most of the time we say `.props()` what we actually mean is `.defaultProps()` ? 19 | 20 | - when we say `.props` we're informing the parent how to render us 21 | 22 | - when is it that we actually need props on a wrapper that aren't on the element? 23 | - when we need render-logic (`.renderIf` or `.style`) 24 | -------------------------------------------------------------------------------- /_notes/2017-06/30-017.md: -------------------------------------------------------------------------------- 1 | # electron: Executing js in a BrowserWindow 2 | 3 | ### with `executeJavaScript` 4 | 5 | If you just want to run js in a page there is 6 | 7 | However if you want to read some information or get a result you need to use `ipc`. Example here of using `ipc` with `executeJavaScript` together: 8 | 9 | There's a small helper module for this too: 10 | 11 | ### with a `preload` script 12 | 13 | When creating a `BrowserWindow` you can specify a js file in the `webPreferences.preload` option: 14 | 15 | This file is run before any js, and has access to the electron API so you can set up communication over `ipc`. 16 | -------------------------------------------------------------------------------- /_notes/2017-08/17-016.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Thu Aug 17 2017 20:51:14 GMT+1000 (AEST) 3 | --- 4 | 5 | Listen: https://www.thegospelcoalition.org/article/white-supremacy-is-spiritual-bondage 6 | 7 | ## Notes 8 | 9 | The belief that one's ethnicity is in some way superior or nobler than another is not merely rude, unkind or ignorant. It is evil and ugly to the deepest degree. 10 | 11 | - in a few points in american history, a theology was formulated specifically to accomodate the racial caste system. 12 | - So even in the midst of the civil rights movement in the 50s and 60s, many church leaders found themselves completely theologically ill-equipped to see their own errors. 13 | 14 | - many americans are not so much "white-supremists" as "american-supremists". They consider america to be "God's chosen nation". 15 | 16 | - we need to be united by something stronger than nationality or ethnicity if we are ever to escape their bind. 17 | -------------------------------------------------------------------------------- /_notes/2017-06/30-075.md: -------------------------------------------------------------------------------- 1 | # Team communication 2 | 3 | Asking for direction is great, but always look for opportunities to become more self-sufficient. Then you'll be able to help the next person. 4 | 5 | Consider this progression: 6 | 7 | ## _what should I do next?_ 8 | 9 | Asking what to do next is fine, but think about the extra burden this puts on your team mates. You might be unintentionally setting the expectation that they are responsible for your productivity. 10 | 11 | ## _should I do {{thing}} next?_ 12 | 13 | Better, because even though you're somewhat reliant on others for direction, you're letting them know you've thought about it. 14 | 15 | You've also potentially lowered the effort for your team members to respond. If you're on the money they can just say "yep". 16 | 17 | ## _I'll start doing {{thing}} next because of {{reasons}}._ 18 | 19 | ![](http://i3.kym-cdn.com/entries/icons/square/000/022/266/brain.png) 20 | -------------------------------------------------------------------------------- /_notes/2017-07/05-009.md: -------------------------------------------------------------------------------- 1 | [Francis Chan: what is up with the number 666?](https://www.youtube.com/watch?v=ZLVAQ3EsrjI) 2 | 3 | - Revelation 13 has captured the imagination of the world. 4 | - the church is full of people who intellectually agree with what is said, but have never made an ongoing personal commitment to follow Jesus. 5 | - symbols pointing back to ancient empires, and of an empire to come which is stronger than all of them combined. 6 | - Q. what would it take for the whole world to be astonished, to the degree that people follow? 7 | - this all-powerful world leader will command war against followers of Jesus. 8 | - "had horns like a lamb, but spoke like a dragon". Looks like Jesus on the outside, but they speak the words of the devil. 9 | - Q. when everyone else in the world is doing things a certain way, and you'll be killed if you don't, will you still then choose your actions rationally, based on what you know to be true? 10 | -------------------------------------------------------------------------------- /_notes/2017-06/30-051.md: -------------------------------------------------------------------------------- 1 | # Requirements 2 | 3 | ## Record the facts 4 | 5 | - one way to gather requirements is to make a list of "facts" about how the system works. 6 | - these might also have accompanying notes to clarify edge cases 7 | - then whenever developing a feature, writing a QA script, or reporting a bug, try to refer to as many of these facts as possible 8 | - need a good way to search for them 9 | - should make it really easy to add new facts, even if there is some overlap 10 | - too confusing to try and describe the entire system in prose, but this way of describing the system is like pointalism: as we add more and more of these points, the whole picture begins to emerge 11 | - still useful to categorise things into sections / screens 12 | 13 | ## Annotate screenshots 14 | 15 | - ather than having to manually name each thing when you describe it, we need to be able to say "this thing" and point to an area in an image file. 16 | -------------------------------------------------------------------------------- /_notes/2017-07/26-015.md: -------------------------------------------------------------------------------- 1 | # Q. how to get the most out of docker build cache? 2 | 3 | Thoughts: 4 | 5 | - each line in the Dockerfile can be considered a cache-layer. If something changes and causes a layer to require rebuild, all following layers need a rebuild too. 6 | 7 | - structure the file so that more-expensive-and-less-likely-to-change things are as close to the top of the file as possible. 8 | 9 | - think about scenarios where things do change, and look at which expensive layers are invalidated. 10 | 11 | - say we have 2 costly (time-consuming) layers, A and B. 12 | - in scenario 1, only A needs to be rebuilt 13 | - in scenario 2, only B needs to be rebuilt 14 | 15 | - the problem here is that no matter which way you order it, you always end up doing some unnecessary rebuilding. (check: is this assumption correct?!) 16 | 17 | - it might be possible in this situation to improve by splitting A and B into 2 separate Dockerfiles 18 | -------------------------------------------------------------------------------- /_notes/2017-09/04-007.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Mon Sep 04 2017 13:10:32 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | I'm starting to see that an important part of this is the inter-dependencies between component's props. 8 | 9 | We could define dependencies like this: 10 | 11 | ``` 12 | const A = x({ 13 | message: 'default value' 14 | }) 15 | 16 | const B = x({ 17 | children: A.message 18 | }) 19 | ``` 20 | 21 | We could also use a define a dependency on more than 1 prop: 22 | 23 | ``` 24 | const A = x({ 25 | message: 'default value', 26 | shout: false 27 | }) 28 | 29 | const B = x({ 30 | children: x.from( 31 | A.message, A.shout, 32 | ({ message, shout }) => shout ? message.toUpperCase() : message 33 | ) 34 | }) 35 | ``` 36 | 37 | When we pass in `A.message` or `A.shout`, we're not passing values but "prop reference" objects. `drx` can analyse all of these references at startup-time to decide which props `A` should use when rendering child `B`. 38 | -------------------------------------------------------------------------------- /_notes/2017-06/30-046.md: -------------------------------------------------------------------------------- 1 | # Projects in Github 2 | 3 | ## Using github issues to discuss features 4 | 5 | Often features are discussed in multiple places like slack, google docs, or in-person meetings. It's important to have a primary location where all of the info and relevant discussion points are stored. 6 | 7 | Here's one way to do it using github issues: 8 | 9 | - When you want to propose a new feature, create a github issue with a special "feature" label. 10 | - discuss the feature and ask questions in github comments. Any out-of-band discussion can also be added or linked. 11 | - when all questions are answered and requirements finalized, edit the top-level description of the issue to reflect the final version. 12 | 13 | Using github issues has a couple of advantages: 14 | 15 | - per-issue subscriptions, so you are notified of updates 16 | - easy to embed images when needed (drag and drop files, or paste from clipboard) 17 | - easy to create cross-reference links between the feature & bug reports or pull-requests 18 | -------------------------------------------------------------------------------- /_notes/2017-08/10-007.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Thu Aug 10 2017 12:51:06 GMT+1000 (AEST) 3 | --- 4 | 5 | I found that the [`nvm`](https://github.com/creationix/nvm) setup in my `~/.bash_profile` was causing quite a big slowdown, whenver I opened a new terminal. 6 | 7 | Not exactly sure what is slow yet. Best quick fix I've seen is described in . In short: 8 | 9 | - create a symlink that points to the version of node you want to be your default: 10 | 11 | ``` 12 | cd ~/.nvm/versions/node/ 13 | ln -s v8.3.0 global 14 | ``` 15 | 16 | - edit your `~/.bash_profile` to use the symlink, and defer running `nvm.sh` until you actually need to use the `nvm` command: 17 | 18 | ``` 19 | export NVM_DIR="$HOME/.nvm" 20 | export PATH=$NVM_DIR/versions/node/global/bin:$PATH 21 | export MANPATH=$NVM_DIR/versions/node/global/share/man:$MANPATH 22 | 23 | nvm() { 24 | [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm 25 | nvm "${@}" 26 | } 27 | ``` 28 | 29 | 30 | -------------------------------------------------------------------------------- /_notes/2017-09/12-015.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 08:09:02 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | at startup time, when `c.children` is called, we can find out what proprefs the children need. 8 | 9 | but I wonder if we want do it here, because it might change later. 10 | 11 | Maybe at render-time. When we render a child-component: 12 | 13 | - what proprefs does the child need? (direct refs, x.from, x.when) 14 | - walk down the tree, and collect any proprefs from descendents 15 | - we can cache this part so we only need to walk the tree once 16 | 17 | When we call `getProps`, we're answering the question "what props does this component need to be rendered with", or "what is the prop signature of this component"? 18 | 19 | To answer that we need to check what the children want. 20 | 21 | ## alternative 22 | 23 | An alternative approach here would be: 24 | 25 | - in component A's `render()` method, walk down the tree to find any children that depend solely on component A's props. 26 | - render them, and pass them in as rendered children 27 | 28 | -------------------------------------------------------------------------------- /_notes/2017-06/30-060.md: -------------------------------------------------------------------------------- 1 | # travis ci 2 | 3 | 4 | 5 | ## detecting the travis environment 6 | 7 | `process.env.TRAVIS` is a handy way to tell whether your code is running on travis 8 | 9 | ## running karma tests in chrome 10 | 11 | Previously I only knew how to run karma tests in phantomjs, when using travis. This is fine for some things but falls apart when you need a more realistic browser environment. 12 | 13 | Turns out there's a way to use chrome in travis. 14 | 15 | - First you need to [add a `before_install` section in the `.travis.yml` config](https://github.com/joshwnj/react-visibility-sensor/pull/54/files#diff-354f30a63fb0907d4ad57269548329e3R7) 16 | - [Tell karma to use chrome when running on the travis environment](https://github.com/joshwnj/react-visibility-sensor/pull/54/files#diff-a2a3b7b0c9c3b4b93b4aebf4e3ec3cfbR52) 17 | - [Configure the `Chrome_travis_ci` browser](https://github.com/joshwnj/react-visibility-sensor/pull/54/files#diff-a2a3b7b0c9c3b4b93b4aebf4e3ec3cfbR55) 18 | 19 | Thanks to for introducing me to this! 20 | -------------------------------------------------------------------------------- /_notes/2017-09/01-005.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Fri Sep 01 2017 17:16:57 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx 6 | 7 | - I still feel like there's an elegent solution trying to get out here... 8 | - stuck on the interplay between `.props` and `.attr` 9 | - maybe we can settle on a solution where there's no difference between `.props` and `.attr`, but we apply an intermediate layer to do the filtering 10 | 11 | - ok so I'm defining the catch-22 as: 12 | - components need their output to be "a function" of their prop-sig 13 | - but we don't want all props in the prop-sig to become attributes element 14 | - it's tedious to manually whitelist attributes 15 | - it feels wasteful to filter from a whitelist of allowed html attributes 16 | 17 | - possible solutions 18 | - intermediate filter layer 19 | - shortcut for creating elements 20 | 21 | - the way react works well is: 22 | - each layer does a single meaningful transformation 23 | - every component is a function of its props 24 | 25 | - design goals: 26 | - keep things together that belong together 27 | - make it easy to do the right thing 28 | 29 | -------------------------------------------------------------------------------- /_notes/2017-06/30-006.md: -------------------------------------------------------------------------------- 1 | # computed fields in javascript 2 | 3 | Situation: we are fetching documents from a database, operating on them, making changes and storing them back in the database. 4 | 5 | Let's say we have a document like this: 6 | 7 | ``` 8 | const doc = { 9 | tastesLikeBacon: true, 10 | usesArtificialFlavours: false 11 | } 12 | ``` 13 | 14 | And we have a definition of "delicious" that means: 15 | 16 | - it tastes like bacon 17 | - it doesn't use artifical flavours 18 | 19 | Rather than duplicating information and adding an `isDelicious` field, we want to calculate the value from the other 2 fields. 20 | 21 | ## Option 1. create a class 22 | 23 | ``` 24 | const a = new Food(doc) 25 | a.isDelicious() ? ... : ... 26 | ``` 27 | 28 | - pros: familiar pattern for a lot of developers 29 | - cons: now we have to keep track of whether we have a class instance or a plain js object, and handling the marshalling for db reads & writes 30 | 31 | ### Option 2. just use functions 32 | 33 | ``` 34 | foodFuncs.isDelicious(doc) ? ... : ... 35 | ``` 36 | 37 | - pros: no temptation to form an inheritance hierarchy 38 | - con: ? 39 | -------------------------------------------------------------------------------- /_notes/2017-06/30-032.md: -------------------------------------------------------------------------------- 1 | # growing salad 2 | 3 | I had a bunch of rocket (arugula for my american buddies) plants growing over the summer. Got a few nice salads, and made some spicy garlic bread by blending up the leaves into a paste with butter & garlic. Rocket-butter is :100: on a steak btw. 4 | 5 | The leaves were significantly hotter (as in, peppery) than ones you get from the shops, and I'm wondering why. 6 | 7 | A clue came more recently: after letting all of the old plants go to seed, I cut them and hung to dry (they were pretty huge by this time), turned the soil and re-sowed. The second round took off quickly, and I noticed that the leaves had a much milder and more pleasant flavour this time. 8 | 9 | So I'm wondering what the difference was? 10 | 11 | - maybe it had something to do with the re-seeding? 12 | - maybe the soil had mellowed by the time of the second batch? 13 | - maybe it was weather related? (the second batch was in significantly cooler and wetter weather than the first). 14 | 15 | If I had to take a guess I'd say that higher heat / dryer ground was the main influencer of the leaves. Will try again next time and see if I can repeat it :) 16 | -------------------------------------------------------------------------------- /_notes/2017-07/25-014.md: -------------------------------------------------------------------------------- 1 | # john cleese on creativity 2 | 3 | [listen](https://soundcloud.com/londonscreenwriters/john-cleese-on-creativity) 4 | 5 | - "open and closed" 6 | - creativity thrives when we are "open" and playful, not stressed and time-constrained 7 | 8 | - alfred hitchcock mistrusted working under pressure: "we're pressing, we're working too hard" 9 | - co-writer: when we came to a blocker, hitchcock would suddenly stop and tell a story that was almost completely unrelated. He did this deliberately! 10 | 11 | - switching between "open" and "closed" is a way to be both creative & productive, for optimal efficiency 12 | - open: play, experiment, go on tangents 13 | - closed: focus on 1 thing 14 | - open: review how that went, look at the big picture 15 | - closed: refine and refocus 16 | 17 | - the problem is, we all too often get stuck in the closed mode. Creativity is not possible in the closed mode 18 | 19 | - a laugh happens when 2 ideas are connected in a new way, that generates some unexpected meaning or significance 20 | - computers can generate billions of possible connections and juxtapositions, but they will not be able to tell which ones "smell interesting" (intuition) 21 | -------------------------------------------------------------------------------- /_notes/2017-08/03-000.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Thu Aug 03 2017 11:39:21 GMT+1000 (AEST) 3 | --- 4 | 5 | # spectacle 6 | 7 | [source](https://github.com/FormidableLabs/spectacle) 8 | 9 | - using boilerplate, seems like a great way to get started 10 | 11 | - I wonder if there's a way to hook into forward / backward events, so I could for example add a css class instead of the usual `` behaviour 12 | 13 | ## styling 14 | 15 | I'm finding the builtin styling approach a bit confusing, but starting to see the rationale behind it: 16 | 17 | designed to be adaptive: https://github.com/FormidableLabs/spectacle/issues/172 18 | 19 | > Your base content area is 1000px x 700px. If you go below that, in width or height, it begins to scale the content using css transforms. 20 | 21 | The problem is that this appears to be sometimes happening unintentionally, which results in my base font sizes jumping around. 22 | 23 | I'm trying out adding `.spectacle-slide { max-height: 700px }` and see if I get more control that way. 24 | 25 | So far so good 26 | 27 | ``` 28 | cmz('spectacle-slide', ` 29 | max-height: 700px 30 | `).toString() 31 | ``` 32 | 33 | ## thoughts 34 | 35 | - I like a lot of the things that it does, but I can't help feeling it's doing a lot more than what I want... 36 | -------------------------------------------------------------------------------- /_notes/2017-06/30-025.md: -------------------------------------------------------------------------------- 1 | # FORC 2 | 3 | _"Fear of Removing CSS"_ 4 | 5 | - Q. why is it often difficult to delete css code? 6 | - global scope 7 | - cross-module cascading 8 | 9 | - "how easy will this be to remove?" is a helpful question to ask when considering technical debt 10 | 11 | - It's vastly easier to add complexity than it is to remove it 12 | - [Joe Armstrong: "the mess we're in"](https://vimeo.com/97408239) 13 | 14 | - golden rule: **you can remove code easily if you know where all of the dependencies are**, and can confirm that nothing depends on it. 15 | 16 | - what kinds of things can make it easier? 17 | - you can remove code easily if you know precisely where all of the dependencies are, and can confirm that nothing depends on it. 18 | - we already have a dependency tree of js modules, so if we consider css modules as part of this tree it's easy to prove the existence or absence of dependencies 19 | - avoid cascading from one module to another. Separate concerns so that we put display-logic in js, leaving css for pure styles 20 | - think about "hidden dependencies". When an html adds something to its `class` attribute, it depends on the css being there. When you write a cascade rule in css, there's a dependency, possibly between multiple css files. 21 | -------------------------------------------------------------------------------- /_notes/2017-08/14-012.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Mon Aug 14 2017 14:30:33 GMT+1000 (AEST) 3 | --- 4 | 5 | Say you have a file called `env/dev`, with environment vars in it like this: 6 | 7 | ``` 8 | # here is a comment 9 | PORT=8000 10 | 11 | # here is another comment 12 | SECRET=password123 13 | ``` 14 | 15 | Then you can populate the environment with `. env/dev` (or `source env/dev`). 16 | 17 | But sometimes this will not be sufficient. For example, when you set env vars this way they are not available within a `node` program. Eg. 18 | 19 | ``` 20 | > . env/dev 21 | > node -e 'console.log(process.env.SECRET)' 22 | undefined 23 | ``` 24 | 25 | In this case we have to `export` those vars. You can do it like this: 26 | 27 | ``` 28 | export $(cat env/dev) 29 | ``` 30 | 31 | But that will break if there are any comments in the file. We can filter out the comment-lines like this: 32 | 33 | ``` 34 | export $(cat env/dev | grep -v ^#) 35 | ``` 36 | 37 | Turns out you don't even need the `cat`: 38 | 39 | ``` 40 | export $(grep -v ^# env/dev) 41 | ``` 42 | 43 | ## Thanks 44 | 45 | - https://twitter.com/kamilogorek/status/896998135859425281 46 | - https://twitter.com/westonruter/status/896977465096130560 47 | - https://twitter.com/nacin/status/896983665456160768 48 | - [@armova](https://github.com/armova) 49 | -------------------------------------------------------------------------------- /_notes/2017-06/30-066.md: -------------------------------------------------------------------------------- 1 | # wireframing 2 | 3 | The purpose of a wireframe is not so much to tell us how something will look, but to give an idea of: 4 | 5 | - what data will be present 6 | - how the data is grouped and prioritized 7 | 8 | So obviously the visual aspect is an important one (grouping and prioritizing is achieved visually) but we can still express a lot of this with text. 9 | 10 | ## Example 11 | 12 | If we wanted to describe a `Tweet` (subcomponent of a `TwitterTimeline`) we might start by listing the data we need to display: 13 | 14 | ``` 15 | - Author avatar 16 | - Author name 17 | - Author handle 18 | - Time 19 | - Body 20 | - Number of replies 21 | - Number of retweets 22 | - Number of likes 23 | ``` 24 | 25 | Next we might split into primary / secondary, to show which fields should be given visual prominance. The split between primary / secondary is dependent on use-case, and we might need to cater for a few of these at once. In this case let's say our user is browsing a timeline, so the "primary" fields should be those which help to scan for interest: 26 | 27 | ``` 28 | primary: 29 | 30 | - Author avatar 31 | - Author name 32 | - Body 33 | 34 | secondary: 35 | 36 | - Author handle 37 | - Time 38 | - Number of replies 39 | - Number of retweets 40 | - Number of likes 41 | ``` 42 | -------------------------------------------------------------------------------- /_notes/2017-07/24-013.md: -------------------------------------------------------------------------------- 1 | # functions that know how to do one thing 2 | 3 | I came across some code like this today: 4 | 5 | ```js 6 | handleSubmit (formData) { 7 | const { actions, doc } = this.props 8 | actions.save({ 9 | ...formData, 10 | someField: parseInt(formData.someField, 10) 11 | }, doc) 12 | } 13 | ``` 14 | 15 | and while it's not terrible, it stands out that this function is doing more than it should. It knows how to: 16 | 17 | 1. normalize the form data (convert `someField` to an int) 18 | 1. call the `save` action 19 | 20 | If we rewrite those two things as separate functions: 21 | 22 | ```js 23 | normalizeFormData (data) { 24 | return { 25 | ...data, 26 | someField: parseInt(data.someField, 10) 27 | } 28 | } 29 | 30 | handleSubmit (formData) { 31 | const { actions, doc } = this.props 32 | actions.save(this.normalizeFormData(formData), doc) 33 | } 34 | ``` 35 | 36 | Now it reads more clearly, and we have an easy place to unit-test some edge cases in the `normalizeFormData` pure function. 37 | 38 | We've also gained some useful encapsulation. The `handleSubmit` function only needs to know about forwarding the data to the right place. All of the knowledge of the nature of that data is contained in the `normalizeFormData` function. 39 | -------------------------------------------------------------------------------- /_notes/2017-06/30-020.md: -------------------------------------------------------------------------------- 1 | # allocating VS estimating 2 | 3 | Here's the idea: stop _estimating_ how long software will take to build. _Allocate_ time instead. It's not a new idea, I'm just thinking through it :) 4 | 5 | It's sleight-of-hand in one sense. You still have to estimate how much time to allocate. But the vibe has totally changed now: 6 | 7 | - when we estimate something, we're saying _"I think it will take this long"_. Then if it takes longer, we say _"Oh well, looks like I didn't account for everything in my estimate"_. Solution: get better at guessing! 8 | - when we allocate time for something, we're saying _"This is how much time you've got to deliver"_. If it's going to take longer, we say _"Better figure out how to make this work"_. Solution: get better at reaching compromises and communicating. 9 | 10 | It might sound too strict, like you're choosing the box first and then deciding what to put in it. But developers are actually very good at doing that! By saying "make it fit" you're actually granting them some creative licence. If corners have to be cut, there's the beginning of a conversation from which the whole team can benefit. Maybe time needs to be extended to avoid cutting necessary features. Or maybe the developers have come up with a creative way to build your product in a shorter time. 11 | -------------------------------------------------------------------------------- /_notes/2017-06/30-034.md: -------------------------------------------------------------------------------- 1 | # Immutable CSS 2 | 3 | _The "C" is for "Composable"._ 4 | 5 | An approach to css which favours composition over cascading. 6 | 7 | ## media queries 8 | 9 | This is one of the big questions around immutable css. If we can't change the meaning of a class, how do we get it to display adaptively to different screen sizes? 10 | 11 | Here's what I've been trying lately: 12 | 13 | - define atoms for various style aspects 14 | - compose them together 15 | - we can also compose atoms media queries 16 | 17 | eg. 18 | 19 | ```js 20 | const cmz = require('cmz') 21 | 22 | const mediumText = cmz(` 23 | font-size: 3rem 24 | `) 25 | 26 | const largeText = cmz(` 27 | font-size: 5rem 28 | `) 29 | 30 | const c = cmz([ 31 | mediumText, 32 | atMedia({ min-width: 550 }, largeText) 33 | ]) 34 | 35 | //
...
36 | ``` 37 | 38 | `atMedia` above actually generates a new css class on-demand, wrapped in a media query: 39 | 40 | ```css 41 | @media (min-width: 550px) { 42 | .largeTextWhenMinWidth550 { 43 | font-size: 5rem; 44 | } 45 | } 46 | ``` 47 | 48 | Inspecting the DOM, it looks like this: 49 | 50 | ```html 51 |
...
52 | ``` 53 | 54 | So we can still have "conditional application" of atoms, without mutating them. 55 | -------------------------------------------------------------------------------- /_notes/2017-09/20-023.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Wed Sep 20 2017 15:44:32 GMT+1000 (AEST) 3 | --- 4 | 5 | # flowtype covariance / contravariance 6 | 7 | I came across this flowtype error in a react component: 8 | 9 | ``` 10 | Error: components/MyComponent.js:34 11 | 34: this.onChange = this.onChange.bind(this) 12 | ^^^^^^^^^^^^^^^ property `onChange`. Covariant property `onChange` incompatible with contravariant use in 13 | 34: this.onChange = this.onChange.bind(this) 14 | ^^^^^^^^^^^^^^^^^^^^ assignment of property `onChange` 15 | ``` 16 | 17 | It's a pretty common practice to bind methods like this in the constructor when writing react component classes. 18 | 19 | I'd like to understand better exactly what the flowtype error message is talking about. Possibly something to do with reassigning the value of `this.onChange`? 20 | 21 | In the meantime the solution is pretty easy. Add `onChange: Function` to the class: 22 | 23 | ``` 24 | class MyComponent extends PureComponent { 25 | onChange: Function 26 | 27 | constructor (props: Props) { 28 | super(props) 29 | 30 | this.onChange = this.onChange.bind(this) 31 | } 32 | 33 | // ...rest of class... 34 | } 35 | ``` 36 | 37 | You could also use a more descriptive type than `Function` but this is an easy way to iterate. 38 | -------------------------------------------------------------------------------- /_notes/2017-09/12-012.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Tue Sep 12 2017 08:06:04 GMT+1000 (AEST) 3 | --- 4 | 5 | # drx notes 6 | 7 | ## 2 ways to think about pure components 8 | 9 | A. takes some props as input, and returns a virtural dom 10 | 11 | B. takes some props as input, and returns a set of new props 12 | 13 | `drx` is focussing on the second option. Declaring the relationships and transformations to get from one component's props to another. 14 | 15 | ## wrapper with no type 16 | 17 | - if there's no children, just render null. 18 | 19 | ## renderif 20 | 21 | - `Drx.RenderIf` wrapper component 22 | - props passed in match the proprefs passed in to `x.renderIf` 23 | 24 | ## cloning prop refs 25 | 26 | - even when we make copies, still pass along the same prop refs (so we're not making copies of functions etc) 27 | 28 | ## context? 29 | 30 | - or something along the same lines 31 | - for rendertrees 32 | - when you render the root component, there won't be any context available, so you know it's a root. 33 | - add "root has rendered with these props" 34 | 35 | ## definitions and instances 36 | 37 | - when you call the `x()` function, we push onto a module-space array of component definitions and record the index as an ID. 38 | 39 | ## screencast demo 40 | 41 | - color picker 42 | - css classes / variables to prevent unnecessary rewrites 43 | 44 | -------------------------------------------------------------------------------- /_notes/2017-06/30-070.md: -------------------------------------------------------------------------------- 1 | # writing 2 | 3 | I've recently set a goal to do more writing as part of my day-job. Not because it's a natural thing for me, but because I want to get better at it. Not only because writing stuff down forces me to articulate what I think about it, but it's also a way I can share that journey with others. 4 | 5 | ## format 6 | 7 | I think a blog format is most suitable for this (more than a wiki / knowledgebase format) because it lends itself more to ongoing discovery, and figuring things out on the go. 8 | 9 | ## tools 10 | 11 | What simple tools will make it easier? 12 | 13 | - quickly create a post file. Shouldn't have to look around for where to put it. Just write. 14 | - quickly link to other posts, and quote them. 15 | - lint markdown for broken links, so we can safely refactor if we need to. 16 | 17 | So far I'm leaning towards this: 18 | 19 | - every post file follows a pattern of `posts/YYYY/MM/DD/{name}.md` 20 | - sometimes a post will reference a previous post. Editor shortcut is good for creating links. 21 | - can be useful to also have `topics/{name}.md` for a long-running topic summary. Kind of link an anchor, and easy to link to. 22 | - here's a simple bash script to start: you give it a name, it creates the file and opens in your favourite editor: https://gist.github.com/joshwnj/58e3cdac8b7ccf4c41fcff2b3ad3189e 23 | -------------------------------------------------------------------------------- /_notes/2017-06/30-063.md: -------------------------------------------------------------------------------- 1 | # idea: walkthroughs 2 | 3 | A `walkthrough` is an experimental approach for producing _verifiable documentation_. That is, the documentation tells us how the software is expected to work, and also gives a way to confirm whether it is working as described. 4 | 5 | The style of documentation is to describe a user's interaction with the software using a combination of text, graphics and data. 6 | 7 | ## How is this different from automated testing 8 | 9 | Unit tests and other forms of automated tests also provide a form of verifiable documentation, in that you can the tests to understand how the software should behave and you can run the tests to tell whether it's working as expected. 10 | 11 | Walkthroughs aren't intended to replace this style of testing, just to offer an alternative for certain cases where you're testing higher-level functionality and you want something more human-friendly. 12 | 13 | A key difference: unit tests and the like work by first setting up the state-of-the-world, then triggering an interaction, and then comparing the actual result to an expected result. With walkthroughs the focus is on capturing artefacts from the system (whether screenshots or data) and then comparing those reference artefacts to subsequent recordings, to see what changed. So they are less black-and-white and more difficult to fully automate, but require less overhead to create or refactor as requirements change. 14 | -------------------------------------------------------------------------------- /_notes/2017-08/07-004.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: Mon Aug 07 2017 15:38:36 GMT+1000 (AEST) 3 | --- 4 | 5 | # learning about electron & chrome remote debugger 6 | 7 | - trying to use `chrome-remote-interface` to dynamically update js source at runtime, following example here: https://github.com/cabul/electron-hot/blob/master/lib/index.js 8 | 9 | - I can see the script ID, it appears to be the same each time I run (although I do expect it will change at some point in future) 10 | 11 | - calling `client.Debugger.setScriptSource` 12 | - seems to be firing the error callback with an arg of `true` 13 | - ahh ok looks like `scriptId` needs to be a string, not an int 14 | 15 | - found this example here too: https://gist.github.com/paulirish/920a260cadfe05e8388c 16 | 17 | - `getScriptSource` is working, not seeing any change after calling `setScriptSource` though 18 | 19 | - but if I call `getScriptSource` a second time, I do see the new source. So it was set, it just didn't do anything in the browser window 20 | 21 | - one big roadblock here: as soon as I open the debugger console in the electron BrowserWindow, my remote debugger websocket requests all fail 22 | - looks like someone else found this too: https://gitter.im/mattdesl/wtch?at=54dceedde0d4eb7f0a49b6c1 23 | 24 | - at some point I'll try to make a small demo showing this stuff. 25 | 26 | - there seems to be some aggressive caching of `