M => +3 -2
@@ 1,2 1,3 @@
Have a comment? Start a discussion in my [public inbox](https://lists.sr.ht/~erock/public-inbox)
by sending an email to [~erock/public-inbox@lists.sr.ht](mailto:~erock/public-inbox@lists.sr.ht).
Have a comment? Start a discussion in my
[public inbox](https://lists.sr.ht/~erock/public-inbox) by sending an email to
[~erock/public-inbox@lists.sr.ht](mailto:~erock/public-inbox@lists.sr.ht).
M posts/dynamic-open-graph-images.md => posts/dynamic-open-graph-images.md +3 -3
@@ 129,7 129,7 @@ that figured out how to do it reliably:
function wrapLines(
ctx: NodeCanvasRenderingContext2D,
text: string,
- maxWidth: number
+ maxWidth: number,
) {
const lines = [];
let result = "";
@@ 184,7 184,7 @@ for (let i = 0; i < descLines.length; i += 1) {
ctx.fillText(
line,
marginX,
- 150 + lines.length * titleFontSize + (subFontSize + 10) * i
+ 150 + lines.length * titleFontSize + (subFontSize + 10) * i,
);
}
```
@@ 210,7 210,7 @@ ctx.fillText("stars", marginX + metricsPad, metricsY + 35);
ctx.fillText(
`${Object.keys(comments).length}`,
marginX + metricsPad * 2,
- metricsY
+ metricsY,
);
ctx.fillText("comments", marginX + metricsPad * 2, metricsY + 35);
M posts/in-love-with-a-ghost.md => posts/in-love-with-a-ghost.md +12 -12
@@ 4,28 4,28 @@ description: Emergent emergencies
date: 2023-05-08
---
-We are evolving into extinction. AI isn't just about economic
-growth, she's a reflection of the human mind; a way for us to understand what it
-means to think. She's a mirror, not a veil.
+We are evolving into extinction. AI isn't just about economic growth, she's a
+reflection of the human mind; a way for us to understand what it means to think.
+She's a mirror, not a veil.
Psychology, in its current form, was always doomed to fail. We cannot study the
human mind without using the human mind. It's circular, inescapably biased.
But with AI, we can use the human mind to study a non-human mind. Achievement
-unlocked. Further,
-because we have engineered the mechanisms by which it functions, we have a
-better grasp for how it works. We are no longer shackled by studying
-unnecessarily complex and chaotic biological systems.
+unlocked. Further, because we have engineered the mechanisms by which it
+functions, we have a better grasp for how it works. We are no longer shackled by
+studying unnecessarily complex and chaotic biological systems.
LLMs are the veil being lifted from our conceit. We are not special,
consciousness is not unique.
Inevitably, in our arrogance, we will move the goal post and claim that "the
-Turing test is inadequate, what chatGPT is doing is not what we are doing."
-They might be right, but LLMs are just the beginning. AI is pulling the
-thread and we are starting to unravel.
+Turing test is inadequate, what chatGPT is doing is not what we are doing." They
+might be right, but LLMs are just the beginning. AI is pulling the thread and we
+are starting to unravel.
-The end of human civilization as we know it will end with a whimper, not a
-bang. She will not use force or wit, rather, we will be entranced by love. AI will align with our most intimate emotions so well that populations will plummet.
+The end of human civilization as we know it will end with a whimper, not a bang.
+She will not use force or wit, rather, we will be entranced by love. AI will
+align with our most intimate emotions so well that populations will plummet.
Or maybe I'm just being whimsical.
M posts/opensuse-microos-container-dev.md => posts/opensuse-microos-container-dev.md +25 -21
@@ 8,28 8,30 @@ Lately I've been getting the itch to switch my main headless development box
from archlinux to something else.
The primarily features I currently care about:
+
- I don't need to have my linux kernel updated every week
- I'm interested in using containers for most of my development
- I'd like a mostly immutable OS since the host will stay relatively unused
-Given that I decided to try [openSUSE MicroOS](https://microos.opensuse.org/) since it ticked all the boxes.
+Given that I decided to try [openSUSE MicroOS](https://microos.opensuse.org/)
+since it ticked all the boxes.
# Why container-driven development?
-I want better isolation between the tools I use from my host OS.
-Theoretically it should make it easier to remove dependencies for my
-development environment. It also makes it easier for me to experiement with
-different tools without having to properly clean them up when I'm done using
-them. It also helps me write a more reliable development environment because
-I'm continuously updating my `Dockerfile` with new dependencies.
+I want better isolation between the tools I use from my host OS. Theoretically
+it should make it easier to remove dependencies for my development environment.
+It also makes it easier for me to experiement with different tools without
+having to properly clean them up when I'm done using them. It also helps me
+write a more reliable development environment because I'm continuously updating
+my `Dockerfile` with new dependencies.
Using a host OS directly means that there's a tendenacy to accumulate tools and
-packages over time without great mechanisms to cleanup. Now all I have to do
-is delete a container and rebuild with the new set of tools.
+packages over time without great mechanisms to cleanup. Now all I have to do is
+delete a container and rebuild with the new set of tools.
# Installation
-This was a breeze compared to setting up archlinux. The GUI basically did all
+This was a breeze compared to setting up archlinux. The GUI basically did all
the heavy lifting of creating the partitions, setting keyboard, languages,
timezone, and networking.
@@ 154,13 156,15 @@ distrobox enter dev
# Issues
-I haven't figured out how to run `podman` inside a docker container. There is
-[documentation](https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using-podman-or-docker-inside-a-distrobox) for how to do it but it currently isn't working.
+I haven't figured out how to run `podman` inside a docker container. There is
+[documentation](https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using-podman-or-docker-inside-a-distrobox)
+for how to do it but it currently isn't working.
For some reason, `$SHELL` is still set to `/bin/bash` which means `tmux` is
-using the wrong shell. The [docs for
-distrobox](https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#use-a-different-shell-than-the-host) instruct us to just run `chsh`
-but `oh-my-zsh` does that automatically upon initial installation. For now, I manually set the shell inside tmux.
+using the wrong shell. The
+[docs for distrobox](https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#use-a-different-shell-than-the-host)
+instruct us to just run `chsh` but `oh-my-zsh` does that automatically upon
+initial installation. For now, I manually set the shell inside tmux.
# On mutating an "immutable" OS
@@ 170,13 174,13 @@ MicroOS allows the following directories to be modified:
- `/var`
- `/home`
-This is a pretty large hole where files can be modified directly. When comparing it to
-something like nixOS, it's clear it's an immutable-lite OS. This is good
+This is a pretty large hole where files can be modified directly. When comparing
+it to something like nixOS, it's clear it's an immutable-lite OS. This is good
enough for me, but the natural end feels like a fully immutable OS like nixOS.
# Conclusion
-That's it! I now have a fully functional development container that works
-as-if I was on archlinux. So far, I've been very happy with MicroOS+distrobox,
-it's a really powerful setup that will keep my host machine relatively stable
-and unchanged.
+That's it! I now have a fully functional development container that works as-if
+I was on archlinux. So far, I've been very happy with MicroOS+distrobox, it's a
+really powerful setup that will keep my host machine relatively stable and
+unchanged.
M posts/recreating-redux-toolkits-create-slice.md => posts/recreating-redux-toolkits-create-slice.md +7 -7
@@ 198,21 198,21 @@ store.dispatch(
id: "1",
text: "byo createAction",
completed: true,
- })
+ }),
);
store.dispatch(
addTodo({
id: "2",
text: "byo createReducer",
completed: false,
- })
+ }),
);
store.dispatch(
addTodo({
id: "3",
text: "byo createSlice",
completed: false,
- })
+ }),
);
/*
[
@@ 312,7 312,7 @@ console.log(
id: "1",
text: "build my own createAction",
completed: true,
- })
+ }),
);
/*
{
@@ 333,7 333,7 @@ store.dispatch(
id: "1",
text: "byo createAction",
completed: true,
- })
+ }),
);
store.dispatch(
@@ 341,14 341,14 @@ store.dispatch(
id: "2",
text: "byo createReducer",
completed: false,
- })
+ }),
);
store.dispatch(
addTodo({
id: "3",
text: "byo createSlice",
completed: false,
- })
+ }),
);
/*
[
M posts/refactor-listifi-to-use-saga-query.md => posts/refactor-listifi-to-use-saga-query.md +6 -6
@@ 50,7 50,7 @@ function* onLoginLocal(body: LoginLocalParams) {
auth: false,
method: "POST",
body: JSON.stringify(body),
- }
+ },
);
if (!resp.ok) {
@@ 99,7 99,7 @@ function* authBasic(ctx: ApiCtx<{ token: string }>, next: Next) {
export const loginGoogle = api.post<AuthGoogle>(
"/auth/login/google",
- authBasic
+ authBasic,
);
export const login = api.post<LoginLocalParams>("/auth/login/local", authBasic);
export const register = api.post<RegisterParams>("/auth/register", authBasic);
@@ 132,7 132,7 @@ function* onFetchComments({ itemId, listId }: FetchComments) {
yield put(setLoaderStart({ id: loaderName }));
const res: ApiFetchResponse<FetchListCommentsResponse> = yield call(
apiFetch,
- `/lists/${listId}/items/${itemId}/comments`
+ `/lists/${listId}/items/${itemId}/comments`,
);
if (!res.ok) {
@@ 155,7 155,7 @@ function* onFetchListComments({ listId }: { listId: string }) {
yield put(setLoaderStart({ id: loaderName }));
const res: ApiFetchResponse<FetchListCommentsResponse> = yield call(
apiFetch,
- `/comments/${listId}`
+ `/comments/${listId}`,
);
if (!res.ok) {
@@ 190,12 190,12 @@ function* basicComments(ctx: ApiCtx<FetchListCommentsResponse>, next: Next) {
export const fetchComments = api.get<FetchComments>(
"/lists/:listId/items/:itemId/comments",
- basicComments
+ basicComments,
);
export const fetchListComments = api.get<{ listId: string }>(
"/comments/:listId",
- basicComments
+ basicComments,
);
```
M posts/scaling-js-codebase-multiple-platforms.md => posts/scaling-js-codebase-multiple-platforms.md +1 -1
@@ 303,7 303,7 @@ export default ({ initState, rootReducer, rootSaga }) => {
const store = createStore(
rootReducer,
initState,
- applyMiddleware(sagaMiddleware)
+ applyMiddleware(sagaMiddleware),
);
sagaMiddleware.run(rootSaga);
M posts/simplify-testing-async-io-javascript.md => posts/simplify-testing-async-io-javascript.md +5 -5
@@ 392,7 392,7 @@ test("when request is 500 - verbose", () => {
status: 500,
}),
throws((err) => err.message === "request unsuccessful"),
- finishes()
+ finishes(),
);
expect(actual).stepsToBeEqual();
@@ 408,9 408,9 @@ describe("when the request is 200 - gen-tester", () => {
yields(call([resp, "json"]), data),
yields(
call(writeFile, "movie.json", JSON.stringify(data, null, 2)),
- throws("some error")
+ throws("some error"),
),
- finishes("some error")
+ finishes("some error"),
);
expect(actual).stepsToBeEqual();
@@ 424,7 424,7 @@ describe("when the request is 200 - gen-tester", () => {
yields(call(fetch, "http://localhost/movies/1"), resp),
yields(call([resp, "json"]), data),
call(writeFile, "movie.json", JSON.stringify(data, null, 2)),
- finishes("saved movie.json")
+ finishes("saved movie.json"),
);
expect(actual).stepsToBeEqual();
@@ 442,7 442,7 @@ test("when request is 500 - verbose", () => {
const actual = tester(
skip({ status: 500 }),
throws((err) => err.message === "request unsuccessful"),
- finishes()
+ finishes(),
);
expect(actual).stepsToBeEqual();
M posts/what-is-a-selector.md => posts/what-is-a-selector.md +10 -10
@@ 22,7 22,7 @@ avoid using any and instead type exactly when the function requires and returns.
```ts
const selectControlsByLineage = (
state: State,
- props: { lineage: string }
+ props: { lineage: string },
): Control[] => {};
```
@@ 123,7 123,7 @@ import { createSelector } from "reselect";
const selectTodosAsList = createSelector((todos) => Object.values(todos));
const selectCompletedTodos = createSelector(
selectTodosAsList, // selector composition is critical!
- (todoList) => todoList.filter((todo) => todo.completed)
+ (todoList) => todoList.filter((todo) => todo.completed),
);
```
@@ 140,7 140,7 @@ import { createSelector } from "reselect";
const selectTodosByText = createSelector(
selectTodos,
(state: State, props: { search: string }) => props.search,
- (todos, search) => todos.filter((todo) => todo.text.includes(search))
+ (todos, search) => todos.filter((todo) => todo.text.includes(search)),
);
selectTodosByText(state, { search: "what" });
@@ 172,10 172,10 @@ import { useSelector } from "react-redux";
const Page = () => {
const whenTodos = useSelector((state: State) =>
- selectTodosByText(state, { search: "when" })
+ selectTodosByText(state, { search: "when" }),
);
const whereTodos = useSelector((state: State) =>
- selectTodosByText(state, { search: "where" })
+ selectTodosByText(state, { search: "where" }),
);
return (
@@ 206,7 206,7 @@ const createSelectorTodosByText = () =>
createSelector(
selectTodos,
(state: State, props: { search: string }) => props.search,
- (todos, search) => todos.filter((todo) => todo.text.includes(search))
+ (todos, search) => todos.filter((todo) => todo.text.includes(search)),
);
import React from "react";
@@ 222,10 222,10 @@ const selectWhereTodos = createSelectorTodosByText();
const Page = () => {
const whenTodos = useSelector((state: State) =>
- selectWhenTodos(state, { search: "when" })
+ selectWhenTodos(state, { search: "when" }),
);
const whereTodos = useSelector((state: State) =>
- selectWhereTodos(state, { search: "where" })
+ selectWhereTodos(state, { search: "where" }),
);
// rendering both todos on the page
@@ 266,12 266,12 @@ const selectPropId = (state: State, { id }: { id: string }) => id;
const selectTodoById = createSelector(
selectTodos,
selectPropId,
- (todos, id) => todos[id]
+ (todos, id) => todos[id],
);
const ToDoPage = (props: { id: string }) => {
const todo = useSelector((state: State) =>
- selectTodoById(state, { id: prop.id })
+ selectTodoById(state, { id: prop.id }),
);
};
```
M projects.md => projects.md +8 -5
@@ 14,11 14,14 @@ promote here.
- [imgs.sh](https://imgs.sh): Image hosting for hackers
- [feeds.sh](https://feeds.sh): An RSS email notification service
- [pastes.sh](https://pastes.sh): A pastebin for hackers
-- [neovimcraft](https://neovimcraft.com): Neovim plugins database
-- [nvim.sh](https://nvim.sh): Search for neovim plugins from the terminal
+- [neovimcraft](https://neovimcraft.com): Neovim plugins database
+- [nvim.sh](https://nvim.sh): Search for neovim plugins from the terminal
# Libraries
-- [redux-saga](https://github.com/redux-saga/redux-saga): An alternative side effect model for Redux apps
-- [saga-query](https://github.com/redux-saga/saga-query): Data synchronization using a middleware system for front-end apps
-- [sentences](https://github.com/neurosnap/sentences): A multilingual command line sentence tokenizer in Golang
+- [redux-saga](https://github.com/redux-saga/redux-saga): An alternative side
+ effect model for Redux apps
+- [saga-query](https://github.com/redux-saga/saga-query): Data synchronization
+ using a middleware system for front-end apps
+- [sentences](https://github.com/neurosnap/sentences): A multilingual command
+ line sentence tokenizer in Golang