Tuesday, October 1, 2024

genie come back

For a long time Macs had an easter egg where if you held the shift key while hitting "minimize" it would have a nice slow motion view that let you appreciate the animation (the Genie effect)

For some reason they removed it by default but DaringFireball points out you can get it back:

defaults write com.apple.dock slow-motion-allowed -bool YES; killall Dock
 

The Mac "minimize" view is always kinda interesting. It's sort of like putting something on the shelf, like how it takes it out of the normal cmd-tab flow.

Tuesday, September 24, 2024

a new minimalist web survey tool

 I made a new minimalist online survey/poll tool - kirk.is/polling/


Definitely one of those "scratch an itch" projects - there are certainly other options out there, but this just gets the job done in a nice concise way - minimalist, but with a few bells and whistles (drag and drop ordering, color coding of results, etc)

Decided to put it on github even though it's built in evergreen tech for reliability, not front end stuff to show off to potential employers

mo'money

 How to monetize your blog (a descent into madness)

Friday, September 20, 2024

note to self: canvas drawing app without p5

 I love how this is a baby drawing app in p5:
function draw() {
}
function mouseDragged(){
   line(pmouseX,pmouseY,mouseX,mouseY);
}

Cleaning up stickies from my desktop, I found this Codepen for a similar canvas based drawing app in vanilla JS.

Sunday, September 15, 2024

whalefall!

Are you familiar with Whale Fall?

Here's a cool description from tumblr:
"With a "normal" whalefall, we're talking about something (a dead whale, to be precise) that lands in an EXTREMELY nutrient-poor environment, the deep ocean. It's not the equivalent of "a truck full of free hamburgers lands from the sky in the middle of your neighbourhood". This is an environment where an important part of the food chain is "marine snow", aka flakes of organic matter (including feces) that drift down from above, and they eat that because it's possible to get nutrients from it. So when a whole-ass (or partial-ass, because it's already been nibbled on from sharks and the like) whale carcass arrives, it is something MAJOR. It starts a whole new localized ecosystem, an oasis of life; those that eat the dead whale, those that eat those that eat the dead whale, and so on. And as the whale is consumed, the creatures there shift, leaving when there's nothing left that they'd eat, arriving when parts of the whale that they DO eat are now exposed, and it continues until the very bones have been devoured.
Whalefalls are fascinating."
The tumblr post goes on to think about a "Sky Whale Fall", the death of a celestial being that changed the magic / cryptid ecosystem in an eldritch horror kind of way.
But, here's a less fun play on the idea - some industries are going through some serious, serious party-over-hangovers - tech and other startups after the thrill of COVID-era zero interest rates, the film industry once the streaming bonanza started running out of steam... but maybe more worrisome, what if the entire introduction of the Internet was similar?
"The invention of the internet is like a whale carcass at the bottom of the ocean. It's an anomaly that lasted 50 years. A lifetimes-long anomaly. Long enough that people started and ended their career within its duration. Long enough that books about "business practice" were written by people who thought it was a new normal. When tech VCs try to apply their startup culture to biotech, scientists have to slowly explain to them that you cannot launch a crop alpha release in 18 months"
Sobering metaphor. Especially for a guy who started his career as the whale was just hitting the seafloor, and just got laid off again.

Friday, September 13, 2024

redux, redux: why people like and dislike it

I was doing some debugging earlier this week on frontend heavy with Redux.

For those who don't know, React (or almost any component based UI system) has a problem - how to share information between parent and child (and grandchild and greatgrandchild etc) components.

No right-thinking developer likes to admit it, but sometimes you kind of "need" global variables, or at least some kind of widely shared state - but raw global variables are horrible, you don't know where or what may change the information you're depending on, you have to be careful a child's local variable doesn't share the same name as something from the wider context, etc.

Now "React 101" tells how you can have a component passing data to a direct child via props. And "React 102" explains how to have call backs so the child can set things in the parent. But again, having to explicitly pass across generations as props - from greatgrandparent to grandparent to parent to child is burdensome.

Eventually, when React got Hooks it got Contexts - roughly speaking it's just a nice way of declaring regions for semi-global variables, but its usage is declared pretty explicitly, with useContext() pulling the shared information back into local state.

Before Hooks' introduction 4-5 years ago, Redux was the go-to choice to solve the "global variable" issue Last year's State Of JS is curiously silent about it's current happenings, but its usage and popularity were strong but declining in previous years.

I always thought there was a fair amount to dislike about Redux even when it was the only game in town - it tends to put the code path for a single interaction all over the place - declare an action in one file, have something like a button click dispatch that action in another file, have a reducer take the action and modify the global store in another file, then back in the component use mapStateToProps or a useSelector hook to see and act on the change. 

(This is a somewhat contrived example, since a single UI action should often be handled as local state to a component, but I've definitely seen examples like this in the wild! And in any event, even for stuff making good use of Redux there's still at least 3 files for anything involving this kind of shared action -> state change -> display kind of chain.)

But doing some debugging (I suspect the problem was probably based on data from the endpoints, but I wanted to get a better feel for why a button was being hidden) - I admit Redux's devtools are kind of neat:

You can see the actions on the left, and what the state was at each action's point on the right (plus you can pin a certain tree of the state and see just when it gets modified.) I think there are also tools to time travel to earlier states - which very much embraces the declarative programming paradigm, the idealized world of state goes in, full UI comes out.

You still need to do bread-and-butter debugging (sometimes it might not be clear just which action or reducers are in play) but it is clearly a cool tool to have around.

Another advantage to heavy Redux use is its middleware; if you have most of your site tooled with Redux, you can have, say, analytics middleware that just listens for the relevant action events and record then them - this was one of the approaches we landed on with this project, and was cleaner than having to insert a lot of "onclick" monitors.

Thursday, September 5, 2024

more on pieter levels

Disclaimer: I do have a suspicion that I might not agree with all of Pieter Levels politics. (I think he wants Europe to be run a bit more like the USA, though I'm not convinced that's the best way to a good quality of life for most of us.)

(FOLLOWUP: listening to the whole podcast,. I think he might be a little libertarian/entrepreneurial but not much that seems that egregious politically)

Anyway, I did like this dive into his stack for MVPs.

I'm still curious when if ever he uses CSS toolkits - most of his sites look pretty sharp. So he either has started using something or he just has a very good eye for design, and goes back to a few tricks.

Wednesday, September 4, 2024

pieter levels is a hero of indie web dev

I lightly edited this transcript from Pieter Levels and Lex Friedman on the Lex Fridman podcast:
I'm seeing a revival now. People are getting sick of frameworks. Like all the JavaScript frameworks are so like, what do you call it? Like wieldy, so it takes so much work to just maintain this code and then it updates to a new version. You need to change everything. PHP just stays the same and works.

Yeah, can you actually just speak to that stack? You build all your websites, apps, startups, projects, all of that with mostly vanilla HTML... JavaScript, jQuery, PHP, and SQLite. And so that's a really simple stack, and you get stuff done really fast. Can you just speak to the philosophy behind that?

I think it's accidental, 'cause that's the thing I knew, like I knew PHP, I knew HTML, CSS, 'cause you make websites and when my startups started taking off, I didn't have time to... I remember putting on my to-do list like 'learn Node.js', 'cause it's important to switch, 'cause... This obviously is much better language than PHP, and I never learned it. I never did it, 'cause I didn't have time. These things were growing like this, and I was launching more project and I never had time. It's like one day, I'll start coding properly and I never got to it. -

I sometimes wonder if I need to learn that stuff. It's still to do for me to really learn Node.js or Flask [or] React. It feels like a responsible software engineer should know how to use these, but you can get stuff done SO fast with vanilla versions of stuff.

Yeah, it's like software developers if you wanna get a job and it's like, you know, people making stuff like startups and if you want to be entrepreneur probably maybe shouldn't, right?

I wonder if there's like, I really wanna measure performance and speed. I think there's a deep wisdom in that. I do think that frameworks and just constantly wanting to learn the new thing this complicated way of software engineering gets in the way. I'm not sure what to say about that, because definitely like you shouldn't build everything from just vanilla JavaScript or vanilla C, for example. C++ when you're building systems engineering is like, there's a lot of benefits for pointer safety and all that kind of stuff. So I don't know, but it just feels like you can get so much more stuff done if you don't care about how you do it.

Man, this is my most controversial take, I think, and maybe I'm wrong, but I feel like there's frameworks now that raise money. They raise a LOT of money. They raise 50 million, 100 million, 300 million dollars. And the idea is that you need to make the developers, the new developers, like when you're 18 or 20 years old, right? Get them to use this framework and add a platform to it. Where the framework can... It's open source, but you probably should use the platform which is paid to use it. And the cost of the platforms to host it are a thousand times higher than just hosting it on a simple AWS server or a VPS on DigitalOcean, right? So there's obviously like a monetary incentive here. We wanna get a lot of developers to use this technology and then we need to charge them money 'cause they're gonna use it in startups and then the startups can pay for the bills. It kind of destroys the information out there about learning to code because they pay YouTubers, they pay influencers, developer influencers is a big thing... And same thing what happens with like nutrition and fitness or something. Same thing happens in developing, they pay this influencer to promote this stuff, use it, make stuff with it, make demo products with it. And then a lot of people are like, "Wow, use this." And I started noticing this 'cause when I would ship my stuff, people would ask me, "What are you using?" I would say, "PHP, jQuery, why does it matter?" And people would start kind of attacking me like, "Why are you not using this new technology, this new framework, this new thing?" And I say, "I don't know, 'cause this PHP thing works and I'm not really optimizing for anything, it just works." And I never understood like why, I understand there's new technologies that are better and there should be improvement, but I'm very suspicious of money. Just like lobbying. There's money in this developer framework scene. There's hundreds of millions that goes to ads or influencer or whatever. It can't all go to developers. You don't need so many developers for a framework, and it's open source. To make a lot of more money on these startups.

So that's a really good perspective. But in addition to that is like, when you say better, it's like, can we get some data on the better? Because I wanna know from the individual developer perspective and then from a team of five, team of 10, team of 20 developers... Measure how productive they are in shipping features. How many bugs they create, how many security holes result.

PHP was not good with security for a while, but now it's good.

In theory, in theory- Is it though?

Now it's good.

No, now as you're saying it, I wanna know if that's true because PHP was just the majority of websites on the internet. Is it just overrepresented? Same with WordPress? Yes, there's a reputation that WordPress has a gigantic number of security holes. I don't know if that's true. I know it gets attacked a lot because it's so popular. It definitely does have security holes, but maybe a lot of other systems have security holes as well. Anyway, I just sort of questioning the conventional wisdom that keeps wanting to push software engineers towards frameworks, towards complex. Like super complicated sort of software engineering approaches that stretch out the time it takes to actually build a thing.

Man, 100%. And it's the same thing with big corporations. 80% of the people don't do anything. It's like- It's not efficient. Your benchmark is like people building stuff that actually gets done and like for society, right? If we wanna save time, we should probably use technology that's simple, that's pragmatic, that works, that's not overly complicated. It doesn't make your life like a living hell.

And use a framework one that obviously solves a problem, a direct problem that you-

Of course, yeah, of course. I'm not saying you should code without a framework. You should use whatever you want. But yeah, think it's suspicious. And I think it's suspicious. When I talk about it on the Twitter, there's this army comes out. There's these framework armies.

I wanna ask the framework army, what have they built this week?

A couple thoughts -

yeah, some of the coding practices encouraged by early PHP *were* terrible (automatically converting CGI params to variables).

And honestly, I don't think Vanilla JS is is that bad to build with relative to jQuery, with a site like You Might Need jQuery you really can get done what you need to do. (Honestly I should look into what CSS libraries Levels uses - the shallow stuff is like 80% of the perception a site.)

Finally, I'm not quite as suspicious about the "follow the money" aspect as Levels is - or at least I'm more aware of the peer pressure aspect, that it feels like so many engineers have really learned to love their chains in terms of complexity... maybe it's a path to better job security somehow, maybe opinionated frameworks scale better for larger teams? But to me, it always seems to get in the way of getting things done in a way that's productive in the short term and maintainable over 5-10 years.

Levels view about the money involved reminds me of this 20 years old essay from Joel "Joel on Software" Spolsky, Fire and Motion. The first half is about the intermittent trouble of getting started being productive in a workday, but then he pivots to his time is an Israeli Paratrooper, where he learned the trick of Fire and Motion - keep moving and keep firing to make the other guy keep his head down. He writes:
Think of the history of data access strategies to come out of Microsoft. ODBC, RDO, DAO, ADO, OLEDB, now ADO.NET – All New! Are these technological imperatives? The result of an incompetent design group that needs to reinvent data access every goddamn year? (That's probably it, actually.) But the end result is just cover fire. The competition has no choice but to spend all their time porting and keeping up, time that they can't spend writing new features.
Sometimes it feels like the "flavor of the month" frontend webdev is a victim of some of that - along with engineers who are more interested in HOW something is done than what actually is done.

Sunday, September 1, 2024

PHP rewriting path names to index.php without trailing slashes and losing POST info

One drawback of "raw PHP" style coding is often the lack of a router... I've rolled my own at least once (with a mix of .htaccess style rewrites parsing out the path 'by hand' in scrip to a single router file) but usually I just punt by using "[approot]/[ACTIONNAME]/index.php" folders - letting the ability to link to "[approot]/[ACTIONNAME]/" as the URL hide my horrible indiscretion of using PHP. 

 (I do feel like the simplicity PHP offers is making some level of comeback - and for me it has a proven track record of stability and simplicity over decades - when you come back to code, it's - lo and behold - still working years later and most often not THAT hard to trace through, with plenty of transparency)

One mistake I vaguely remembered making before has to do with how Apache and/or PHP rewrites can lose POST information.

Lets say I was making an app for easily conducting surveys and was hosting it at myserver.com/survey/

If I had a form that started

<form action="/survey/save" method="POST">

I might be in trouble without trailing slash! Looking at the network tab, it looks like there's a jump from /survey/save to /survey/save/ (and from thence to /survey/save/index.php) and so information doesn't actually get POSTed. But including in the trailing slash lets it work just fine.


Friday, August 30, 2024

against complexity

Developers Rail Against JavaScript ‘Merchants of Complexity’... I saw this and I went "right into my veins".

“I’m seeing a revival [of PHP] now. People are getting sick of frameworks. All the JavaScript frameworks are so… what do you call it, like [un]wieldy. It takes so much work to just maintain this code, and then it updates to a new version, you need to change everything. PHP just stays the same and works.”

-Pieter Levels


Monday, August 26, 2024

whatever you meter you get more of

 Nike’s $25B blunder shows us the limits of “data-driven”


Heh - and at the risk of saying  another thing you can always say at a meeting and people wil agree with: "It's all about finding that balance".


I do recall one small internal startup I was at that incentivized us with "if we get X,000 trial subscriptions by such and such a date, everyone gets a iPad for the holiday". BUT... marketing had a spigot of ad spend. And there was a pretty direct relation between subscriptions and ad spend. So... the taps were opened wide, we got our iPads, then the budgets went back down to a trickle.
 

So I guess you can never shake the need to be data driven (and not all gut feels) but you do need to be careful.

Tuesday, August 13, 2024

rock's law

 How to Build a $20 Billion Semiconductor Fab
Best Quote:

These enormous costs are ultimately due to the same factor that has steadily driven down the cost of semiconductors: Moore's Law, the observation that the number of components on an integrated circuit tends to double every two years. (There is a Moore's Second Law, also known as Rock's Law, which posits that the cost of a semiconductor fab doubles every four years.)

Sunday, August 11, 2024

throwback thu--sunday

Two articles I found relevant about how the computer scene of the 1980s is reflected today:

Clive Thompson on Back to BASIC. There seem to be a lot of engineers now who don't understand the run-eval loop that BASIC and Lisp used has tremendous power in keeping development dynamic and transparent, which is why it lived on and gained such traction with JS.


Anna Washenko on From Infocom to 80 Days: An oral history of text games and interactive fiction. That old Infocom parser was such a mind blower back in the day; able to parse moderately complex sentences and even have a sense of context ("Which book do you want to open, the green one or the red one?") at a time when other programs were all like "GET SWORD", "KILL DRAGON" was amazing. I wonder how LLM might come to play in this space, I know there have been some attempts to get one to play "DM" for a one person campaign...

Wednesday, August 7, 2024

two notes from the land of LLM

 One:

be really aware of the security holes you could be making especially in terms of markdown and images I guess...

Two:

kind of interesting to see how a company like Apple prompts LLMS to constrain what they will come back with (in terms of not hallucinating, not writing offensive stuff, and in what format.)

Friday, August 2, 2024

the dark ui of endless subscriptions

 I used to think "everything must be free (as in beer)" was the worse thing to happen to the web - people's (maybe understandable) uptightness about being nickel and dimed to death (remember ten cents per text message?) brought us into an age of endless ads and zero privacy.

But now it's also the age of its ugly cousin -vast forests of subscriptions and scams ( https://pleated-jeans.com/2024/08/01/infuriating-subscriptions-scams/ ). It's some of the worst of "Dark UI" (sometimes literally, like a few cases where it looks like the company makes the text for the unsubscribe page unreadable.)

I mean on some level I get it - even maintenance takes work and energy, and who doesn't dream of being a landlord collecting rent forever - but damn, it really is a hellscape out there.

Thursday, August 1, 2024

What You Don't See and What You Do

US Secretary of Transportation Pete Buttigieg, was on a recent episode of the 99% Invisible podcast (in their ongoing coverage of the book "The Power Broker") One thing he said really echoed into the podcast's title, about the importance of what you DON'T see:
Again, to my earlier point, its elegance is often in the fact that you DON'T think about it. The way I always approach and conceptualize these things is the less you have to worry about whether you're gonna get a glass of clean, safe drinking water or for that matter whether there's a hole in the road on the way to work - the more free you are to concentrate on whatever lifts your soul, you know? Whatever matters to you in life. Raising your kids, practicing your faith, starting a business, being a scholar, whatever it is.
But later in the podcast, he points out the power of making things MORE visible:
And I'll give you an example that's less in the realm of building things but is one of the most important things we [of the Department of Transportation have] worked on, which is how airlines treat their passengers. So there are some things we've been trying to to get done, and are still trying to get done, through rule-making. But the rule-making process, the Administrative Procedures Act, the notice and comment period - it can take years. While we were working on that, especially in the summer of 2022 when there were so many frustrations around cancellations and delays, the idea emerged that if we just put more information out in a really easy to understand form, that not only would help passengers know which airlines would take better care of 'em, but knowing it was out there might actually change the airlines' behavior. And living in this world where it takes months or years to do something, I asked the team 'well, ok if we set up a website, like how long would that actually take?' and they said 'we could do it in a couple of weeks' and I said, ok, I'll send a letter to all the CEOs of the airlines saying, 'hey, in a couple of weeks we're gonna put this website up, you might want to change your customer service plan before we do it, because there's gonna be a bunch of green checkmarks and red Xs' - and they DID! This was not an enforcement, we've done those, this was not a rule-making, we're doing those... this was just saying we're going to tell people what you're doing, so you might want to think about what you're doing... and it led to real change.

So, superficially a bit of a contradiction, but really two complementary ideas: both what you can take for granted and what you have awareness of can be greatly important, depending on the context. (Broad stroke implications for my job in UI/UX as well!) 

google, js, and you

I've worked at companies that did a great deal of double rendering to make sure that google saw the content, even when we filled in most of the content via Javascript. (Of course Google REALLY hates it if it figures out your content is different than what it scraped...) We would make a basic version via server side templates (FreeMarker), then redraw the screen - which Google also hates.

There was a lot of mystery about "is Google even rendering our JS?" but now this comprehensive article seems to say the answer is "yes": How Google handles JavaScript throughout the indexing process

Interesting that it treats URLs with ?cgi=something style arguments differently in terms of scheduling stuff...

Monday, July 29, 2024

the way we were

 Kottke just (re)posted WWW: The Way We Were (just noticed the acronym pun there) talking about how the show "Halt and Catch Fire" had a Don Draper-esque speech about the nascent potential of the earliest Web, and how it could be just anything.

There was a beautiful and egalitarian time shortly after that - even if you didn't want to pay to host your own website on the "Information Superhighway", "Geocities" was a free or cheap option to hang your shingle and put your stuff at a fixed URL.

But then - as the 2016 article mourns - FB came in and offered trivial sharing your stuff with friends and family, and then Twitter and Instagram rolled in to give you a shot at that ephemeral immortality of "going viral" with bon mots and images, respectively. And suddenly becoming a part of the endless stream made more sense than building your own little island

I know I'm biased. My twenty years of blogging (at my site kirk.is ) has given me an incredibly rich archive, even if its value is mostly just for me. (I can generally retrieve any half-remembered quote, anecdote, personal photo or meme) And the technology of my "side hustle" of Porchfest websites carries more in common with those early-web days - before UI work exploded into an impossibly wide and dense forest of libraries and frameworks.

So much was lost. Geeks used to think a good URL could be forever - and while the Wayback Machine is still fighting that war against entropy, I think the stream is this endless deluge encouraging all but the most stalwart to let stuff just get swept away. And maybe I'm foolish to be hoping for earthly immortality and not embracing the transience of all things. Still, I think we could do better.

about my new employer

 Excellent article from CodaMetrix's VP of Product Management + Development Lindsey Reilly, RN, MBA: How AI can change the way healthcare is delivered.

It echoes something I appreciated from an in-house presentation by our President / CEO Hamid Tabatabaie - yes coding (i.e. properly tagging medical diagnosis and treatment) has to be part of the conversation about billing (regardless of  everyone's shared concerns about financial flows of healthcare, increasing accuracy and reducing costs of coding is an important part of that) but also it empowers research - better data gathering and understanding via standardizing and automating.



Wednesday, July 17, 2024

everybody's free (to write websites)

By Sara Joy

Enbies and gentlefolk of the class of ‘24:

Write websites.

If I could offer you only one tip for the future, coding would be it. The long term benefits of coding websites remains unproved by scientists, however the rest of my advice has a basis in the joy of the indie web community’s experiences. I will dispense this advice now:

Enjoy the power and beauty of PHP; or never mind. You will not understand the power and beauty of PHP until your stack is completely jammed. But trust me, in 20 years you’ll look back at your old sites and recall in a way you can’t grasp now, how much possibility lay before you and how simple and fast they were. JS is not as blazingly fast as you imagine.

Don’t worry about the scaling; or worry, but know that premature scalability is as useful as chewing bubble gum if your project starts cosy and small. The real troubles on the web are apt to be things that never crossed your worried mind; if your project grows, scale it up on some idle Tuesday.

Code one thing every day that amuses you.

Style.

Don’t be reckless with other people’s data; don’t put up with people who are reckless with yours.

POSSE.

Don’t waste time on shiny new frameworks; sometimes they’re helpful, sometimes they’re a trap. The web platform doesn’t need gigs of node_modules.

Remember the guestbook entries you receive; forget the spam. If you succeed in doing this well, tell me how.

Keep your old site designs. Throw away your old nested <div>s.

Flex.

Don’t feel guilty if you don’t know what you want to do with your site. The most interesting websites don’t even have an introduction, never mind any blog posts. Some of the most interesting web sites I enjoy just are.

Add plenty of semantic HTML.

Be kind to your eyes, your visitors will appreciate a nice theme.

Maybe you’ll blog, maybe you won’t.
Maybe you’ll have users, maybe you won’t.
Maybe you’ll give up that cool domain.
Maybe you’ll sell that little project and hate what the buyers do with it.

Whatever you do, don’t congratulate yourself too much, or berate yourself either. Your code is half spaghetti; so is everybody else’s.

Enjoy your <body>. Style it every way you can. Don’t be afraid of CSS, or what other people think of it. It’s the greatest design tool you’ll ever learn.

Animate, even if you only try it out in your local IDE or CodePen.

 Read the documentation, even if you don’t follow it.

Do not read React dev rel articles; they will only make you feel confused.

Get to know the web platform; HTML, CSS and JS are there for good.

Be nice to your community; they are your hyperlinks that keep the web interconnected and the people who will give the web a future.

Understand that frameworks come and go, but for a precious few you should donate to the maintainers.

Work hard to bridge the gaps in accessibility and responsiveness, because the older you get, the more you need the accommodations you didn’t need when you were young.

Host on Netlify once, but leave before it makes you static.

Host on Ãœberspace once, but leave before it makes you dynamic.

Contribute.

Accept certain inalienable truths: connection speeds will rise, techbros will grift, you too will get old— and when you do, you’ll fantasize that when you were young websites were light-weight, tech founders were noble and fonts used to be bigger.

Respect the W3C.

Ask for help and people will support you.

Maybe you have a patreon, maybe you have venture capital funding; but you never know when either one might run out.

Don’t mess too much with your tabbing order, or by the time you’ve got arthritis, using a keyboard will be useless.
Be careful whose advice you buy, but be patient with those who supply it.

The old web is a form of nostalgia. Rebuilding it needs to be more than fishing the past from the disposal, painting over the inaccessible parts and recycling it for more than it’s worth.

But trust me on the websites.


(It's funny comparing this to another article I ran into today: Why I'm Over GraphQL. I've never used it but it always seemed like a weirdly over (or maybe under-) engineered idea...

Friday, July 12, 2024

free airline wifi! sort of

https://robertheaton.com/pyskywifi/ - using an account info screen as a low-bandwidth but free TCP/IP-ish gateway.

Somehow this reminds me of how "Pickle Rick" in Rick+Morty bootstraps himself w/ sewer dweller pieces and misc. junk into a Barbie sized Terminator warrior...
 

Wednesday, July 10, 2024

state of js

https://2023.stateofjs.com/ -
the gender disparity in the respondent demographics is a little disheartening
the footprint of JS/ECMAscript a dev might choose to use (and should be able to recognize) is growing
I do love this kind of graph, and double axis of "I have used" and "I like it"

 


note to self - figma replacement?

 Note to self, at some point I should check out Penpot - looks like an interesting replacement for Figma.

(To be honest, I think it's a little bizarre that bare Figma starts you with like, just the rawest of shapes, and not much that looks like an actual UI until you start importing a lot of library things.)

Monday, July 8, 2024

urchin

 I kind of like how the semi-ubiquitous UTM code for putting analytics trackers in URL comes from the delightfully named, now defunct, yet perpetually memorialized company "Urchin" - here is a page on their history.

Also I like how they "cleaned up" their charming logo to make it look more professional...



Tuesday, July 2, 2024

KISS

I appreciate Chris Ferdinandi's "Go Make Things". He's a kindred soul to me shaking my head about how needlessly complex web development has gotten. (Maybe I should also take his lead on web components...)

But I really appreciated Evergreen tech is an asset (and dependencies are a liability).
For so many apps and sites, there just isn't that much the front end needs to do that core browser tech doesn't handily provide...

Maybe I should lean on the framing of "evergreen". It almost seems like a contradiction for "tech", but the fact is there are conservative low-turnover parts of tech and edge-y high-turnover parts prone to flavor of the month, and the latter doesn't have as many benefits as many in the industry seem to assume. Someone once said, the Internet just has one big trick, getting information onto and off of someone else's server, and PHP and browser-native tech does that very well, and even in attractive ways if you know how to work it.

Monday, July 1, 2024

1, 2, 3, 4 I declare cyberwar

 I need to reconsider how I'm getting my news headlines because I hadn't heard about the major auto finance industry cyberattack making many dealers fallback to old paper based systems.

Hello from the Middleman Economy quotes Cory Doctorow:

"This is the American story of the past four decades: accumulate tech debt, merge to monopoly, exponentially compound your tech debt by combining barely functional IT systems. Every corporate behemoth is locked in a race between the eventual discovery of its irreparable structural defects and its ability to become so enmeshed in our lives that we have to assume the costs of fixing those defects."
Actually it's probably better just to read that Doctorw piece

 

Thursday, June 27, 2024

humans and robots, working toget

 Interview with the CEO/President of CodaMetrix (my new company)

As a kid, thinking of the computer-y future (and literally wondering when Bill Gates was going to make a program that wrote other programs) I kept up what was mostly a romantic, sci-fi driven hope that the best results were going to be from humans cooperating with computers, rather than either acting alone.

In a lot of ways that's where we are at now. Anecdotally, a lot of programmers are finding ChatGPT and its ilk enormously helpful as a "second pair of eyes" and as a well read but distinctly junior level paired-programmer. Similarly, I'm happy to have a role here on UX/UI at CodaMetrix, enabling pulling humans back in the loop either for specific medical coding issues and for providing informed guidance and oversight on the overall process.


 

Wednesday, June 19, 2024

AI-aiiiiiii

 I Will Fucking Piledrive You If You Mention AI Again - really very thoughtful piece:

The crux of my raging hatred is not that I *hate* LLMs or the generative AI craze. I had my fun with Copilot before I decided that it was making me stupider - it's impressive, but not actually *suitable* for anything more than churning out boilerplate. Nothing wrong with that, but it did not end up being the crazy productivity booster that I thought it would be, because *programming is designing* and these tools aren't good enough (yet) to assist me with this seriously
The thing is, in an age where frontend programming libraries and toolkits have just EXPLODED like mushrooms and we have more "flavors of the month" than a Baskin-Robins in a timelapse, "churning out [customized!] boilerplate" is an enormously helpful thing.

Tuesday, June 4, 2024

when usability misthinks and security nightmares go hand in hand

 

Why is Microsoft so hell bent on making this security nightmare?

Like, even putting the security dangers aside, it's such a weird usability misthink (IMO; I'm sure some segment of users would appreciate it.) Like, you sort of need to embrace the ephemeral nature of day-to-day digital, and take steps to recognize what you want to preserve, and come up with a mechanism and structure that works for you to preserve it. Leaning on the computer playing "Little Big Brother" as a convenience feature is no way to live.

I think of parallel examples from a simpler age: bookmark managers. Every browser would like to be your main bookmark repository, since that increase the browsers value (and "stickiness") to you. But early on, I took the HTML page that Netscape Navigator was using internally to store your bookmarks (yes I'm old) and put that on my rented webspace. (yes I'm an old geek) Then I could use any browser at work or home and do my own conscious curation of what bookmarks were worth keeping.

(As an old geek aside: I am appalled at the universality of linkrot. A Good URL can and should live forever, us old school geeks thought, and I try to live up to that with my personal sites - but this seems to be an increasingly rare approach, and maybe one in fifteen links I have on my old 90s bookmarks page still works)

Similarly, a lot of product lines try to lure users with being able to pick up on one device where another one leaves off - like handing off from a phone's browser to the laptop or vice versa. I'm not a purist against cross-device sharing - I rely on Apple's shared clipboard fairly often - but making a "seamless" handoff seems like a fool's errand to me, and as likely to startle the user as to be helpful - they are different devices with different use modes, and when the need to transfer does occur.... I mean that's what URLs have always been for.

This isn't a black and white issue. There are some kind of "ease of use" features I depend on - like I don't usually need my browser to record my bookmarks, but I DO lean on autocomplete for website URLs pretty heavily, and if i switch to a completely new machine it's a pain in the butt for a few days. But recording all my activity via screengrabs (and recording lots of stuff as plain text?) What a disastrous mixup of "can" and "should", one of the most idiotic paths in the current AI arms race.

css gives html new options for whitespace

Back in the day, one of the hardest things to get used to with HTML was how it treated white space; any linebreak in the source code wouldn't show up in the final page, and in fact its only concept of white space was "none" "a space" or "some linebreak caused by a <br> or <p> tag"

Different content systems aspiring for some flavor of WYSIWYG had to decide how treat carriage returns - the simplest, like what my homebrew CMS for my blog does, is replace "\n" with "<br>\n". More typographically elegant systems would use <p> tags - BUT - there was always some xhtml-days guilt about having to wrap paragraphs in "<p></p>", and then ambiguity about when you wanted a single line break vs a full on paragraph break.

(Also there was always the <pre></pre> tag for preserving ALL line breaks and other white space- but this was like the opposite of responsive design)

But these days CSS offers another good option:

white-space: pre-wrap;

This seems to do a great job of preserving both carriage returns as they are in the text, as well as preserving collections of spaces (where you used to have to use convert &nbsp; to get the same effect). You can use the mere "pre" setting to get back to full <pre>-tag like behavior without having to use non-semantic" tags

I probably can't retrofit my blog with this... too much of my old content was too free with the whitespace in general, but it's good to know about for future projects.

Wednesday, May 29, 2024

o'reilly on building with LLMs

Good article on building with LLMs. Ironically I think ChatGPT or similar is going to be a help for some people unfamiliar with the terms of art used in the article - ("n-shot prompting", "Retrieval-Augmented Generation (RAG") etc.

Heh, I remember when O'Reilly was the first line of defense for coding (I especially loved their "Cookbook" and "Phrasebook" formats.) It shifted to sites like experts-exchange, and then Google + Stackoverflow, and now ChatGPT.


Monday, May 27, 2024

backlog review...

 AI for Web Devs - In this blog post, we start bootstrapping a web development project using Qwik and get things ready to incorporate AI tooling from OpenAI.

Nice intro to WebComponents - I do love the advent calendar format...

https://tiiny.host/web-hosting-free-sites/ or https://glitch.com/ for static hosting of HTML?

WildAgile: just enough process

 It's probably meant half tongue-in-cheek but WildAgile is a minimalist approach to scrum, one that attempts to somewhat codify (or possibly "legitimize") the process many companies kind of land on - a pragmatic (and sprintless) approach.

Saturday, May 25, 2024

on being dense

Smart article on UI Density - I'm a sucker for anything that cites Edward Tufte. 

Its summary quote is:

UI density is the value a user gets from the interface divided by the time and space the interface occupies.

I think that's good at advancing the art, but it might be falling into the trap of only considering things that can be readily quantified. A UI will live or die based on the mental headspace it takes to understand it. A compacted interface can be off-putting because it requires to much external knowledge to grok it, and so just appears overwhelming.

lifehacks to stay afloat

 I've been floundering with email for a few weeks now.


This morning I came up with an idea to try and gate things a little better: no tumblr (my favorite way of keeping up with the memes) til I'm at just about Inbox Zero. We'll see how it goes.


But one of the things that trip me up are these newsletters - Frontend Focus, Javacript Weekly , ui.dev's bytes. Like on the one hand I'm grateful for these, 5 or 6 years ago I was really feeling out of the loop where frontend tech was heading - React sort of crept on to me - and now I feel much better informed.
But I still am disheartened, and a bit suspicious of the extreme complexity flavor of the month stuff. I think this video puts it kind of well: 

Tuesday, May 21, 2024

just trust us (i.e. our Bot)

 
Google is pivoting to REALLY leaning into preferring AI summaries of information rather than traditional web links and snippets. This article is a workaround that (at least for now) makes it easier to stick to web results.

But this trend so infuriating! Google made its mark with a brilliant "BackRub" algorithm: banking on the idea that a source is more useful and trustworthy based on how many OTHER sites refer to it. That's not Truth, but it's a good first order approximation.

This throws that out the window. They are putting all their eggs in a basket of how "people just want a simple answer" (As Nolan Bushnell puts it, "A simple answer that is clear and precise will always have more power in the world than a complex one that is true") and so replacing its history of "trust us, we'll show you who you can trust!" to a simplistic "just trust us (i.e., our Bot)"

And sure, knowing whom to trust online has always been as much an art as a science - people have to develop their own nose (starting with their own preconceptions) using the content and (for better or worse) the design and presentation of a site. (And while not infallible, I think it shows the wisdom of Wikipedia's approach - insist on citations, and let knowledgeable parties slug it out. Of course conservatives suspect it has a slant - but progressives tend to think of Colbert's "It is a well known fact that reality has liberal bias") But the "blurry JPEG" that is AI causes information to lose its flavor, all piped through the same Siri- or Alexa- or Google-Assistant- friendly stream of words.

And when the AI is wrong - boy there are some anecdotes out there. The one about what to do about a Rattlesnake bite is a killer. Possibly literally. It's almost enough to make one hope for some huge punitive lawsuits.

There is a weird "Idiot Ouroboros" aspect to Google's pivot away from connecting people to other knowledge sources - the AI has its knowledge base from what was gleaned from the web. And now the incentives for building up a reputable parcel on the wider information landscape fades away, and eventually the whole web starts to look like those dark corners of social media where Spambots try to pitch their wares to fake user account bots, endlessly.

Saturday, May 18, 2024

draw a line anywhere on a page!

Two quick points:
They released GTP-4o. The o stands for "optimized", though based on a few random tech problems I through at it I'm thinking it stands for "oh, not as good as 4" - I think they tuned it to be fast and take more types of inputs in in a fluid way, but for my main use (programmer's lil' helper) the web version provides lesser results

Anyway, 4 had better suggestions for my problem where I wanted to draw arbitrary lines on page (in my case I'm revamping my "poll editor", and I realized it would be great if the element used to set up an individual poll entry could point to the appropriate place on the preview.)

Enter LeaderLine! To rip off that page:

I love it - if your page is dynamically reformatting you might have to call "line.position()" to reset things and there were a few cases (like when the page was distorted from a textarea being weirdly resized) where it wasn't 100% perfect, but I think it nails most usescases and meets my criteria for using a library vs writing bespoke code:
1. it pulls its weight by solving a relatively difficult problem
2. it has a reasonable simple API
3. it works with vanilla.js without a build system


Friday, May 17, 2024

BASIC and this one weird trick with line numbers

Happy Birthday BASIC - it just had its 60th birthday.

Sometimes I say Perl taught me 5 big things, after taking up C in college: maps, first class strings (vs C character arrays), duck typing, regular expressions, and not having to micromanage memory. But really, BASIC was my exposure to 3 of those things!

Famously Dijkstra said

It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.

Pretty rough talk! Though he may have been talking about a particularly primitive flavor of it.

Line numbers are probably the thing most reviled - certainly they don't encourage modular thinking the way named subroutines do, but as my friend Jeremy "SpindleyQ" Penner pointed out, they are at least a good way to getting new (and young!) programmers to understand the step-by-step thinking that is critical to writing programs. (I remember seeing a listing of Amiga BASIC and was blown away that it had no line numbers! Also it reminds me that 8-bit computers had weird flavors of "full screen editing" - line numbers were a way of managing the program listing structure in an age before text editors were always available.)

One trick you heard while learning BASIC in the 80s - number by 10s, so that you can easily insert code before or after a specific lines. Weirdly this came in handy when I was creating my 50th Birthday comic book - it started as a bunch of standalone thoughts, which I turned into comic panels (and later grouped into 4 sections). I had a rough idea of the ordering, and so I started each file name with a 3 digit multiple of ten ("010-BEGINS-TO-BAND.png", "020-FIXED-MINDSET.png") etc, so that the filesystem could easily show me the ordered list.  (I'm not sure if writing in all caps was another nod the old 8-bit computer days.)

Wednesday, May 15, 2024

uh-oh is chatgpt slipping

 ChatGPT has proven itself a valuable programming partner but with the new version when I asked it to make a React component and it started:

import React, { useState } from 'recat'; import styled from 'styled-components';

"recat"? That does not bode well...

Wednesday, May 1, 2024

remember to not require authentication for OPTIONS requests on your authenticated endpoints!

Recently I was on a project where we started using "bearer tokens" (like bearer bonds, bearer tokens means if you have possession of it, you're trusted)

But we were getting CORS errors - but they read like cross-origin issues?And the request with the bearer token would go ahead and work when exported as cUrl commands....

Cut to the chase, the browser was sending an OPTIONS request to sniff around to the "Access-Control-Allow-Origin" header - but accidentally that was set to require the token - but that's not the way OPTIONS are supposed to work, so the browser doesn't include it. Anyway, so the 401 rejection of the OPTIONS request meant that the browser wouldn't try the actual GET. 

A little frustrating. It's like "c'mon browser - live a little, send the request, let the server figure out if it doesn't want to talk to you" -- sort of like giving a pep talk when you're playing wingman for your single friend at a bar.

coors = mediocre beer, CORS = annoying security gotchas

chatgpt as lossy compression

My favorite sci-fi author Ted Chiang wrote ChatGPT is a blurry jpeg of the web:
Imagine what it would look like if ChatGPT were a lossless algorithm. If that were the case, it would always answer questions by providing a verbatim quote from a relevant Web page. We would probably regard the software as only a slight improvement over a conventional search engine, and be less impressed by it. The fact that ChatGPT rephrases material from the Web instead of quoting it word for word makes it seem like a student expressing ideas in her own words, rather than simply regurgitating what she's read; it creates the illusion that ChatGPT understands the material. In human students, rote memorization isn't an indicator of genuine learning, so ChatGPT's inability to produce exact quotes from Web pages is precisely what makes us think that it has learned something. When we're dealing with sequences of words, lossy compression looks smarter than lossless compression.
Admittedly this was written last year but I think he underestimates the usefulness of ChatGPT in applying knowledge to a particular case at hand:
This analogy makes even more sense when we remember that a common technique used by lossy compression algorithms is interpolation--that is, estimating what's missing by looking at what's on either side of the gap. When an image program is displaying a photo and has to reconstruct a pixel that was lost during the compression process, it looks at the nearby pixels and calculates the average. This is what ChatGPT does when it's prompted to describe, say, losing a sock in the dryer using the style of the Declaration of Independence: it is taking two points in "lexical space" and generating the text that would occupy the location between them. ("When in the Course of human events, it becomes necessary for one to separate his garments from their mates, in order to maintain the cleanliness and order thereof. . . .") ChatGPT is so good at this form of interpolation that people find it entertaining: they've discovered a "blur" tool for paragraphs instead of photos, and are having a blast playing with it.
I'm willing to grant that asking ChatGPT to apply its embedded gleaned knowledge to a particular problem is basically that kind of of interpolation, but in practice it is far more useful than making entertaining mashups. In my case, especially for technical tasks - as I previously quoted David Winer:
ChatGPT is like having a programming partner you can try ideas out on, or ask for alternative approaches, and they're always there, and not too busy to help out. They know everything you don't know and need to know, and rarely hallucinate (you have to check the work, same as with a human btw). It's remarkable how much it is like having an ideal human programming partner. It's the kind of helper I aspire to be.

Interesting world.

Monday, April 29, 2024

don't be afraid to duplicate

 "I generally follow the rule. Duplicate code until you have at least three examples. Then you can generalise.

So many times if you dedupe code which appears in two places that at first looks like the same code you later realise it is different behaviour and make the "general" function much more complex."

--Clair Blackshaw

Interesting to pair that with my general sense of the kneejerk tendency of some folk to look for a library rather than write a little bespoke code. A good library solves MANY scenarios at once, but since the whole point is kind of NOT understanding the solution as deeply (or taking a lot of time to learn new language of configuration) if it does go wrong you're likely to have less clear sight into how to dig yourself out...

Monday, April 22, 2024

the chicken and the pig

Once upon a time I had official scrum master training with Ken Schwaber.

Besides the general scrum knowledge I acquired some details have stuck with me, like the bill-shaped duck call he would use to get peoples' attention. (He said people were less likely to steal it.)
 

Also this introductory line which seems oddly belligerent, but reflects the Scrum folks' faith that they had the better idea (and indeed they did make the new standard, even if few places practice the pure version) is this:

You suck... and that makes me sad.

Also I remember hearing this story, not quite sure if this exactly the version but:

A man walks into Fat Burger and orders a Double Fatburger, fries, and a drink.

Man only has $3.15 but the total comes to $7.15. The manager tells him he’s going to remove something from his order.  But the man insisted to have it all.

The manager doesn’t want to lose the customer so he walks out and finds a dead squirrel off the street.  He makes the burger by cooking the squirrel and putting it on a bun and hands it over to the man.

So if you draw the analogy of the story with the scenario above, it clearly seems that team compromises the quality just to deliver the product on time.

In order to achieve the unrealistic deadlines, first thing teams do is to discard the automated tests and stops refactoring the code. Soon after their code resembles coding they did in high school and they are making a huge mess.

But mostly I remember the metaphor of the chicken and the pig:

 

(Here's Vizdos' page on the origin of the cartoon)

The metaphor was that developer are the "pigs" whose bacon is on the line, so to speak, while the other people involved were "chickens" without skin in the game, and so should be quiet observers during the daily standup, for instance.

OK, for one thing, that is a WEIRD metaphor. Way back when I sketched out a different final panel:

(Ken Schwaber was amused by the panel and asked to keep it.)

But that really tied into my problem with the metaphor; Product Owners and other non-devs DO have skin in the game, their jobs and reputations are at stake as well, and in some ways it's even tougher for them because they are dependent on devs and can't just "work harder" to get better results. (also true Scrum aims to guarantee predictability over time, and has relatively little to say about efficiency and timeliness.  As my team lead Steve Katz put it: "the process isn't about not getting fired")

I guess they've moved on from the chicken/pig metaphor anyway - it was a little too joke-y, and I think other people shared my view that non-dev stakeholders are still critical to the success of a project.


Friday, April 19, 2024

humane/her

Marques Brownlee reviews the Humane AI Pin... "the worst product I've ever reviewed... for now"


The form factor reminds me of this chef's kiss detail from the movie "Her" - Samantha's form factor is basically that of a foldable smartphone, but Twombly uses a safety pin to give her a boost in his pocket so she can see the world:

 (Also Brownlee had the clapback of the year to someone arguing he shouldn't have been so negative about a new striving-to-be-innovative product - "We disagree on what my job is")

 

 

on leadership

the biggest threat facing your team, whether you're a game developer or a tech founder or a CEO, is not what you think

Brilliant article on leadership. It's long and gets into the weeds of the games industry, but there is a lot that is true for the whole corporate world.

It touches on one point that is much on my mind: so much of our corporate leadership is "make number go up" (immediately! but then also forever.) Corporations generally have a legal obligation to "increase shareholder value", and in general that's on a per quarter basis. Sustainability and long term viability are afterthoughts at best.

The article points out there's parallels in that and some USA policy decisions in Vietnam:
But when the McNamara discipline is applied too literally, the first step is to measure whatever can be easily measured. The second step is to disregard that which can't easily be measured or given a quantitative value. The third step is to presume that what can't be measured easily really isn't important. The fo[u]rth step is to say that what can't be easily measured really doesn't exist. This is suicide.
But then when you combine that with leaders who view themselves as capable of finessed big picture and aesthetic decisions as, say, Steve Jobs... well, they aren't always looking to the people reporting to them as potential Jony Ives - they want to go on their own guts.

So an organization has to thread the needle between "it only counts if it can be quantified" and "it only counts if it has good 'gut feel' to topmost leadership". I think you do that by building and then trusting the expertise of the people in the middle.

Tuesday, April 16, 2024

from "Headcrash"

"I mean." Uberman cleared his throat, adjusted his necktie, and began delivering his morning whine, which is clearly what he'd been intending to do all along. "This is, what? The third network outage this year?"

I stopped. "We're having some problems porting your database to our server, sir." I edged one step closer to the exit.

"I mean," Uberman scowled, "if I can't depend on your network, I'm screwed. Just totally screwed, you know?"

Then how come you're not smiling? is what I thought, but "We'll have it back up as soon as possible," is what I said.

"I mean," Uberman whacked his PC with his newspaper again, "we never had problems like this before MDE acquired us. Dammit, our old Applied Photonics network never crashed! Not once!"

"So I've heard." And heard, and heard, and heard! And if you gave me just sixteen users in a one-floor office, I could make this network look pretty good, too.

Bruce Bethke, "Headcrash"
"Headcrash" is kind of a no-account cyberpunk-y book from the mid-90s... the technobabble is pretty clumsy, but for some reason this passage has stuck with me for 20 years so I thought I'd post it - from time to time, its reminder that little toy systems can get away with things that projects you want to scale can't is useful.

Thursday, April 4, 2024

ux ideas!

 Some UX humor ideation from Sorn Iverson ...
Some of my favorites:





easy drag-and-drop sorting/reordering with no build system vanilla js using SortableJS

I've already linked to a defense of making webapps without a build system - it really is great for long term sustainability and updates, and PHP + Vanilla JS are actually really powerful tools these days. You can even build dynamic page parts in a declarative style, using JSX looking string templates: 

const list = document.getElementById("myList");
list.innerHTML = items.map((item)=>`<li>${item}</li>`).join("");

It's all right there in the browser these days!

One thing I didn't know how to do is add drag-and-drop reordering - at least not in a way that was mobile-friendly. (The browser's Drag and Drop API is one place where the usual abstraction between computers with mice or touchpads and mobile devices with touch screen breaks down.)

I knew of SortableJS but the README didn't make it clear that it works without a build system. ChatGPT straightened me out - using SortableJS is just a <script> tag away:

<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.14.0/Sortable.min.js"></script>

(Hmm, there's no authentication checksum so you might want to grab the file and move it locally - I mean in general eliminating external dependencies is a good practice, tying into that long term sustainability: linkrot is real and ubiquitous, even well meaning CDNs broke projects depending on them as stuff switched from http to https...)

But back to sortable! Here's about the simplest example:
<script src="Sortable.min.js"></script>
<ol id="items-list">
    <!-- List items will be dynamically inserted here -->
</ol>
<script>
document.addEventListener('DOMContentLoaded', () => {
    const items = ["Apple", "Banana", "Cherry", "Date"];

    const listElement = document.getElementById('items-list');
    listElement.innerHTML = items.map(item => `<li>${item}</li>`).join('');

    new Sortable(document.getElementById('items-list'), {
        animation: 150, // Animation speed (milliseconds)
        onEnd: function (evt) {
            items.splice(evt.newIndex, 0, items.splice(evt.oldIndex, 1)[0]);
        }
    });
});
</script>


You can see it in action - everything is right there in the source.

So one slightly wonky aspect is that this kind of reverses the usual flow of declarative programming: Sortable update the DOM and then relies on the onEnd to make your internal state match. Still, a small price to pay for a mobile-friendly reordering solution; so much better than providing little /\ and \/ buttons!

You can go a little further and add some grabbable handles - here's how to make those three lines:
<span class="drag-handle">&#x2630;</span>

Add the reference to the Sortable options object:
handle: ".drag-handle",

and then a little CSS:
  ul {
   list-style-type: none;
   padding-left: 0;
 }
 .drag-handle {
    cursor: grab; /* Changes the cursor to indicate movability */
    padding-right: 10px; /* Spacing between the handle and the text */
    user-select: none; /* Prevents text selection */
  }

  /* Style the drag handle on hover and active states for better feedback */
  .drag-handle:hover, .drag-handle:active {
    cursor: grabbing;
  }


Here's a working example of that.

Finally, if you DO rerender the list, you should probably hold onto the returned Sortable object and call .destroy() and then reapply. That's obviously more tied into whatever app you're actually making, but here is a basic destroy/rerender example as well, which is a bit closer to my usecase.

Wednesday, April 3, 2024

robohorn

As a kid I wondered if you could make a robot trumpet player. The answer is now yes. I wonder how the cyber-embouchure works... (you can google up a robot sax player as well...)

Related Diesel Sweeties comic 10:



dangerous times

A while back I posted I’m harvesting credit card numbers and passwords from your site. Here’s how. a fake (or was it) description of how the overwhelming amount of npm-ish dependencies can make your webapp vulnerable, if a bad actor makes a helpful looking tiny utility (that the framework you like uses, even if you don't see it as worthwhile) and covers their tracks well. 

What we know about the xz Utils backdoor that almost infected the world is along the same lines, except i can't preach the gospel of "use fewer dependencies!"

None of this is new - the seminal Reflections on Trusting Trust - where a trojan could be snuck into a C compiler, covering its tracks all along the way - is 40 years old. But it's scary.

Related: You Are All On The Hobbyists Maintainers' Turf Now. The business world has absolutely embraced the Open Source paradigm - or at least decided to take freely of its fruit, and so the risk of poisoned flowers is there, even as more and more we depend on the good will "doing it for the reputation and to scratch my own itch" work of fewer and fewer - or as XKCD put it:




Monday, April 1, 2024

ObHack: see if I've hit quota

 I know I've mentioned Usenet's alt.hackers and "ObHacks" before... the latest is this:

My main VPS is pretty old (I'm migrating to a new one) and it doesn't do a good job of letting me how close to my disk quota I am - but when I start having problems, the clearest telltale is that if I try writing to a file from terminal, the file is made but is zero bytes.

But on that same server I run my personal start page, so many times during the day I'm going back to that site. So now the script that generates that page tries does this:

// QUOTA PROBLEM CHECK
// Get the current Unix timestamp
$timestamp = time();
// Write it to a file named "timetest.txt"
file_put_contents("timetest.txt", $timestamp);
// Initialize $bodyclass with an empty value
$bodyclass = "";
// Open the file and read the timestamp
$readTimestamp = file_get_contents("timetest.txt");

// Check if we can open the file, if it's not empty, and if the contents match
if ($readTimestamp === FALSE
        || $readTimestamp == ""
        || $readTimestamp != $timestamp) {
    $bodyclass = "alert";
}

and I made the body.alert CSS to be bright red, so I'll see that something is up.


Heh, that piece of PHP reminds me of a thought I had recently; in general I don't adore TypeScript because while I like having JSON arguments described, there are better ways to do that, I find the syntax makes code a bit harder to read, and also there's more of a chance of a false sense of security, since you don't REALLY know what types are going to come back from a given endpoint at runtime.

My observation with that is that 90% of the typing issues I *do* have in JS would go away if "+" always meant addition and not string concatenation. Which is how PHP does it. But then I realized that PHP only gets away with supporting both $string.$concatenation and $object.key lookup syntax because it prefixes its variables with "$", otherwise you'd have to do object["key"] only since object.key would look like a lookup reference.

Monday, March 25, 2024

baby mock json endpoint server and cloning endpoints

My boss thought it strange that we didn't already have a "mock server" so that we could keep doing UI work in case the endpoints went down.

He suggested using json-server but that wasn't made to emulate a rich set of endpoints, just one level deep, either GETing all the entries or just one at a time by id. Luckily that kind of server is the easy part of the assignment.

The first part was to make a file "urls.txt", with just the relevant part of the endpoint...

then this script load-db.js hits each of those entries and writes the content to a file in mocks/

const express = require("express");
const fs = require("fs");
const path = require("path");
const app = express();

// Ensure the mocks directory exists
const mocksDir = path.join(__dirname, "mocks");
if (!fs.existsSync(mocksDir)) {
fs.mkdirSync(mocksDir);
}

// Read the command line argument for the prefix
const prefix = process.argv[2];

// Read the URLs from urls.txt
const urlsFilePath = path.join(__dirname, "urls.txt");
const urls = fs.readFileSync(urlsFilePath, "utf8").split("\n");

// Function to make a safe filename from a URL path and append .json
const makeSafeFilename = (urlPath) => encodeURIComponent(urlPath.replace(/^\//, "").replace(/\//g, "_")) + ".json";

// Fetch content and save it as JSON
urls.forEach(async (urlPath) => {
if (!urlPath.trim()) return; // Skip empty lines
const content = await fetch(`${prefix}${urlPath}`).then((res) => res.json());
const safeFilename = makeSafeFilename(urlPath);
fs.writeFileSync(path.join(mocksDir, safeFilename), JSON.stringify(content, null, 2));
console.log(`Saved content from ${urlPath} to ${safeFilename}`);
});

Then the server.js just looks like this:

const express = require("express");
const fs = require("fs");
const path = require("path");
const cors = require("cors");
const app = express();

app.use(cors());

const mocksDir = path.join(__dirname, "mocks");

app.get("/", (req, res) => {
fs.readdir(mocksDir, (err, files) => {
if (err) {
console.error(err);
return res.status(500).send("Server error");
}

const links = files
.filter((file) => file.endsWith(".geojson") || file.endsWith(".json"))
.map((file) => {
const decodedFilename = file.replace(/\..+$/, "").replace(/_/g, "/");
const encodedPath = decodedFilename
.split("/")
.map((part) => encodeURIComponent(part))
.join("/");
return `<li><a href="/${encodedPath}">${file}</a></li>`;
})
.join("");

res.send(`<ul>${links}</ul>`);
});
});

app.get("*", (req, res) => {
const safeFilename = encodeURIComponent(req.path.replace(/^\//, "").replace(/\//g, "_"));
const filePath = path.join(mocksDir, safeFilename);

if (fs.existsSync(`${filePath}.geojson`) || fs.existsSync(`${filePath}.json`)) {
res.type("application/json");
res.sendFile(fs.existsSync(`${filePath}.geojson`) ? `${filePath}.geojson` : `${filePath}.json`);
console.log(req.path);
} else {
res.status(404).send("Not Found");
console.error(`404 ${req.path}`);
}
});

// Use environment variable for port or a default value
const port = process.env.PORT || 3000;

app.listen(port, () => {
console.log(`Mock server listening at http://localhost:${port}`);
});




package.json is

{
"name": "mock-server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.3",
"node-fetch": "^3.3.2"
}
}



(Sigh, I suppose if I was feeling ambitious I should make my a little project out of this and put it on github, but I'm sure someone has, and better.)

UPDATE: this version now lists the endpoint/files it knows about if you go to the root, and listens to process.env.PORT for instructions on port