<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Richard Leddy</title>
    <description>The latest articles on DEV Community by Richard Leddy (@rleddy).</description>
    <link>https://dev.to/rleddy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F118049%2F75613959-52c8-4b48-b2ce-37957cd9aede.jpg</url>
      <title>DEV Community: Richard Leddy</title>
      <link>https://dev.to/rleddy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rleddy"/>
    <language>en</language>
    <item>
      <title>Running process from a web page</title>
      <dc:creator>Richard Leddy</dc:creator>
      <pubDate>Mon, 05 Sep 2022 23:26:21 +0000</pubDate>
      <link>https://dev.to/rleddy/running-process-from-a-web-page-a0f</link>
      <guid>https://dev.to/rleddy/running-process-from-a-web-page-a0f</guid>
      <description>&lt;p&gt;I put together a little process manager for running communicating programs.&lt;/p&gt;

&lt;p&gt;The point was to put up something simple and quickly. That was not too hard to accomplish by using Svelte for the web page, node.js, etc. for my server. And, I added a class to &lt;a href="https://www.npmjs.com/package/copious-transitions-manager"&gt;message-relay-services&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can install it and use it yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g copious-transitions-manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can get an example config file by using &lt;a href="https://www.npmjs.com/package/get-npm-assets"&gt;get-npm-assets&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get-npm-assets copious-tm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can run your program by calling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;copious-tm manager.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once it is running, you can surf to the web page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://localhost:8989/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there, you can control the processes you see in the list.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The reader is encouraged to dig around in the code, propose issues, do pull requests, etc. Indeed, the code includes Svelte, node.js, polka.js, websockets, and message-relay-services examples. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  copious-transitions-manager README.md follows:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;A simple web app for managing procs and sharing data between them&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The runtime provides those two functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A web page server with a web page for starting, stopping, updating, etc. processes.&lt;/li&gt;
&lt;li&gt;A simple messaging system that allows the processes to share messages&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The processes are managed as child processes of the copious-transitions-manager process. The child processes may send messages to the copious-transitions-manager process to store object or to fetch objects. These are simple applications of JavaScript data structures.&lt;/p&gt;

&lt;p&gt;So far, this tool is good for managing a basic configuration for those trying out processes which may also communicate with each other. The runtime is compatible with processes that use communication interfaces provided by &lt;a href="https://www.npmjs.com/package/message-relay-services"&gt;message-relay-services&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g copious-transitions-manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic Ops
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install a process from npm&lt;/li&gt;
&lt;li&gt;Remove a process&lt;/li&gt;
&lt;li&gt;Start a process&lt;/li&gt;
&lt;li&gt;Stop a process&lt;/li&gt;
&lt;li&gt;List processes&lt;/li&gt;
&lt;li&gt;Set top level config parameters....&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Run
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;copious-tm manager.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration file is a JSON object that describes how to call programs from the command line.&lt;/p&gt;

&lt;p&gt;You can get an example manager.conf file into you working directory by using &lt;a href="https://www.npmjs.com/package/get-npm-assets"&gt;get-npm-assets&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get-npm-assets copious-tm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what it looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "password" : "your password",
    "web_page_port" : 8989,
    "wss_app_port" : 8990,
    "all_procs" : {

        "test1.sh" : {
            "name" : "test1.sh",
            "run_on_start" : false,
            "attempt_reconnect" : false,
            "runner" : "bash",
            "args" : ["test/test1.sh","Print this message"]
        },
        "test2.js" : {
            "name" : "test2.js",
            "run_on_start" : false,
            "attempt_reconnect" : true,  
            "runner" : "node",
            "args": [
                "test/test2.js",
                "test/test2.conf"
            ]
        },
        "test3.js" : {
            "name" : "test3.js",
            "run_on_start" : false,
            "attempt_reconnect" : false,  
            "runner" : "node",
            "args": [
                "test/test3.js",
                "test/test3.conf"
            ]
        }

    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The top level fields are as follows&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;password&lt;/strong&gt; :: you have to type this in on the web page to make anything work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;web_page_port&lt;/strong&gt; :: this is the html server port. Surf to your computer's IP and specifiy this port, e.g.: &lt;code&gt;http://&amp;lt;my machine's ip&amp;gt;:8989&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;wss_app_port&lt;/strong&gt; :: this is for websockets. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;all_procs&lt;/strong&gt; :: this is a map of process names to process descriptions. The web page will know about these at startup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have a look at the different process descriptions. You will see that they refer to programs and their descriptions.&lt;/p&gt;

&lt;p&gt;Let's have a closer look at the fields for describing the processes. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt;  :: a name that identifies the process&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;run_on_start&lt;/strong&gt; :: whether or not to start a process as soon as the manager comes up or wait for the admin to start it from the web page&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;attempt_reconnect&lt;/strong&gt; :: if the process fails, should the manager try to restart it?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;runner&lt;/strong&gt; :: a program name that uses the parameters. This will be what runs at the outermost part of the process. It may run a script mentioned in the arguments, or it may be the name of a binary executable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;args&lt;/strong&gt; parameters that are fed to the runner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, "test3.js" has a "node" runner &lt;strong&gt;node.js&lt;/strong&gt;. The first parameter of the argments list is a javascript file in the test directory. So, "test3.js" will be available to run from the test page.&lt;/p&gt;

&lt;p&gt;Once the manager is running, you can surf to the web page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; http://&amp;lt;my machine's ip&amp;gt;:8989
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the web page you can select the process, find the "op" section and click on the "run" button.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Web Page
&lt;/h2&gt;

&lt;p&gt;You can see what the web page looks like here: &lt;a href="http://www.copious.world/transition-manager/"&gt;web page&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: nothing works on this page. The computer is not available for public operation. &lt;em&gt;For viewing purposes only&lt;/em&gt;...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the front page you can see buttons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;overview&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stdout&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ops&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clicking on these shows different panels.&lt;/p&gt;

&lt;p&gt;The first panel, &lt;strong&gt;overview&lt;/strong&gt;, shows a list box (processes will be seen there if you try it). Selecting a process makes it available for use in the &lt;strong&gt;ops&lt;/strong&gt; panel. It can be removed as well using "remove" on the front panel.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;overview&lt;/strong&gt;, you can &lt;strong&gt;add&lt;/strong&gt; a processes to the configuration file. You can run a command line using he &lt;strong&gt;exec&lt;/strong&gt; button. You can install npm modules or uninstall them. The buttons lead to dialogs to help you enter field values.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;stdout&lt;/strong&gt; panel, you can view the terminal output of a process.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;ops&lt;/strong&gt; panel, you can &lt;strong&gt;run&lt;/strong&gt;, &lt;strong&gt;stop&lt;/strong&gt;, &lt;strong&gt;restart&lt;/strong&gt;, &lt;strong&gt;update&lt;/strong&gt; or &lt;strong&gt;remove&lt;/strong&gt; a process (remove is the same as the front panel). Or, you can get access to the configuration file, &lt;strong&gt;config&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;confg&lt;/strong&gt; button will look at the arguments array and ask if that is the config file you want to edit. A rudimentary editor will be opened in a panel with the config file contents. The editor expects that you will specify the configuration in JSON. The configuration will only update with parseable JSON. The JSON will be seen on a box on the left.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TO SEE THE WHOLE PAGE&lt;/strong&gt;, you need to try out examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Look at Example Apps
&lt;/h2&gt;

&lt;p&gt;Here are two test program that can be managed by the &lt;strong&gt;copious-transitions-manager&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In the following, test2.js is the process that gets values from the communication channel, while test3.js writes values to the communication channel. You can see that test2.js calls &lt;strong&gt;messenger.get_on_path&lt;/strong&gt;, while test3.js calls &lt;strong&gt;messenger.set_on_path&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;test2.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {IPCChildClient} = require('message-relay-services')
const {load_json_file} = require('../lib/utils')
const {XXHash32} = require('xxhash32-node-cmake')

console.log("TEST 3 STARTS")

let hasher = new XXHash32(9347597)

let conf = load_json_file(process.argv[2])

if ( conf === undefined ) process.exit(0)

let messenger = new IPCChildClient(conf)


console.log("THIS IS TEST 2")

let any_old_key = [
    "this is a key for this is a test",
    "another key 94r9w487r you should know tests when you see them",
    "more keys are as much fun as testing lots of junk"
]

setInterval(async () =&amp;gt; {
    let the_time =  new Date()
    let time_report = the_time.toLocaleString()
    //
    let rand_pick = Math.trunc(Math.random()*(any_old_key.length - 1))
    let txt = any_old_key[rand_pick]
    let hash = hasher.hash(txt)
    //
    let status = await messenger.get_on_path({
        "table" : "key_value",
        "hash" : hash
    },"test2")
    //
    console.log(status)
    //
    console.log("test2: One more tick: "  + time_report)

},2000)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;test3.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
//
const {IPCChildClient} = require('message-relay-services')
const {load_json_file} = require('../lib/utils')
const {XXHash32} = require('xxhash32-node-cmake')


console.log("TEST 3 STARTS")


let hasher = new XXHash32(9347597)

let conf = load_json_file(process.argv[2])

if ( conf === undefined ) process.exit(0)

let messenger = new IPCChildClient(conf)

let any_old_key = [
    "this is a key for this is a test",
    "another key 94r9w487r key for testing tests",
    "more keys are as much fun as testing lots of tests"
]

let things_to_send = [
    "this is a test",
    "you should know tests when you see them - right?",
    "have fun testing lots of test with more tests"
]

setInterval(async () =&amp;gt; {
    //
    let the_time =  new Date()
    let time_report = the_time.toLocaleString()
    //
    let rand_pick = Math.trunc(Math.random()*(any_old_key.length - 1))
    let txt = any_old_key[rand_pick]
    let hash = hasher.hash(txt)
    //
    let status = await messenger.set_on_path({
        "table" : "key_value",
        "hash" : hash,
        "v" : things_to_send[rand_pick]
    },"test2")
    //
    console.log(status)
    //
    console.log("test3: One more tick: "  + time_report)
},2000)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  check it out
&lt;/h3&gt;

&lt;p&gt;You can run these from the web page and see the messages they print in the &lt;strong&gt;stdout&lt;/strong&gt; panel.&lt;/p&gt;

&lt;p&gt;Later, hypothetically, you could use a different class from &lt;a href="https://www.npmjs.com/package/message-relay-services"&gt;message-relay-services&lt;/a&gt; and a more sophisticated server to run the same programs. All you have to do is change the class in the require line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {IPCChildClient} = require('message-relay-services')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {MessageRelayer} = require('message-relay-services')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Givent the endpoint server the programs attach to provides an appropiate hash table functionality, the programs would not have to change more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/copious-world/copious-transitions-manager/issues"&gt;issues on github&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  dependencies
&lt;/h2&gt;

&lt;p&gt;The web page have been developed in Svelte. Find the project in the &lt;strong&gt;manager-app&lt;/strong&gt; diretory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks from &lt;a href="http://www.copious.world"&gt;copious.world&lt;/a&gt;
&lt;/h2&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
    </item>
    <item>
      <title>get-npm-assets for an easier installation</title>
      <dc:creator>Richard Leddy</dc:creator>
      <pubDate>Fri, 02 Sep 2022 00:36:48 +0000</pubDate>
      <link>https://dev.to/rleddy/get-npm-assets-for-an-easier-installation-410l</link>
      <guid>https://dev.to/rleddy/get-npm-assets-for-an-easier-installation-410l</guid>
      <description>&lt;p&gt;It's easy enough to do a post install in your npm package. But, after a while, package after package, the shell scripting gets tedious.&lt;/p&gt;

&lt;p&gt;I have some packages that install executable node.js scripts in the npm global bin directory. Then, I had to go fishing around for a template for the config file. I just wanted a command that would get the stuff for me. And, I needed the command to run for a particular script in the bin directory.&lt;/p&gt;

&lt;p&gt;Maybe it's out there. But, it seemed easy enough to make and pass on. So, today, I made &lt;a href="https://www.npmjs.com/package/get-npm-assets"&gt;get-npm-assets&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can read the Read.me to see how to make use of it. &lt;/p&gt;

&lt;p&gt;Just to give you a highlight, I have already put it to use for one of my other packages &lt;a href="https://www.npmjs.com/package/copious-endpoints"&gt;copious-endpoints&lt;/a&gt;.  For that, I made a &lt;strong&gt;asset-map.json&lt;/strong&gt; file.  This file maps the bin scripts released by copious-endpoints to the files that are needed to run each program.&lt;/p&gt;

&lt;p&gt;Here is the file contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "copious-contacts" : "contact-service.conf",
    "copious-user" : "relay-service.conf"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is file relates to the bin field in package.json. Here is the bin field from the module's package.json file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "bin" : {
    "copious-user" : "./bin/endpoint-user.js",
    "copious-contacts" : "./bin/endpoint-contacts.js",
    "add-mini-links" : "./bin/add-mini-links.js"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, to use one of the programs released the user will need to call something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$copious-user relay-services.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, where is that file? What should it look like? If I knew once, what if it changed?&lt;/p&gt;

&lt;p&gt;But, I could call &lt;strong&gt;get-npm-assets&lt;/strong&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$get-npm-assets copious-user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, as a user, I don't have to look into the module directory to get an example. And, this version of the command will get the relay-services.conf instead of contact-service.conf.&lt;/p&gt;

&lt;p&gt;You an also set up an assets directory and have the whole directory copied into a local assets directory that &lt;strong&gt;get-npm-assets&lt;/strong&gt; will make for you.&lt;/p&gt;

&lt;p&gt;Enjoy. Please leave issues in the github repository.&lt;/p&gt;

</description>
      <category>npm</category>
      <category>node</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Svelte Nested Tabs</title>
      <dc:creator>Richard Leddy</dc:creator>
      <pubDate>Tue, 07 Sep 2021 05:43:15 +0000</pubDate>
      <link>https://dev.to/rleddy/svelte-nested-tabs-3274</link>
      <guid>https://dev.to/rleddy/svelte-nested-tabs-3274</guid>
      <description>&lt;h1&gt;
  
  
  Svelte is Pretty Cool
&lt;/h1&gt;

&lt;p&gt;Maybe something worth talking about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is About
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/svelte-nested-tabs"&gt;svelte-nested-tabs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Experience
&lt;/h2&gt;

&lt;p&gt;I got some stuff up in a hurry. And, that may have been to do with Svelte.  &lt;/p&gt;

&lt;p&gt;I decided to make a blogging platform, one with music and videos among other things. I decided that I might have several entry pages, depending on the kind of media that is being presented. So, I needed to make grids I could just drop stuff into. &lt;/p&gt;

&lt;p&gt;So, I made a Svelte component that I am calling The grid of things. &lt;a href="https://www.npmjs.com/package/grid-of-things"&gt;grid-of-things&lt;/a&gt;. I figured that if you want an Internet of Things, you might want to see them, sometimes in a grid.&lt;/p&gt;

&lt;p&gt;One cool thing about Svelte is that you can have a slot. A slot is called out in HTML within a component that you might use in your web page. It goes something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;... Bunches of HTML
&amp;lt;!- suddenly you are here --&amp;gt;
&amp;lt;slot&amp;gt;
Oh! My gosh! Someone forget to put a value in!
&amp;lt;/slot&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, if that is part of a component, says "Surprises.svelte". Then when the application uses it, it can put in a value from the application. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
import * as everything from "Surprises.svelte"

// do JavaScript stuff.

&amp;lt;/script&amp;gt;
&amp;lt;!-- now for the HMTL part of the app --&amp;gt;
&amp;lt;div&amp;gt;
&amp;lt;Surprises {...parameters_in_an_object} &amp;gt;
I did not forget to put values in!
&amp;lt;/Surprises&amp;gt;
&amp;lt;span class="stylish"&amp;gt;So there!&amp;lt;/span&amp;gt;
&amp;lt;/div
&amp;lt;style&amp;gt; 
  .stylish { font-style: cursive }
&amp;lt;/style&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;It's like the Svelte components have attitude or something.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, it's all great fun.&lt;/p&gt;

&lt;p&gt;I was piking down the Svelte road, until one day...&lt;/p&gt;

&lt;h2&gt;
  
  
  I Needed Nested Tabs
&lt;/h2&gt;

&lt;p&gt;Strange! A little hard to come by. Well, maybe its in some ultra large library that finishes loading on your page for that date you have with Rip Van Winkle. But, how about something simple?&lt;/p&gt;

&lt;p&gt;Was making another little web app for sending message back and forth in a public P2P file system. It's doesn't have much purpose except replacing email with end to end encrypted contact mail that never touches a mail server. But, other than that it's just a page that needs nested tabs.&lt;/p&gt;

&lt;p&gt;You can find that software in the copious-world repository called, &lt;a href="https://github.com/copious-world/interplanetary_contact"&gt;interplanetary-contact&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am going to make some changes to the code there. Maybe I will call it "intergalactic-contact" later on. I am going to start using UCWIDs and derived keys. But, that is for another conversation. Right now, I am worried about nested tabs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tabs and Panels
&lt;/h3&gt;

&lt;p&gt;OK. You probably have a clue as to what I am talking about. But, just in case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A tab is a likely a button that you will see in a row at the top of a display area. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A panel is like a box ('div' in HTML-ese) that contains information to be displayed when one of the tab buttons is clicked.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a general idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="tab-row"&amp;gt;
&amp;lt;button on:click={activate_me}&amp;gt;tab 1&amp;lt;/button&amp;gt;
&amp;lt;button on:click={activate_me}&amp;gt;tab 2&amp;lt;/button&amp;gt;
&amp;lt;button on:click={activate_me}&amp;gt;tab 3&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div id="tab1-panel"  class="panel"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div id="tab2-panel"  class="panel"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div id="tab3-panel"  class="panel"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the panels are visible one at a time, depending on the button that got clicked.&lt;/p&gt;

&lt;h3&gt;
  
  
  I Looked Around
&lt;/h3&gt;

&lt;p&gt;I looked around and found some pretty good components that will make great tabs if you just use one layer. I used one, and just decided that all the page could be under separate tabs. If I recall (just months ago) I was hoping to keep the message lists under one tab with tabs for kinds of messages nested below it. I made some compromises.&lt;/p&gt;

&lt;p&gt;I started wondering if maybe Svelte was just too tricky to work with. I started looking around again. I found nested tabs that look wonderful and are in vanilla JS or use jQuery. OK. But, I was hoping to keep things organized with in one scheme, not many.&lt;/p&gt;

&lt;p&gt;I tried slots. So, in my &lt;strong&gt;grid-of-things&lt;/strong&gt; component, there is a single slot that is replicated many times. In fact, it is the same object allowing in different data. But, all the data has the same structure. So, each presentation is similar, but it might have a different picture, SVG, or a different link to some media.&lt;/p&gt;

&lt;p&gt;At first I thought named slots might work. But, really name slots are just like slots without names. They allow a datum to be parsed into them for a one view. Again the structure is expected to be the same. I tried using a formula for the name, but I got a message in the compiler saying "slot names cannot be dynamic".  So, that is actually blocked. I was imaging an application loop going through a list of tabs somehow generating a list of matched slots in the components.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Nested Tabs Need Different Components in Each Panel
&lt;/h3&gt;

&lt;p&gt;Something more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="tab-row"&amp;gt;
&amp;lt;button on:click={activate_me}&amp;gt;tab 1&amp;lt;/button&amp;gt;
&amp;lt;button on:click={activate_me}&amp;gt;tab 2&amp;lt;/button&amp;gt;
&amp;lt;button on:click={activate_me}&amp;gt;tab 3&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div id="tab1-panel"  class="panel"&amp;gt;{stuff_from_ace[1]}&amp;lt;/div&amp;gt;
&amp;lt;div id="tab2-panel"  class="panel"&amp;gt;{stuff_from_acme[0]}&amp;lt;/div&amp;gt;
&amp;lt;div id="tab3-panel"  class="panel"&amp;gt;{stuff_from_the_bay[4]}&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like that. One for each provider - say. Or, maybe they are all the same type. But, what you want to do is generate the panels in a &lt;strong&gt;for&lt;/strong&gt; loop. The same for the buttons. Here is the Svelte way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="tab-row"&amp;gt;
{#each tab_list as tab (tab.id)}
&amp;lt;button on:click={activate_me}&amp;gt;tab.name&amp;lt;/button&amp;gt;
{/each}
&amp;lt;/div&amp;gt;
{#each tab_list as tab (tab.id)}
&amp;lt;div id={tab.id) &amp;gt;
{tab.content}
&amp;lt;/div&amp;gt;
{/each}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, right there where it says &lt;code&gt;tab.content&lt;/code&gt;, you want something like a &lt;em&gt;slot&lt;/em&gt;. But, you can't have a &lt;em&gt;slot&lt;/em&gt;. At least you can't have a different &lt;em&gt;slot&lt;/em&gt; at each point in the loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  There is a Way
&lt;/h2&gt;

&lt;p&gt;Svelte does have a trick up its sleeve, it's called &lt;strong&gt;&lt;em&gt;svelte:component&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What you do with this is use it where you might put a &lt;em&gt;slot&lt;/em&gt;.  And, you tell it what component to put there. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;svelte:component this={component} {...parameters} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you bind "this" to the component to say what it's type is. And, you can pass parameters in a generic way, using the ellipsis. So, as long as you can pass a component to the tabs component, where the passed component is one imported into the Svelte app calling the nested tab component, you can put anything into the tab's panel. The parameters object would be passed as well. So, you get you data straight in the application and send it down.&lt;/p&gt;

&lt;p&gt;For my Tabs component, I put in a loop to get my components lined up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{#each tab_list as tab (tab.id) }
{#if active === tab.id }
&amp;lt;div class="tab-panel" style={(tab.style &amp;amp;&amp;amp; tab.style.panel) ? tab.style.panel : (style &amp;amp;&amp;amp; style.panel ? style.panel : "") }&amp;gt;
    {#if (tab_panels[tab.id] !== undefined) &amp;amp;&amp;amp; tab_panels[tab.id] }
    &amp;lt;svelte:component this={tab_panels[tab.id].component} {...(tab_panels[tab.id].parameters)} /&amp;gt;
    {:else}
        {@html tab.content}
    {/if}
&amp;lt;/div&amp;gt;
{/if}
{/each}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, you see, I passed in a list of tabs, &lt;em&gt;tab|_list&lt;/em&gt; and a map of &lt;em&gt;tab|_panels&lt;/em&gt;. The &lt;em&gt;tab|_panels&lt;/em&gt; have fields pointing to the component class, and  field point to parameters to parameters that go into the component.&lt;/p&gt;

&lt;h2&gt;
  
  
  It Needs to be Said : the Component Parameter may be a Tabs Component
&lt;/h2&gt;

&lt;p&gt;So, there you have it. &lt;/p&gt;

&lt;p&gt;The application can now decide what it wants inside a Tabs component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
import Tabs from "svelte-nested-tabs"

&amp;lt;/script&amp;gt;
&amp;lt;!-- now for the HMTL part of the app --&amp;gt;
&amp;lt;main&amp;gt;
    &amp;lt;h1&amp;gt;Hello {name}!&amp;lt;/h1&amp;gt;
    &amp;lt;div class="tab-container" &amp;gt;
        &amp;lt;Tabs {...tab_def} /&amp;gt;
    &amp;lt;/div&amp;gt;  
&amp;lt;/main&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The innocuous variable, &lt;em&gt;tab_def&lt;/em&gt; has a longish definition. One you might want to grab from a DB or something. Here is a version of one that does one nested tab.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let tab_list_def = {
        "tab_list" : [
            { 
                "id" : "l1_1",
                "name" : "tutorial",
                "content" : "not much"
            },
            { 
                "id" : "l1_2",
                "name" : "example",
                "content" : "won't see this"
            },
            { 
                "id" : "l1_3",
                "name" : "colors",
                "content" : "superfluous..."
            }
        ],
        "tab_panels" : {
            "l1_1" : false,
            "l1_2" : {
                "component" : Tabs,
                "parameters" : {
                    "tab_list" : [
                                    { 
                                        "id" : "l2_1",
                                        "name" : "jumping jack",
                                        "content" : "bouncy"
                                    },
                                    { 
                                        "id" : "l2_2",
                                        "name" : "nick nack",
                                        "content" : "likes momentos"
                                    }
                                ],
                    "tab_panels" : {
                        "l2_1" : false,
                        "l2_2" : false
                    },
                }
            }
        }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks longer than it is. But, you can load parts and put them together, and you don't have it in your code. Notice that &lt;code&gt;tab_list_def.tab_panels.l1_2.component&lt;/code&gt; is a &lt;strong&gt;Tabs&lt;/strong&gt; component, the same from the import statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You can customize it, too. There is room for improvement there if you want to help out. &lt;/p&gt;

&lt;p&gt;You can find out more by checking out the repository: &lt;a href="https://www.npmjs.com/package/svelte-nested-tabs"&gt;svelte-nested-tabs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, you can get a working example from my brand new (not yet rewritten readme) example repository. &lt;a href="https://github.com/rleddy/svelte-examples"&gt;svelte-examples&lt;/a&gt;.  The example uses the styling capabilities.&lt;/p&gt;

&lt;p&gt;Not bad for an afternoon! Gotta go!.&lt;/p&gt;

&lt;p&gt;Hope you enjoy!&lt;/p&gt;

&lt;p&gt;Thanks. Bye.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>nested</category>
      <category>tabs</category>
    </item>
    <item>
      <title>Elliptic Curve TLSv1.3 for Node.js</title>
      <dc:creator>Richard Leddy</dc:creator>
      <pubDate>Fri, 20 Aug 2021 01:06:22 +0000</pubDate>
      <link>https://dev.to/rleddy/elliptic-curve-tlsv1-3-for-node-js-16mm</link>
      <guid>https://dev.to/rleddy/elliptic-curve-tlsv1-3-for-node-js-16mm</guid>
      <description>&lt;p&gt;So...  This is short. &lt;/p&gt;

&lt;p&gt;I spent a lot of time (I mean an awful amount of time) yesterday assuring myself that the few short steps in the node.js docs for TLS are as easily done with elliptic curves. After reading up on a lot of things and running my freshly secure application, I am finally satisfied that it's &lt;strong&gt;OK&lt;/strong&gt; to just use the openssl ecparam and ec parameters. And, it's &lt;strong&gt;OK&lt;/strong&gt; to slip them into an X509 format at the end to get files for node.js TLS connections.&lt;/p&gt;

&lt;p&gt;Why is that something that you wouldn't just do without thinking it about? Well...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Problem #1&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;I overthink things as a habit.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Problem #2&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've been playing this development game for too many years. So, now I am suspicious of all documentation, all code snippets, and anyone saying he's got a quick fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful Articles
&lt;/h2&gt;

&lt;p&gt;The articles are helpful for explaining lots of things. Except, many are now quite a few years old. My! How time flies!&lt;/p&gt;

&lt;p&gt;So, you start opening many articles returned by your favorites search engine, only to find a repetition of the first one some twenty articles back with the same code snippet from the node.js documentation.&lt;/p&gt;

&lt;p&gt;In the end, the best thing to read was the openssl documentation. See &lt;a href="https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations"&gt;openssl elliptics&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's lots of great articles with pretty pictures that explain elliptic curve cryptography. Some of it is beautiful. I will have to write up some review some time. Later...&lt;/p&gt;

&lt;p&gt;Of course, if you want to go deeper into what the TLS standard is, you can always immerse yourself in the IETF documents &lt;a href="https://tools.ietf.org/id/draft-ietf-tls-tls13-21.html"&gt;IETF on TLSv1.3&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this Bother?
&lt;/h2&gt;

&lt;p&gt;Well... Let's say you have working processes in back-end computers. They don't all have to be HTTP/S. They can just pass messages around with their own format. For instance, I am using my own little JSON message relay stack. Find it here: &lt;a href="https://www.npmjs.com/package/message-relay-services"&gt;message-relay-services&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, you want connections only; no other overhead. &lt;/p&gt;

&lt;p&gt;And, yes, you want secure connections between computers that aren't even facing the outside world. Maybe within a specific cluster you can forego some security. But, these messages go between loosely connected (tiny) servers fairly close to the front of the operation. Better safe than sorry.&lt;/p&gt;

&lt;p&gt;As a result, my implementation case even has specific client keys being configured into the servers. I have endpoint servers (those that finally do something to a table on disk or similar). They know who their client is. Of course, other than one admin desktop app, the client is most likely a middle message exchange, which serves many clients itself. &lt;/p&gt;

&lt;h2&gt;
  
  
  So... What are those Commands?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The ellipses once again!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is the two step key generation using openssl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ openssl ecparam -name secp384r1 -genkey -out keys/ec_key.pem

$ openssl req -new -x509 -key keys/ec_key.pem -sha256 -nodes -out keys/ec_crt.crt -days 365
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, yes, I copied them from the docs. &lt;/p&gt;

&lt;p&gt;The first generates the secret key. Notice that I put it in a &lt;em&gt;key&lt;/em&gt; directory. The directory is about keeping down clutter. Put it where you need it. &lt;/p&gt;

&lt;p&gt;Also, notice that I chose a particular curve, &lt;strong&gt;secp384r1&lt;/strong&gt;. This is for 384 bits of key. There are many other curves. Check the node.js docs on how to find out what they are. &lt;/p&gt;

&lt;p&gt;The next command generates the public key and puts it into an X509 file. The file is the &lt;strong&gt;cert&lt;/strong&gt;. The &lt;em&gt;req&lt;/em&gt; command with the X509 format guides you through putting in required fields. The fields are not magical, just where you are and who you are and a way to contact you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just make sure that you do this for the server and the client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Keys in node.js
&lt;/h2&gt;

&lt;p&gt;Now, this where the examples don't change. Below is code if you don't want to follow links like this one &lt;a href="https://nodejs.org/api/tls.html"&gt;node.js tls doc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The code is from &lt;a href="https://www.npmjs.com/package/message-relay-services"&gt;message-relay-services&lt;/a&gt;. Notice that I used a configuration object. The file reading happens at initialization. It is not safe code per se. &lt;em&gt;Later, I may move the file reading to an earlier point in initialization, so it can crash sooner.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You might ask, "Does this basically copy the docs?" Yes, it does, almost to the letter. &lt;strong&gt;Read the docs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But, the point is: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You don't have to change old TLS code to use the EC curves. Just prepare the files differently. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;This exercise has been carried out on node version v16.6.2&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Server:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let base = process.cwd()
const options = {
    key: fs.readFileSync(`${base}/${this.tls_conf.server_key}`),
    cert: fs.readFileSync(`${base}/${this.tls_conf.server_cert}`),
    requestCert: true,  // using client certificate authentication
    ca: [ fs.readFileSync(`${base}/${this.tls_conf.client_cert}`) ] //client uses a self-signed certificate
};
if ( this.extended_tls_options !== false ) {
    options = Object.assign({},options,this.extended_tls_options)
}
this.connection = tls.createServer(options,((sock) =&amp;gt; { this.onClientConnected_func(sock) }));    

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Client:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let base = process.cwd()
const tls_options = {
    // Necessary only if the server requires client certificate authentication.
    key: fs.readFileSync(`${base}/${this.tls_conf.client_key}`),
    cert: fs.readFileSync(`${base}/${this.tls_conf.client_cert}`),
    // Necessary only if the server uses a self-signed certificate.
    ca: [ fs.readFileSync(`${base}/${this.tls_conf.server_cert}`) ],
    // Necessary only if the server's cert isn't for "localhost".
    checkServerIdentity: () =&amp;gt; { return null; },
};
if ( this.extended_tls_options !== false ) {
    tls_options = Object.assign({},tls_options,this.extended_tls_options)
}
this.socket = tls.connect(this.port, this.address, tls_options, () =&amp;gt; {
    if ( this.socket.authorized ) {
        this._connection_handler()
    } else {
        this.socket.end()
    }
    this.writer = this.socket
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  EXIT
&lt;/h2&gt;

&lt;p&gt;If this saved you time, then maybe life has purpose.&lt;/p&gt;

</description>
      <category>tls</category>
      <category>ec</category>
      <category>node</category>
      <category>openssl</category>
    </item>
    <item>
      <title>Crypto-wraps</title>
      <dc:creator>Richard Leddy</dc:creator>
      <pubDate>Tue, 10 Aug 2021 02:21:54 +0000</pubDate>
      <link>https://dev.to/rleddy/crypto-wraps-3n8p</link>
      <guid>https://dev.to/rleddy/crypto-wraps-3n8p</guid>
      <description>&lt;p&gt;So, I put this npm package out there: &lt;a href="https://www.npmjs.com/package/crypto-wraps"&gt;crypto-wraps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this package, which is on GitHub &lt;a href="https://www.github.com/copious-world/crypto-wraps"&gt;crypto-wraps-GitHub&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I tested it in FireFox and node.js&lt;/p&gt;

&lt;p&gt;As with many wrapper libraries, some of the methods pick which encryption standard they use. So, while crypto.subtle  gives you just about every standard crypto routine you can think of, this library just uses some of them.&lt;/p&gt;

&lt;p&gt;More on the crypto.subtle library can be found at MDN: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Crypto/subtle"&gt;Crypto/subtle&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;What is there to say? Well, calling the crypto.subtle methods has its ins and outs. The code gets a little long, and you are always worrying about the types of the data buffers going in and out of the methods. Then, since the crypto.subtle methods always use ArrayBuffers or more specifically Uint8Arrays, your program has to put the buffers into text (hex or base64url) to send them anywhere.&lt;/p&gt;

&lt;p&gt;Actually, I ran into some trouble storing buffers straight up in the IndexedDB. But, they stored well as blobURls which are usually a base64 encoding of the blob along with some mime type information.  But, yes, the first time I stuck a blob straight into the IndexedDB to have it disappear, I was a little surprised and started converting the buffers to base text.&lt;/p&gt;

&lt;p&gt;So, here is a code example from the node.js test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let cwraps = require('../lib/crypto-wraps')
let hashit = require('../lib/crypto-hash');
...

    let again_text = "Finally the last test again until the next last test."
    let again_cipher_text = await cwraps.encipher_message(again_text,aes_key,nonce)
    let wrapped_key = await cwraps.key_wrapper(aes_key,key_pack.pk_str)
    let again_decipher_text =  await cwraps.decipher_message(again_cipher_text,wrapped_key,key_pack.priv_key,nonce)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, I saved myself a lot lines. Here is the code for just the key_wrapper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function key_wrapper(key_to_wrap,pub_wrapper_key) {
    try {
        let wrapper_jwk = JSON.parse(pub_wrapper_key)
        let wrapper = await g_crypto.importKey(
                "jwk",
                wrapper_jwk,
                {   //these are the wrapping key's algorithm options
                    name: "RSA-OAEP",
                    modulusLength: 4096, //can be 1024, 2048, or 4096
                    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
                    hash: { name: "SHA-256" },
                },
                true,
                ["wrapKey"]
        );

        let wrapped_key = await g_crypto.wrapKey(
                                            "jwk",
                                            key_to_wrap,
                                            wrapper,
                                            {   //these are the wrapping key's algorithm options
                                                name: "RSA-OAEP"
                                            }
                                        );
        let type8 = new Uint8Array(wrapped_key)
        let tranportable = to_base64_from_uint8array(type8)
        return tranportable
    } catch(e) {
        console.log(e)
    }
    return false
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, you see how things can grow. Here the program is parsing JSON to get an "jwk" object carrying the public wrapper key. This is the key you would give someone to wrap something to send to you, that only you can unwrap with your private key. The code imports the wrapper key from the "jwk" object. The key to wrap is passed in as an object of type Cryptokey. The wrapper does not know too much about it. But, it is an AES key that I got out of the key gen method.&lt;/p&gt;

&lt;p&gt;The methods are using this global variable: &lt;strong&gt;g_crypto&lt;/strong&gt;. The reason for that is that node.js exposed the &lt;em&gt;crypto.subtle&lt;/em&gt; methods from one global object, while the browser uses another: &lt;/p&gt;

&lt;p&gt;node.js way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let g_crypto = crypto.webcrypto.subtle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;browser way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;window.g_crypto = window.crypto ? window.crypto.subtle : null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It turns out that node.js and the browser are very much in agreement with the exposition of the &lt;em&gt;crypto.subtle&lt;/em&gt; methods. The modules, crypto-wraps.js, for the two versions are almost identical. For base64url encoding, they both import to methods from the hash module: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to_base64_from_uint8array&lt;/li&gt;
&lt;li&gt;from_base64_to_uint8array&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These methods do differ between node.js and the browser. But, at the next level up, they are used exactly the same. &lt;/p&gt;

&lt;p&gt;For the browser version, I borrowed base64 encoding from a Gist by Egor Nepomnyaschih. &lt;a href="https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727"&gt;base64&lt;/a&gt;.  That proved to be very helpful. The node version makes use of easy Buffer class conversions.&lt;/p&gt;

&lt;h3&gt;
  
  
  That's all for now folks.
&lt;/h3&gt;

&lt;p&gt;Have fun with it. Leave notes in the issues. Thanks.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>crypto</category>
      <category>subtle</category>
    </item>
    <item>
      <title>IPFS CIDS v.s. CWIDS</title>
      <dc:creator>Richard Leddy</dc:creator>
      <pubDate>Tue, 03 Aug 2021 07:59:39 +0000</pubDate>
      <link>https://dev.to/rleddy/ipfs-cids-v-s-cwids-3acm</link>
      <guid>https://dev.to/rleddy/ipfs-cids-v-s-cwids-3acm</guid>
      <description>&lt;p&gt;So, I just wrote a program, call it more a prototype, for something like email, but using IPFS. I call it interplanetary-contact for the moment.  You can find a copy of it at &lt;a href="https://www.github.com/copous-world"&gt;copious-world&lt;/a&gt;. I was hoping for email without a server, but for this you still have to invoke the node.js server included there. And, interface is a Svelte application.&lt;/p&gt;

&lt;p&gt;I got it up and working. But, I still have much more to do with it. One things I was doing was using the Mutable File System, MFS which is part of IPFS. And, I was allowing the server to act as an agent for IPFS. Not the worst thing you can do, but not a true player in P2P. Also, the server is being relied upon to make CIDs or fetch them from IPFS. &lt;/p&gt;

&lt;p&gt;So, I need to make CIDs in a browser. This led me to the anatomy of CID. And, as I dug deeper, I wanted more from a CID and less code in the browser, too. So, I came up with a CWID. It's really a minor difference. And, I will explain. But, I will also fill you in on a CID just in case you are not the CID aficionado.&lt;/p&gt;

&lt;h3&gt;
  
  
  CIDs
&lt;/h3&gt;

&lt;p&gt;A CID is a content identifier. It refers to a unique set of bytes, that is one byte array per CID. It also has information, a prefix, preceding the true identifier telling the programs and programmers the format in which the identifier is being presented. So, the if identifier contains a SHA256 hash of the content, the hash may be presented in a base, such as Hex = base16, or base64url, or btc58, or binary, or other. Another hashing algorithm may be used, and the length will be part of the encoded data.  At the very front of the string is single character indicating the base. All the rest of the characters are in the base.&lt;/p&gt;

&lt;p&gt;So, for a CID not all formats can simply be tacked together by concatenating parts of the CID. Hex can be done that way. But, base64 requires a little more finesse. Before putting the base flag at the front of the string, all the descriptors must be placed into a binary buffer, and the whole buffer gets presented in the base.&lt;/p&gt;

&lt;p&gt;So, for a Hex string using SHA256, prior to putting an 'f' in front of the lower case hex string, the buffer will be arranged as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;version number: 01 - this is the CIDv1&lt;/li&gt;
&lt;li&gt;the hash storage structure:  'raw' = 0x55&lt;/li&gt;
&lt;li&gt;the algorithm: 'sha2-256' = 0x12&lt;/li&gt;
&lt;li&gt;length of the hash buffer: 0x20 = 256bits/8 = 32bytes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final string will look something like the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;f01551220a9uf9ac9af9ua0c8a9f890a8f0af0...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, if you have a system that is solid in one kind of CID, you can store f01551220 as a constant. But, that works if you are using Hex or another very predictable base.&lt;/p&gt;

&lt;p&gt;If you get good CIDs, you can try them out using the IPFS &lt;a href="https://cid.ipfs.io/"&gt;CID Inspector&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  My CID problem
&lt;/h3&gt;

&lt;p&gt;So, I was thinking why use all that IPFS code to make a CID, and what if I want to use base64? So, I started toying around with CIDs and I came to a point where the idea of concatenating strings and have the SHA256 hash clearly exposed would be nice. But, CIDs are not so amazingly clear with base64.&lt;/p&gt;

&lt;p&gt;So, here is a SHA256 hash of "MUCH TO DO ABOUT IDENTITY" in base64url:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;KSrJ8BfYBJFRaHsFbClKvhwVFeapgccN2QCxShd54GY=&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is the IPFS CID for just this text:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;uAVUSICkqyfAX2ASRUWh7BWwpSr4cFRXmqYHHDdkAsUoXeeBm&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, where did the SHA hash go?&lt;/p&gt;

&lt;p&gt;Well, it is in there, but the length of the SHA256 hash, 32 bytes, which you might have seen before in the hex prefix, has started the base64 encoding, changing the rest of the string.&lt;/p&gt;

&lt;p&gt;In fact, the base64 encoding of the prefix, which might never change, is uAVUSIA==. You can see the uAVUSI part. But, the size of hash is not going to change either.&lt;/p&gt;

&lt;p&gt;So, what if I want to get get the hash from the CID. There are times one wants to do that. For instance, you might be verifying a hash in a Merkel tree. So, this would mean that for all hashes, you have to run the CID parser and pull out the bytes. &lt;/p&gt;

&lt;p&gt;But, you could just make a string that keeps the hash exposed. You want the hash, and neither its function nor its accessibility doesn't change from how you pack the string. But, that is  a functional point about the hash doing its job as an indicator. You can make the string harder to access in the sense that the computer works harder to pull it out. But, that's all that will be happening. So, with millions and millions of hashes, the energy bill goes up.&lt;/p&gt;

&lt;h3&gt;
  
  
  CWID
&lt;/h3&gt;

&lt;p&gt;Does CWID rhyme with quid? &lt;/p&gt;

&lt;p&gt;Well, I put a program in this repository: &lt;a href="https://github.com/copious-world/CWID"&gt;CWID&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A CWID is not much different than a CID. I just made it so that the prefix is separate from the hash. I put in a Sheffer stroke '|' to indicate the separation. &lt;/p&gt;

&lt;p&gt;So, here is my CWID for "MUCH TO DO ABOUT IDENTITY":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;uAVUSIA==|KSrJ8BfYBJFRaHsFbClKvhwVFeapgccN2QCxShd54GY=&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maybe the padding could be taken out and put back in for checking it out. Maybe something other than a Sheffer stroke should be used (it gets URI encoded by some browsers). Or, maybe that is not too big a issue.&lt;/p&gt;

&lt;p&gt;So, if you are making lots of CWIDs, just make a constant out of the prefix and have it waiting in a buffer to write the hash after it. That works well in C++. The JavaScript might not gain too much from that.&lt;/p&gt;

&lt;p&gt;I was wondering if the prefix really had to be in the same base as the hash. I guess if you are on a really small machine that you might only have room for one encoding function. Would that just be a special prefix?&lt;/p&gt;

&lt;p&gt;Well, now that I have this trick, I can revisit Interplanetary-contact and switch to making CWIDs in the browser. Maybe I will have to rename it to Intergalactic-contact.&lt;/p&gt;

&lt;p&gt;You can play with the code.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm test&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This should launch your default browser and start up http-server to serve the page. You may have to install http-server.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i http-server@0.8.5&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The CWID repository is not an npm package. But, you can clone it off of GitHub. Please feel free to raise issues.&lt;/p&gt;

&lt;p&gt;Also, note that this is very new (did it today), and there is very little support for all the different formats. That is, there is just base64url and Hex.&lt;/p&gt;

&lt;h3&gt;
  
  
  Following up
&lt;/h3&gt;

&lt;p&gt;Hope that is entertaining for now. For later, I am planning to discuss identity and how to have email without having email. With the contact system, no email addresses are used. Rather, your description of yourself is turned into a content identifier. But, that's all for now...&lt;/p&gt;

</description>
      <category>cid</category>
      <category>ipfs</category>
      <category>svelt</category>
      <category>cwid</category>
    </item>
  </channel>
</rss>
