wiki-plugin-mech 0.1.13 → 0.1.15
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 +63 -23
- package/package.json +1 -1
package/client/mech.js
CHANGED
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
function run (nest,state={},mock) {
|
|
86
|
+
async function run (nest,state={},mock) {
|
|
87
87
|
const scope = nest.slice()
|
|
88
88
|
while (scope.length) {
|
|
89
89
|
const code = scope.shift()
|
|
@@ -96,14 +96,15 @@
|
|
|
96
96
|
const stuff = {command,op,args,body,elem,state}
|
|
97
97
|
if(state.debug) console.log(stuff)
|
|
98
98
|
if (blocks[op])
|
|
99
|
-
blocks[op].emit.apply(null,[stuff])
|
|
99
|
+
await blocks[op].emit.apply(null,[stuff])
|
|
100
100
|
else
|
|
101
101
|
if (op.match(/^[A-Z]+$/))
|
|
102
102
|
trouble(elem,`${op} doesn't name a block we know.`)
|
|
103
103
|
else if (code.command.match(/\S/))
|
|
104
104
|
trouble(elem, `Expected line to begin with all-caps keyword.`)
|
|
105
105
|
} else if(typeof code == 'array') {
|
|
106
|
-
|
|
106
|
+
console.warn(`this can't happen.`)
|
|
107
|
+
run(code,state) // when does this even happen?
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
}
|
|
@@ -113,7 +114,7 @@
|
|
|
113
114
|
|
|
114
115
|
function click_emit ({elem,body,state}) {
|
|
115
116
|
if(elem.innerHTML.match(/button/)) return
|
|
116
|
-
if (!body?.length) return trouble(elem
|
|
117
|
+
if (!body?.length) return trouble(elem,`CLICK expects indented blocks to follow.`)
|
|
117
118
|
elem.innerHTML += '<button style="border-width:0;">▶</button>'
|
|
118
119
|
elem.querySelector('button').addEventListener('click',event => {
|
|
119
120
|
state.debug = event.shiftKey
|
|
@@ -122,16 +123,17 @@
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
function hello_emit ({elem,args,state}) {
|
|
125
|
-
const
|
|
126
|
+
const world = args[0] == 'world' ? ' 🌎' : ' 😀'
|
|
126
127
|
for (const key of Object.keys(state))
|
|
127
128
|
inspect(elem,key,state)
|
|
128
|
-
elem.innerHTML +=
|
|
129
|
+
elem.innerHTML += world
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
function from_emit ({elem,args,body,state}) {
|
|
132
133
|
const line = elem.innerHTML
|
|
134
|
+
const url = args[0]
|
|
133
135
|
elem.innerHTML = line + ' ⏳'
|
|
134
|
-
fetch(`//${
|
|
136
|
+
fetch(`//${url}.json`)
|
|
135
137
|
.then(res => res.json())
|
|
136
138
|
.then(page => {
|
|
137
139
|
state.page = page
|
|
@@ -146,13 +148,13 @@
|
|
|
146
148
|
inspect(elem,'page',state)
|
|
147
149
|
const datalog = state.page.story.find(item => item.type == 'datalog')
|
|
148
150
|
if(!datalog) return trouble(elem, `Expect Datalog plugin in the page.`)
|
|
149
|
-
const
|
|
150
|
-
if(!
|
|
151
|
+
const device = args[0]
|
|
152
|
+
if(!device) return trouble(elem, `SENSOR needs a sensor name.`)
|
|
151
153
|
const sensor = datalog.text.split(/\n/)
|
|
152
154
|
.map(line => line.split(/ +/))
|
|
153
155
|
.filter(fields => fields[0] == 'SENSOR')
|
|
154
|
-
.find(fields => fields[1] ==
|
|
155
|
-
if(!sensor) return trouble(elem, `Expect to find "${
|
|
156
|
+
.find(fields => fields[1] == device)
|
|
157
|
+
if(!sensor) return trouble(elem, `Expect to find "${device}" in Datalog.`)
|
|
156
158
|
const url = sensor[2]
|
|
157
159
|
|
|
158
160
|
const f = c => 9/5*(c/16)+32
|
|
@@ -192,6 +194,10 @@
|
|
|
192
194
|
.join(", ")
|
|
193
195
|
if (state.debug) console.log({topic,sources})
|
|
194
196
|
elem.innerHTML = command + ' ⇒ ' + counts
|
|
197
|
+
// state.assets = ?
|
|
198
|
+
// state.aspect = ?
|
|
199
|
+
// state.region = ?
|
|
200
|
+
// state.marker = ?
|
|
195
201
|
state[topic] = sources.map(({div,result}) => ({id:div.dataset.id, result}))
|
|
196
202
|
if (body) run(body,state)
|
|
197
203
|
}
|
|
@@ -199,8 +205,9 @@
|
|
|
199
205
|
function preview_emit ({elem,command,args,state}) {
|
|
200
206
|
const round = digits => (+digits).toFixed(7)
|
|
201
207
|
const story = []
|
|
202
|
-
|
|
203
|
-
|
|
208
|
+
const types = args
|
|
209
|
+
for (const type of types) {
|
|
210
|
+
switch (type) {
|
|
204
211
|
case 'map':
|
|
205
212
|
if(!('marker' in state)) return trouble(elem,`"map" preview expects "marker" state, like from "SOURCE marker".`)
|
|
206
213
|
inspect(elem,'marker',state)
|
|
@@ -234,7 +241,7 @@
|
|
|
234
241
|
story.push({type:'paragraph',text})}
|
|
235
242
|
break
|
|
236
243
|
default:
|
|
237
|
-
return trouble(elem,`"${
|
|
244
|
+
return trouble(elem,`"${type}" doesn't name an item we can preview`)
|
|
238
245
|
}
|
|
239
246
|
}
|
|
240
247
|
const title = "Mech Preview" + (state.tick ? ` ${state.tick}` : '')
|
|
@@ -264,7 +271,7 @@
|
|
|
264
271
|
elem.innerHTML = command
|
|
265
272
|
const nodes = aspects.map(({graph}) => graph.nodes).flat()
|
|
266
273
|
elem.innerHTML += ` ⇒ ${aspects.length} aspects, ${nodes.length} nodes`
|
|
267
|
-
if(steps.find(({graph}) => !graph)) trouble(elem
|
|
274
|
+
if(steps.find(({graph}) => !graph)) trouble(elem,`WALK skipped sites with no links in sitemaps`)
|
|
268
275
|
const item = elem.closest('.item')
|
|
269
276
|
item.classList.add('aspect-source')
|
|
270
277
|
item.aspectData = () => aspects
|
|
@@ -273,9 +280,9 @@
|
|
|
273
280
|
|
|
274
281
|
function tick_emit ({elem,args,body,state}) {
|
|
275
282
|
if(elem.innerHTML.match(/button/)) return
|
|
276
|
-
if (!body?.length) return trouble(elem
|
|
283
|
+
if (!body?.length) return trouble(elem,`TICK expects indented blocks to follow.`)
|
|
277
284
|
const count = args[0] || '1'
|
|
278
|
-
if (!count.match(/^[1-9][0-9]?$/)) return trouble(elem
|
|
285
|
+
if (!count.match(/^[1-9][0-9]?$/)) return trouble(elem,`TICK expects a count from 1 to 99`)
|
|
279
286
|
let clock = null
|
|
280
287
|
elem.innerHTML += '<button style="border-width:0;">▶</button>'
|
|
281
288
|
elem.querySelector('button').addEventListener('click',event => {
|
|
@@ -319,14 +326,16 @@
|
|
|
319
326
|
function forward_emit ({elem,command,args,state}) {
|
|
320
327
|
if(args.length < 1) return trouble(elem,`FORWARD expects an argument, the number of steps to move a "turtle".`)
|
|
321
328
|
if(!('turtle' in state)) state.turtle = new Turtle(elem)
|
|
322
|
-
const
|
|
329
|
+
const steps = args[0]
|
|
330
|
+
const position = state.turtle.forward(+steps)
|
|
323
331
|
elem.innerHTML = command + ` ⇒ ${position.map(n => (n-200).toFixed(1)).join(', ')}`
|
|
324
332
|
}
|
|
325
333
|
|
|
326
334
|
function turn_emit ({elem,command,args,state}) {
|
|
327
335
|
if(args.length < 1) return trouble(elem,`TURN expects an argument, the number of degrees to turn a "turtle".`)
|
|
328
336
|
if(!('turtle' in state)) state.turtle = new Turtle(elem)
|
|
329
|
-
const
|
|
337
|
+
const degrees = args[0]
|
|
338
|
+
const direction = state.turtle.turn(+degrees)
|
|
330
339
|
elem.innerHTML = command + ` ⇒ ${direction}°`
|
|
331
340
|
}
|
|
332
341
|
|
|
@@ -437,9 +446,10 @@
|
|
|
437
446
|
return trouble(elem,`SHOW expects a slug or site/slug to open in the lineup.`)
|
|
438
447
|
}
|
|
439
448
|
} else {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
449
|
+
const info = args[0]
|
|
450
|
+
[site,slug] = info.includes('/')
|
|
451
|
+
? info.split(/\//)
|
|
452
|
+
: [null,info]
|
|
443
453
|
}
|
|
444
454
|
const lineup = [...document.querySelectorAll('.page')].map(e => e.id)
|
|
445
455
|
if(lineup.includes(slug)) return trouble(elem,`SHOW expects a page not already in the lineup.`)
|
|
@@ -457,6 +467,34 @@
|
|
|
457
467
|
state.info = infos[one]
|
|
458
468
|
}
|
|
459
469
|
|
|
470
|
+
function sleep_emit({elem,command,args,body,state}) {
|
|
471
|
+
let count = args[0] || '1'
|
|
472
|
+
if (!count.match(/^[1-9][0-9]?$/)) return trouble(elem,`SLEEP expects seconds from 1 to 99`)
|
|
473
|
+
return new Promise(resolve => {
|
|
474
|
+
if(body)
|
|
475
|
+
run(body,state)
|
|
476
|
+
.then(result => {if(state.debug) console.log(command,'children', result)})
|
|
477
|
+
elem.innerHTML = command + ` ⇒ ${count} remain`
|
|
478
|
+
let clock = setInterval(()=> {
|
|
479
|
+
if(--count > 0)
|
|
480
|
+
elem.innerHTML = command + ` ⇒ ${count} remain`
|
|
481
|
+
else {
|
|
482
|
+
clearInterval(clock)
|
|
483
|
+
elem.innerHTML = command + ` ⇒ done`
|
|
484
|
+
if(state.debug) console.log(command, 'done')
|
|
485
|
+
resolve()
|
|
486
|
+
}
|
|
487
|
+
}, 1000)
|
|
488
|
+
})
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
function together_emit({elem,command,args,body,state}) {
|
|
492
|
+
if (!body) return trouble(elem,`TOGETHER expects indented commands to run together.`)
|
|
493
|
+
const children = body
|
|
494
|
+
.map(child => run([child],state))
|
|
495
|
+
return Promise.all(children)
|
|
496
|
+
}
|
|
497
|
+
|
|
460
498
|
|
|
461
499
|
// C A T A L O G
|
|
462
500
|
|
|
@@ -477,7 +515,9 @@
|
|
|
477
515
|
FILE: {emit:file_emit},
|
|
478
516
|
KWIC: {emit:kwic_emit},
|
|
479
517
|
SHOW: {emit:show_emit},
|
|
480
|
-
RANDOM: {emit:random_emit}
|
|
518
|
+
RANDOM: {emit:random_emit},
|
|
519
|
+
SLEEP: {emit:sleep_emit},
|
|
520
|
+
TOGETHER:{emit:together_emit}
|
|
481
521
|
}
|
|
482
522
|
|
|
483
523
|
|