Sunday, July 2, 2017

Blueprint: awesome React UI library

Blueprint is a fabulous library, built for React. It has everything that I know that I've wanted for building a UI, and it has lots of stuff that I didn't realize that I wanted--but I do now!

And did I say that it's built for React? Oh, yeah.

Things like Navbars, and Menus and Toasts. Never heard of a Toast? Check this out.

You can play a bit on this here CodeSandbox project. Or click below.



Monday, April 3, 2017

Requirements for a minimal viable TODO

# Minimal Viable TODO

The TODO list is an editable document in MarkDown.

1. The system uses a CodeMirror instance. Each line is an item.

2. It persists data to local storage AND to the server's .data directory.

3. It uses Markdown as a representation

4. Markdown heading lines (starting with one or more #) are section markers. So # Next is the next group. # Projects is the project group. Projects start with ##. Subprojects with ###

5. When I leave a line the system turns the line from Markdown to HTML Entering a line reverses the process.

7. When I leave a line, any line with a # or @ annotation is moved to the matching section. Top or bottom of section to be decided later.

8. The annotation #done overrides all other # annotations, and moves the item to the end of the relevant section. #done lines are rendered with a .task_done style, which is a strikethrough.

9. Ctrl-up/Down are used to move lines up and down

10. Ctrl-K selects the current word (if nothing is selected) or uses the current selection, and wraps it in [] and pastes the current clipboard contents wrapped in (). This is the markdown link syntax.

11. Add a RESTFUL API that will let me read the list or push it to a remote site.

12. Push the system to `glitch` which will give me a project that I can work on, online.

# Ideas for next phase

Use the CodeMirror `marktext` API and code folding API to hide/show regions of the document.

By default, regions are unfolded when the cursor enters them; are folded when the cursor moves out.

Convert atomic edits to Redux Actions.

VS Code multi-process debugging

VS Code is cool!
I set up a project here on Github to demonstrate debugging two processes— a parent process and a child.
The parent launch configuration looks like this:
 {
            "type": "node",
            "request": "launch",
            "name": "Parent",
            "program": "${workspaceRoot}/parent.js",
            "args": [],
            "cwd": "${workspaceRoot}"
            // ,"port": 5858
            ,"protocol": "auto"

        }
Note that the port:5858 line is commented out. If it’s included, everything works, but later, when we launch both parent and child together, there are problems.
Parent code:
console.log("Parent running")
const cp = require('child_process');

const child = cp.fork(`${__dirname}/child.js`,{
 //force the debug port to the one in the launch config
 execArgv: ["--debug=5859"]
 ,silent: true
//  ,stdio: 'ipc'
}
);

//Child data does not go to console with VS Code
//So do this.
child.stdout.on("data", (m) => console.log(m.toString()));

const sender = () => {
    child.send({ hello: 'world' });
}

child.on('message', (m) => {
  console.log('PARENT got message:', m);
  sender()
});
The parent has to pass debug=5859 to the child, and the Child launch configuration has to have that port set:

  {
        "name": "Child",
        "type": "node",
        "request": "attach",
        "port": 5859,
        "address": "localhost",
        "restart": false,
        "sourceMaps": false,
        "outFiles": [],
        "localRoot": "${workspaceRoot}",
        "remoteRoot": null,
        "protocol": "legacy"
    }
The child looks like this:
console.log("Child started\nu");
console.log(process.argv)

sender = () => {
    process.send({ foo: 'bar' });
}

process.on('message', (m) => {
  console.log('CHILD got message:', m);
  sender()

});
//start by sending a message
sender();
The README.md file explains how to use the project

VS Code Child Process Debug

This is a VS code project that lets you open a debugger on a parent process and a child at the same time.
It shows several ways to connect:
  1. Connecting to one process at a time in debugger
  2. Connecting to both together in debugger
  3. Connecting to a parent started in a console

Connecting to one process at a time in debugger

  1. Switch to the debug view
  2. Set a breakpoint in parent.js in the line that reads:
    console.log('PARENT got message:', m);
  3. Set a breakpoint in child.js in the line that reads:
    console.log('CHILD got message:', m);
  4. Select Program as the launch configuration
  5. Start the debugger by clicking on the green arrow key or F5. A debug widget

    will appear and the debugger will stop in parent.js and display the file in an editor pane. You’ll get output in the console that looks like this:
Debugging with inspector protocol because Node v6.10.0 was detected.
node --inspect=SOME PORT --debug-brk parent.js 
Debugger listening on port 5858.
Warning: This is an experimental feature and could change at any time.
Debugger attached.
Parent running
Child started
[ '/home/mwolf/tools/node-v6.10.0-linux-x64/bin/node',
  '/home/mwolf/tools/junk/child.js' ]
*******************
Like this one
  1. Choose Child in the launch configuration, and press the green arrow key to attach to the child.
Note: in this case F5 will not attach to the child, but cause the already running parent to continue and stop at the breakpoint again.
  1. The debug widget will now have a a drop-down list and let you switch between the parent (launch) process or to the child. You can also disconnect from one or the other
  2. If you press the green arrow in the debugger widget, or F5, the program will run to the next breakpoint—which by design is in the other process, display the code and stop there. Pressing F5 again moves it back.
  3. If you have two tab sets open and move one file to each set, then you’ll see it toggle back and forth as you hit successive breakpoints.

Connecting to both together

  1. Select the Program/Child launch configuration.
  2. Press F5 of click on the green arrow.
  3. The debugger will stop in parent.js and both

Disconnecting and reconnecting

If you disconnect from the parent, then the child disconnects as well. But if you disconnect from the child, you can reconnect using the child launch configuration

Sunday, March 19, 2017

Toward an awesome development workflow

I've spent a lot of time over the past few years designing and building tools that approached my vision of an ideal application development workflow. Web tools were the future: CSSHTMLJavascript, NodeJs for the back end. Plus others. I learned a lot. Then I decided that what I was doing wasn't working. So I took a break.

After a bit, I started reading about new high-productiviy technologies that had appeared and begun to mature since I'd started my project. The more I learned, the more impressed I became, and the more excited I got about building something even better than what I had originally envisioned.

I decided that I needed to spend time mastering some of the core technologies for web app building. I knew the basics of JS, but ES6 had come along. And JSX. And Typescript and Babel, the next generation compiler. All these tools added up to something better than what I'd been using (Coffee Script).

Then I found React and Redux, which put HTML back into Javascript and solves a bunch of problems. Then CSS Modules which put CSS in Javascript and solved a bunch of problems. Then Webpack which packaged things up on the fly and made building for the web a lot simpler. And hot module reloading. And React and Redux dev tools. And then a buddy pointed me to glitch.com -- a better coding playground in the cloud than the ones I had been using. And VS Code, a better editor and working environment on the desktop (Linux, Windows, Mac) than what I'd been using (Sublime Text and Atom.) I was off and running.

And along the way, I've found people online with similar visions for application building. Some had already contributed to big pieces I've listed. Others were crafting smaller bits that helped make a workflow really flow. My job now is filling in the gaps in my education, integrating their stuff, making my contribution, and spreading the word.

I want to build the world's most awesome development environment for web applications. I'm not going to fill this blog with my discussions of what I am doing and what I've learned. Instead, I'm going to be posting on another blog that I have: Awesome Development, starting with a copy of this post. 

If you're interested, I'll see you there.

Originally published here

Tuesday, January 3, 2017

Time travelling development--for JS apps

TL;DR To how things should really work, watch this talk by Dan Abramov who created Redux, and the debugger concept.

Long version:
Make a change in your code. See it updated instantly. That's what I want because modern development is an iterative process, with fast iterations.

We've got something like that in JS playgrounds like JSFiddle, CodePen, and so on. But there's still a couple of things that are wrong. Make a change and the app runs again, from the top.  It's pretty quick, and for small bits of code, there may be almost no lag. But as your app scales, the time grows.

You can write a test driver, so that once the app loads, it tests itself, but that's another whole lot of code that you have to write. And even then, reloading takes time, and most of the changes that you make are teeny tiny ones. Even a second or two for a reload is too long.

You can do this in your Dev environment, as well as

And you don't want to test your whole app every time you make a change. Most changes are not going to break the app. They're just little tweaks. What you'd like to do is this: put the app in a certain state. Make your code change. Do some fiddling with the interface. See if it works right. If it doesn't then:

  • Revert to the earlier change
  • Rerun the interface twiddles
  • Repeat until it's perfect
  • Make this the new base, state
  • Repeat forever
And if you run into problems you'd like to go back to your base state with the ability to back up through the twiddles and debug anywhere. Now someone has pretty much done that using mainstream tools.

The key is making your code functional. Take state out of the functions. It's a variation on MVC programming. And it points out a flaw in MVC.

The usual MVC routine is this: you've got a data structure, which is your model. You've got code that takes the Model and renders a View. The view contains UI Control components. When a user manipulates the Controls, the model changes -- either by two-way binding, or by calling functions that are part of the Model, or by directly manipulating the Model data structure. But sometimes the View has its own controlling data structures. So there's a Data Model, and a View Model to pay attention to.

Instead, design code using Model, View, Controller, and Actions. The rules are:

All state is in the Model. Base data state and View state are in different parts of the one and only Model.

Models are POJOs, so they can be serialized and parsed back to their former state.

Actions are Plain Old Javascript Objects (POJOS) emitted by Controllers. 

A part of a Model is updated by calling a model updating function with an Action. There is no other way to update a Model. Model updating functions are called Reducers.

Reducers functions have the following signature: (Oldstate, action) -> newState, the signature used for functions called by Array.reduce They take the prior state as an input parameter and produce a new state. Because of their signature, reducers can be called with an array of Actions, using Array.map. So calling:
arrayOfActions.reduce(reducer, initialState)
Will return the final state, after applying all of the actions. 

Reducers don't update the Model; they replace the old state with a new state, in which the changes have been made according to the Actions. So state objects are immutable.

As a consequence:
  • We can save and restore the application state at any time
  • We can take any state, and apply a set of actions to it, giving the state after the actions
This lets us create a debugger that will do what we want it to do.

The technologies that make this easy to do are React and Redux. React is a framework for view rendering. In ordinary practice, View components can be stateless or stateful. Redux is a framework for managing states for React-based applications so that View components can be stateless.

To see how this works, watch this talk by Dan Abromov who created Redux, and the debugger concept.

Also read the docs for React and Redux, which I am in the process of doing.

Sunday, January 1, 2017

Browser synchronization, event capture

BrowserSync is an Open Source project that keeps multiple browser instances in sync.

I've downloaded it and tested it. It has some problems, but it mainly works as advertised. And it can do a bunch of thing that an awesome environment would need to do.

First: the main idea. BrowerSync captures events from each browser that's displaying data from a site that it serves, and forwards those events to other browsers looking at the same site. Even better, the BrowserSync server can proxy another server, including one serving pages by https.

Here's a review of some competing technologies by Addy Osmani, and his review of BrowserSync or browser-sync (github) and site.

I started by installing browser-sync

npm install -g browser-sync

I started by testing it with a polymer/firebase project. I cd's into the directory and ran:

$firebase serve 

That gave:

Starting Firebase development server...

Project Directory: /home/mwolf/tools/prog-with-papa
Public Directory: dist

Server listening at: http://localhost:5000


In another console, I run browser-sync in proxy mode:

browser-sync start -p  http://localhost:5000

That gives:

[BS] Proxying: http://localhost:5000
[BS] Access URLs:
------------------------------------
      Local: http://localhost:3000
   External: http://192.168.1.2:3000
------------------------------------
         UI: http://localhost:3001
UI External: http://192.168.1.2:3001
------------------------------------

And pops open a window on http://localhost:3000

I opened an incognito window and went to the same URL. Sure enough, clicking on menu selections in one made the same changes happen in the other. One of the pages had a text box. Entering text in one entered it in the other. But scrolling the form did not sync! I also tested it using my phone and the external port. Worked fine.

Next test. I proxy a site on the web.

browser-sync start -p  http://slatestarcodex.com/

Next test. I proxy a site on the web. Works fine, including navigation within the site and scrolling. So maybe the scrolling problem has something to do with Polymer?

Then I proxy the site using https. I get:

[BS] Proxying: https://slatestarcodex.com
[BS] Access URLs:
-------------------------------------
      Local: https://localhost:3000
   External: https://192.168.1.2:3000
-------------------------------------
         UI: http://localhost:3001
UI External: http://192.168.1.2:3001

Again, it works as hoped for.

Will it work for google?

browser-sync start -p  https://www.google.com

Opens a browser, but tells me that there's a security problem: the site doesn't have a correct SSL certificate. I approve it as an exception, and it works!

I try with facebook. Facebook lets me get public content, but its security protocols won't let me log in. I assume that the same thing will happen with any site withy good security.

So BrowserSync does some of the things that I want it to do. Others, like bypassing security, are probably impossible by any means.

Couple this with Chrome Plugins, and I may be able to do some of the hacking that I want to do.

At the heart of browser-sync is its ability to capture events and forward them. On the road to discovery, I found the following resources:

HTMLGoodies Advanced Javascript event handling

Ghostlab

Comparison of Ghostlab and BrowserSync

EventTarget.addEventListener at MDN, defines the basic procedure for handling events. By overriding EventTarget.prototype.addEventListener you can capture events for all targets, and do funky things with them.

An article about event capture on css-tricks.com by one of the authors of GhostLab. The article includes links to several CodePen examples for capture.


The workbench paradigm

IDEs and other power software tools suffer a tension between power and complexity. A photo editing tool has a dozen menus; each might have a dozen selections, and many of those might have submenus. If you remove all the menus and selection, you remove the tool's power. If you keep them, then finding out how to do the thing you want to do next means searching for the right command.

Some tools get you around this by letting you type a string that fuzzy-matches to the function that you are looking for. That's better, but still requires quite a bit of fiddling to get the function that you want.

Instead, consider a shop project as a governing paradigm. A skilled craftsman has a workshop full of tools and materials, but for any one task, needs only a few. Before commencing work the craftsman grabs the needed tools and materials, lays them out on the workbench in easy reach, and then sets to work. When possible, a workman prefers materials as close to finished size as possible. He'd prefer already-turned drawer pulls to blocks of raw wood he can turn into pulls.

So, consider building a GUI. The usual method is to go to a palette of components, pick one, place it, then assign properties to it. Then pick the next one, and so on. Instead, pick only the components that you'll need; choose the items in the palette that you want to be visible, and hide the rest; when you've adapted one to size, add it to the palette.

Consider building something with a bunch of icons using Polymer's iron-icons. If we were doing it with a GUI builder, we might pick iron-icon from a palette of iron elemements (there are 35 of them) place it, pull up a property sheet to set its properties, and continue.

One property is the icon image name from an iron-iconset. So we'd choose the icon images that we want. Then on to pick the next icon. If we're a little smart, then instead of picking another icon from the palette we'd duplicate the first one. But we're still left with the task of choosing another image.

Instead, we'd do better to go to a collection of pre-made iron-icons, each with a different image, and use them as our components.

The Polymer library lets us define a collection, and add iron-icon to the collection. But we can only add the raw iron-icon element's definition. And it has another element that contains a set of icon images. But it doesn't have a nice way to subset the images, or to attach a chosen image to an icon instance other than cut and paste with the text editor.