wiki-plugin-mech 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client/mech.js CHANGED
@@ -36,9 +36,9 @@
36
36
  for (part of more) {
37
37
  const key = `${unique}.${path.join('.')}`
38
38
  part.key = key
39
- if(part.command)
39
+ if('command' in part)
40
40
  html.push(`<span id=${key}>${expand(part.command)}</span>`)
41
- else if(typeof part == 'array')
41
+ else
42
42
  html.push(`<div id=${key} style="padding-left:15px">${block(part,[...path,0])}</div> `)
43
43
  path[path.length-1]++
44
44
  }
@@ -48,52 +48,102 @@
48
48
  }
49
49
 
50
50
  function trouble(elem,message) {
51
+ if(elem.innerText.match(/✖︎/)) return
51
52
  elem.innerHTML += `<button style="border-width:0;color:red;">✖︎</button>`
52
53
  elem.querySelector('button').addEventListener('click',event => {
53
54
  elem.outerHTML += `<span style="width:80%;color:gray;">${message}</span>` })
54
55
  }
55
56
 
56
- function click_emit (elem) {
57
+ function click_emit ({elem,body,state}) {
57
58
  if(elem.innerHTML.match(/button/)) return
58
- const body = this
59
- if (!body.length) return trouble(elem,'CLICK expects indented blocks to follow.')
59
+ if (!body?.length) return trouble(elem,'CLICK expects indented blocks to follow.')
60
60
  elem.innerHTML += '<button style="border-width:0;">◉</button>'
61
- elem.querySelector('button').addEventListener('click',event => run(this))
61
+ elem.querySelector('button').addEventListener('click',event => {
62
+ state.debug = event.shiftKey
63
+ run(body,state)
64
+ })
62
65
  }
63
66
 
64
- function click_bind (elem) {
65
- }
66
-
67
- function hello_emit (elem,what) {
68
- const want = what == 'world' ? ' 🌎' : ' 😀'
67
+ function hello_emit ({elem,args}) {
68
+ const want = args[0] == 'world' ? ' 🌎' : ' 😀'
69
69
  elem.innerHTML += want
70
70
  }
71
71
 
72
- function hello_bind (elem) {
72
+ function from_emit ({elem,args,body,state}) {
73
+ const line = elem.innerHTML
74
+ elem.innerHTML = line + ' ⏳'
75
+ fetch(`//${args[0]}.json`)
76
+ .then(res => res.json())
77
+ .then(page => {
78
+ state.page = page
79
+ elem.innerHTML = line + ' ⌛'
80
+ run(body,state)
81
+ })
82
+ }
83
+
84
+ function sensor_emit ({elem,args,body,state}) {
85
+ const line = elem.innerHTML.replaceAll(/ ⌛/g,'')
86
+ if(!('page' in state)) return trouble(elem,`Expect "page" as with FROM.`)
87
+ const datalog = state.page.story.find(item => item.type == 'datalog')
88
+ if(!datalog) return trouble(elem, `Expect Datalog plugin in the page.`)
89
+ const want = args[0]
90
+ if(!want) return trouble(elem, 'SENSOR needs a sensor name.')
91
+ const sensor = datalog.text.split(/\n/)
92
+ .map(line => line.split(/ +/))
93
+ .filter(fields => fields[0] == 'SENSOR')
94
+ .find(fields => fields[1] == want)
95
+ if(!sensor) return trouble(elem, `Expect to find "${want}" in Datalog.`)
96
+ const url = sensor[2]
97
+
98
+ const f = c => 9/5*(c/16)+32
99
+ const avg = a => a.reduce((s,e)=>s+e,0)/a.length
100
+ elem.innerHTML = line + ' ⏳'
101
+ fetch(url)
102
+ .then (res => res.json())
103
+ .then (data => {
104
+ if(state.debug) console.log({sensor,data})
105
+ elem.innerHTML = line + ' ⌛'
106
+ const value = f(avg(Object.values(data)))
107
+ state.temperature = `${value.toFixed(2)}°F`
108
+ run(body,state)
109
+ })
110
+ }
111
+
112
+ function report_emit ({elem,command,state}) {
113
+ const value = state?.temperature
114
+ if (!value) return trouble(elem,`Expect data, as from SENSOR.`)
115
+ elem.innerHTML = command + `<br><font face=Arial size=32>${value}</font>`
73
116
  }
74
117
 
75
118
  const blocks = {
76
- CLICK: {emit:click_emit, bind:click_bind},
77
- HELLO: {emit:hello_emit, bind:hello_bind}
119
+ CLICK: {emit:click_emit, bind:null},
120
+ HELLO: {emit:hello_emit, bind:null},
121
+ FROM: {emit:from_emit, bind:null},
122
+ SENSOR: {emit:sensor_emit, bind:null},
123
+ REPORT: {emit:report_emit, bind:null}
78
124
  }
79
125
 
80
- function run (nest) {
126
+ function run (nest,state={}) {
81
127
  const scope = nest.slice()
82
128
  while (scope.length) {
83
129
  const code = scope.shift()
84
- if (code.command) {
130
+ if ('command' in code) {
131
+ const command = code.command
85
132
  const elem = document.getElementById(code.key)
86
133
  const [op, ...args] = code.command.split(/ +/)
87
- const more = scope[0]?.command ? null : scope.shift()
134
+ const next = scope[0]
135
+ const body = next && ('command' in next) ? null : scope.shift()
136
+ const stuff = {command,op,args,body,elem,state}
137
+ if(state.debug) console.log(stuff)
88
138
  if (blocks[op])
89
- blocks[op].emit.apply(more||[],[elem,...args])
139
+ blocks[op].emit.apply(null,[stuff])
90
140
  else
91
141
  if (op.match(/^[A-Z]+$/))
92
142
  trouble(elem,`${op} doesn't name a block we know.`)
93
143
  else if (code.command.match(/\S/))
94
144
  trouble(elem, `Expected line to begin with all-caps keyword.`)
95
145
  } else if(typeof code == 'array') {
96
- run(code)
146
+ run(code,state)
97
147
  }
98
148
  }
99
149
  }
package/factory.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "Mech",
3
- "title": "Mech Plugin",
3
+ "title": "Script Mechanisms",
4
4
  "category": "other"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wiki-plugin-mech",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Federated Wiki - Mechanism Scripting Plugin",
5
5
  "keywords": [
6
6
  "mech",