From e5bbe8e3631c4402da1c3d267b6e8ac11a7594eb Mon Sep 17 00:00:00 2001
From: Jake <jake.read@cba.mit.edu>
Date: Mon, 25 Mar 2019 11:31:03 -0400
Subject: [PATCH] at hello ws to nautilus

---
 README.md                        |  23 ++++++-
 bootstrap.js                     |  54 +---------------
 hunks/comm/websocketclient.js    | 103 +++++++++++++++++++++++++++++++
 hunks/communication/websocket.js |  72 ---------------------
 hunks/hunks.js                   |   4 +-
 hunks/link.js                    |   2 +
 hunks/manager.js                 |   2 +-
 programs/wstest.json             |  39 ++++++++++++
 style.css                        |   4 +-
 9 files changed, 171 insertions(+), 132 deletions(-)
 create mode 100644 hunks/comm/websocketclient.js
 delete mode 100644 hunks/communication/websocket.js
 create mode 100644 programs/wstest.json

diff --git a/README.md b/README.md
index 3de9085..f0a00d2 100644
--- a/README.md
+++ b/README.md
@@ -255,6 +255,9 @@ The other (maybe better) way is to, after state updates are called, send a new d
  these are heirarchichal ... draw the tree description of those messages, starting from the complete hunk 
  and think about this again when you're writing messages from the cpp manager 
 
+ - w/r/t managing the manager - calls that require file system access can be made to a 2nd file, exported outside of manager.js - then we don't have to re-write it every time we make changes. when we make big changes next, let's do this 
+ - of other interest is writing a node script to read thru files and walk them between directories ... i.e. look for all browser elements without a this.dom element and copy pasta, including manager ... and the other way 
+
 ### Log 2019/03/22
 
  - have I finished the link / node port ?
@@ -264,16 +267,30 @@ The other (maybe better) way is to, after state updates are called, send a new d
  - find a way to scale the whole div, and push its edges out ? must be a way, and it's hella worth trying 
  - ... on link add, adds view also, hooks that view to that link (find a route?) - this is a cuttlefish subroutine ! 
 
+### Log 2019/03/24 
+
+This week, I'm up to talking between two contexts. I have 'cuttlefish' (this) and 'nautilus' (node) which are near-identical implementations of a flow-controlled context in js. I am waking up websockets on both sides - the immediate task is just to send anything back and forth with two simple test programs.
+
+Then I'll be writing the link - at first just a few flow-controlled ports: these will let me experiment with putting a view inside of cuttlefish... and a nautilus bootstrap program.
+
+From there I'm going to need to stretch the manager a little bit more, the link is going to need to add / rm ports dynamically. Probably based on state, so these things will have to get worked out.
+
+Given all of this cross-domain work, It's probably going to save me lots of hassle if I sit down and carefully write a script to pull edits from the node environment into the browser environment etc. This should be true for 'link' and 'manager' especially. That means that Manager needs a file-helper on both sides. 
+
+To satisfy the itch, I'll finish the ws throughput first, commit to both, and then start on the mess. 
+
+The next breath I can take is when I get a view up and running of an offboard resource ... of that node server. I think I need a schedule for this, and real goals with dates attached to them, else deadline creep is going to make me sad. 
+
 ## View Potshots
- - right-click on name to delete
- - escape key to leave menu (/ keys on dom ?)
+ - escape key to leave menu (/ keys on dom ? /on new right-click etc)
  - on zoom, check if element is view or not,
  - if not view (is block) then look for event parent position, not event 
 
 # Videos to Take
 
  - loading with view relaxation 
- - loading a link, spawning a view 
+ - loading a link, spawning a view
+ - show two cuttlefishes with views into the same nautilus, editing together... or just pushing program edits back and forth. 
 
 # Known Bugs
 
diff --git a/bootstrap.js b/bootstrap.js
index 98626ea..24500ed 100644
--- a/bootstrap.js
+++ b/bootstrap.js
@@ -40,60 +40,10 @@ window.onload = () => {
         NROL.describeRunningProgram()
         bootloop()
         // and then we can load this program
-        NROL.addProgram('programs/linktest').then((newHunks) => {
+        NROL.addProgram('programs/wstest').then((newHunks) => {
             for (let hnk of newHunks) {
                 NROL.sendHunkAsDef(hnk)
             }
         })
     })
-}
-
-/*
-
-window.onload = () => {
-    console.log('BOOOOOOOOOT')
-    NROL.addHunk('manager').then((native) => {
-        Native = native
-        console.log('HELLO MANAGER', Native)
-        NROL.addHunk('hidden/view').then((view) => {
-            View = view
-            console.log('HELLO VIEW', View)
-            $('#wrapper').get(0).append(View.dom)
-            try{
-                NROL.addLink(View.id, 'msgs', Native.id, 'msgs')
-                NROL.addLink(Native.id, 'msgs', View.id, 'msgs')
-            } catch (err) {
-                console.log('no dice', err)
-            }
-            // NROL is hooked up, View is hooked to Native,
-            // do startup program load 
-            console.log("BEGIN THE PROGRAM LOADETH")
-            Native.addProgram('programs/linktest').then((x) => {
-                console.log('PROGRAM LOADETH SUCCESS', x)
-                Native.describeRunningProgram()
-            }).catch((err) => {
-                console.log('PROGRAM LOADETH NOT', err)
-            })
-            // let this happen in the context of the loop running?
-            bootloop() 
-            
-            /*
-            Native.addHunk('input/string').then((str) => {
-                Native.addHunk('interface/logger').then((lgr) => {
-                    // connext
-                    Native.addLinkByObject(str, 'string', lgr, 'tolog')
-                    // needs 2 be buffered for multiple writes like this 
-                    Native.sendHunkAsDef(str)
-                    Native.sendHunkAsDef(lgr)
-                    console.log('strang', str)
-                    console.log('logger', lgr)
-                })
-            })
-            console.log('BOOOOOOOOOT BEGIN')
-            bootloop()
-            
-        })
-    })
-}
-
-*/
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/hunks/comm/websocketclient.js b/hunks/comm/websocketclient.js
new file mode 100644
index 0000000..46eb8a8
--- /dev/null
+++ b/hunks/comm/websocketclient.js
@@ -0,0 +1,103 @@
+/*
+
+line input
+
+*/
+
+import { Hunkify, Input, Output, State } from '../hunks.js'
+
+function WebSocketClient() {
+    Hunkify(this, 'WebSocketClient')
+
+    this.inputs.bytes = new Input('type', 'bytes')
+    this.outputs.bytes = new Output('type', 'bytes')
+
+    // TODO is tackling state sets / updates / onupdate fn's 
+    // this is hunk -> manager commune ... 
+    this.state.status = new State('string', 'status', 'closed')
+    this.state.address = new State('string', 'address', '127.0.0.1')
+    this.state.port = new State('string', 'port', '2042')
+
+    // this ws is a client, 
+    let ws = {}
+    let url = 'ws://127.0.0.1:2020'
+    this.outbuffer = new Array() 
+
+    this.init = () => {
+        startWs() 
+        setTimeout(checkWsStatus, 1000)
+    }
+
+    let startWs = () => {
+        // manager calls this once 
+        // it is loaded and state is updated (from program)
+        url = 'ws://' + this.state.address.value + ':' + this.state.port.value
+        console.log('INIT WS', url)
+        ws = new WebSocket(url)
+        ws.onopen = (evt) => {
+            this.log('ws opened')
+            this.log('the ws object', ws)
+            this.log(evt)
+            this.state.status.set('opened')
+        }
+        ws.onerror = (evt) => {
+            this.log('ws error')
+            console.log(evt)
+            this.state.status.set('error')
+            // go for reboot
+            checkWsStatus() 
+        }
+        ws.onmessage = (evt) => {
+            if (this.outputs.bytes.ie && this.outbuffer.length === 0) {
+                this.outputs.bytes.put(evt.data)
+            } else {
+                this.outbuffer.push(evt.data)
+            }
+        }
+        //setTimeout(checkWsStatus, 1000)
+    }
+
+    let checkWsStatus = () => {
+        switch(ws.readyState) {
+            case WebSocket.CONNECTING: 
+                setTimeout(checkWsStatus, 500)
+                break 
+            case WebSocket.OPEN:
+                // all gucci turn this event ringer off
+                break 
+            case WebSocket.CLOSING:
+                // check back later
+                setTimeout(checkWsStatus, 500)
+                break 
+            case WebSocket.CLOSED:
+                // try for reboot 
+                startWs() 
+                setTimeout(checkWsStatus, 500)
+                break 
+
+        }
+    }
+
+    this.loop = () => {
+        // something like if(ws !== null && ws.isopen)
+        // if we have an open port, and have bytes to send downstream, 
+        if (ws !== null && ws.readyState === 1) {
+            // no buffering 
+            if (this.inputs.bytes.io) {
+                let message = this.inputs.bytes.get()
+                console.log("WS SENDING", message)
+                ws.send(message)
+            }
+        }
+
+        // check if we have outgoing to pass along 
+        if (this.outbuffer.length > 0) {
+            if (this.outputs.bytes.ie) {
+                this.outputs.bytes.put(this.outbuffer.shift())
+            }
+        }
+
+    }
+}
+
+export default WebSocketClient
\ No newline at end of file
diff --git a/hunks/communication/websocket.js b/hunks/communication/websocket.js
deleted file mode 100644
index 67ee582..0000000
--- a/hunks/communication/websocket.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-
-line input
-
-*/
-
-import { Hunkify, Input, Output, State } from '../hunks.js'
-
-function WebSocket() {
-    Hunkify(this, 'WebSocket')
-
-    this.inputs.bytes = new Input('type', 'bytes')
-    this.outputs.bytes = new Output('type', 'bytes')
-
-    // TODO is tackling state sets / updates / onupdate fn's 
-    // this is hunk -> manager commune ... 
-    this.state.status = new State('string', 'status', 'hidden')
-    this.state.address = new State('string', 'address', '127.0.0.1')
-    this.state.port = new State('string', 'port', '2042')
-
-    let ws = {}
-    let outbuffer = []
-
-    this.init = () => {
-        // manager calls this once 
-        // it is loaded and state is updated (from program)
-        this.log('hello websocket')
-        let url = 'ws://' + this.state.address.value + ':' + this.state.port
-        ws = new WebSocket(url)
-        ws.onopen = (evt) => {
-            this.log('ws opened')
-            this.log('the ws object', ws)
-            this.log(evt)
-            this.state.status.set('opened')
-        }
-        ws.onerror = (evt) => {
-            this.log('ws error')
-            this.log(evt)
-            this.state.status.set('error')
-        }
-        ws.onmessage = (evt) => {
-            if (this.outputs.bytes.ie) {
-                this.outputs.bytes.put(evt.data)
-            } else {
-                this.outbuffer.push(evt.data)
-            }
-        }
-    }
-
-    // ok we dont' actually get to test this until we have a node version back up and running 
-
-    this.loop = () => {
-        // something like if(ws !== null && ws.isopen)
-        // if we have an open port, and have bytes to send downstream, 
-        if (ws !== null && ws.isopen) {
-            // no buffering 
-            if (this.inputs.bytes.io) {
-                ws.send(this.inputs.bytes.get())
-            }
-        }
-
-        // check if we have outgoing to pass along 
-        if(outbuffer.length > 0){
-            if(this.outputs.bytes.ie){
-                this.outputs.bytes.put(outbuffer.shift())
-            }
-        }
-
-    }
-}
-
-export default WebSocket
\ No newline at end of file
diff --git a/hunks/hunks.js b/hunks/hunks.js
index 39b665f..e92c0a8 100644
--- a/hunks/hunks.js
+++ b/hunks/hunks.js
@@ -190,7 +190,7 @@ function State(type, name, startup) {
 
     // from within a hunk, we typically call this
     // to update the value and ship it out to any views
-    this.update = (value) => {
+    this.set = (value) => {
         this.value = value
         this.hookup(this.value)
     }
@@ -200,7 +200,7 @@ function State(type, name, startup) {
     this.change = (value) => {
         // correct, this will by default ring back to 
         // the view, to confirm 
-        this.update(value)
+        this.set(value)
     }
 }
 
diff --git a/hunks/link.js b/hunks/link.js
index 9a213de..8f308a8 100644
--- a/hunks/link.js
+++ b/hunks/link.js
@@ -57,6 +57,7 @@ function Link() {
     // the outputs that we pull but can't send
 
     this.loop = () => {
+        /*
         // WELL ! wrapping it up
         // this is a fun problem, keep going 
         // need to be careful about sequencing here. 
@@ -119,6 +120,7 @@ function Link() {
         }
 
         // now check for 
+        */
     }
 }
 
diff --git a/hunks/manager.js b/hunks/manager.js
index 3fcdacd..0c6db3f 100644
--- a/hunks/manager.js
+++ b/hunks/manager.js
@@ -427,7 +427,7 @@ function Manager() {
                     reject(new Error('mysterious array handling inside of program load'))
                 }
             }).fail((err) => {
-                console.log('program load fails at server request')
+                console.log('program load fails at jquery get request', err)
                 reject(new Error('program load fails at server request', err))
             })
         })
diff --git a/programs/wstest.json b/programs/wstest.json
new file mode 100644
index 0000000..ec0f5ae
--- /dev/null
+++ b/programs/wstest.json
@@ -0,0 +1,39 @@
+{
+    "programname": "wstest",
+    "hunks": [
+    {
+        "name": "input/string",
+        "id": "strng"
+    },
+    {
+        "name": "interface/logger",
+        "id": "lg"
+    },
+    {
+        "name": "interface/logger",
+        "id": "lgws"
+    },
+    {
+        "name": "comm/websocketclient",
+        "id": "WSONE_ONE"
+    }],
+    "links": [
+    {
+        "outhunk": "strng",
+        "outname": "string",
+        "inhunk": "lg",
+        "inname": "tolog"
+    },
+    {
+        "outhunk": "strng",
+        "outname": "string",
+        "inhunk": "WSONE_ONE",
+        "inname": "bytes"
+    },
+    {
+        "outhunk": "WSONE_ONE",
+        "outname": "bytes",
+        "inhunk": "lgws",
+        "inname": "tolog"
+    }]
+}
\ No newline at end of file
diff --git a/style.css b/style.css
index 1d14534..3977c35 100644
--- a/style.css
+++ b/style.css
@@ -112,8 +112,8 @@ body {
 	font-size: 15px;
 	font-weight: bold;
 	font-style: italic;
-	padding-left:89px;
-	padding-right: 89px;
+	padding-left:5px;
+	padding-right: 5px;
 	padding-top: 7px;
 	padding-bottom: 7px;
 	color: #eee;
-- 
GitLab