wiki-plugin-mech 0.1.16 → 0.1.18
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 +35 -10
- package/package.json +1 -1
- package/server/server.js +85 -8
package/client/mech.js
CHANGED
|
@@ -236,6 +236,11 @@
|
|
|
236
236
|
inspect(elem,'items',state)
|
|
237
237
|
story.push(...state.items)
|
|
238
238
|
break
|
|
239
|
+
case 'page':
|
|
240
|
+
if(!('page' in state)) return trouble(elem,`"page" preview expects "page" state, like from "FROM".`)
|
|
241
|
+
inspect(elem,'page',state)
|
|
242
|
+
story.push(...state.page.story)
|
|
243
|
+
break
|
|
239
244
|
case 'synopsis':
|
|
240
245
|
{const text = `This page created with Mech command: "${command}". See [[${state.context.title}]].`
|
|
241
246
|
story.push({type:'paragraph',text,id:state.context.itemId})}
|
|
@@ -282,30 +287,42 @@
|
|
|
282
287
|
state.aspect = [{id:item.dataset.id,result:aspects}]
|
|
283
288
|
}
|
|
284
289
|
|
|
285
|
-
function tick_emit ({elem,args,body,state}) {
|
|
290
|
+
function tick_emit ({elem,command,args,body,state}) {
|
|
286
291
|
if(elem.innerHTML.match(/button/)) return
|
|
287
292
|
if (!body?.length) return trouble(elem,`TICK expects indented blocks to follow.`)
|
|
288
293
|
const count = args[0] || '1'
|
|
289
294
|
if (!count.match(/^[1-9][0-9]?$/)) return trouble(elem,`TICK expects a count from 1 to 99`)
|
|
290
295
|
let clock = null
|
|
291
|
-
|
|
292
|
-
|
|
296
|
+
ready()
|
|
297
|
+
function ready () {
|
|
298
|
+
elem.innerHTML = command+'<button style="border-width:0;">▶</button>'
|
|
299
|
+
elem.querySelector('button').addEventListener('click',start)
|
|
300
|
+
}
|
|
301
|
+
function start (event) {
|
|
293
302
|
state.debug = event.shiftKey
|
|
303
|
+
const status = ticks => {elem.innerHTML = command + ` ⇒ ${ticks} remaining`}
|
|
294
304
|
if(clock){
|
|
295
305
|
clock = clearInterval(clock)
|
|
296
306
|
delete state.tick
|
|
297
307
|
} else {
|
|
308
|
+
let working
|
|
298
309
|
state.tick = +count
|
|
299
|
-
|
|
310
|
+
status(state.tick)
|
|
311
|
+
working = true; run(body,state).then(() => working = false)
|
|
300
312
|
clock = setInterval(()=>{
|
|
313
|
+
if(working) return
|
|
301
314
|
if(state.debug) console.log({tick:state.tick})
|
|
302
|
-
if(('tick' in state) && --state.tick > 0)
|
|
303
|
-
|
|
304
|
-
|
|
315
|
+
if(('tick' in state) && --state.tick > 0) {
|
|
316
|
+
status(state.tick)
|
|
317
|
+
working = true; run(body,state).then(() => working = false)
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
305
320
|
clock = clearInterval(clock)
|
|
321
|
+
ready()
|
|
322
|
+
}
|
|
306
323
|
},1000)
|
|
307
324
|
}
|
|
308
|
-
}
|
|
325
|
+
}
|
|
309
326
|
}
|
|
310
327
|
|
|
311
328
|
function until_emit ({elem,command,args,body,state}) {
|
|
@@ -450,7 +467,7 @@
|
|
|
450
467
|
return trouble(elem,`SHOW expects a slug or site/slug to open in the lineup.`)
|
|
451
468
|
}
|
|
452
469
|
} else {
|
|
453
|
-
const info = args[0]
|
|
470
|
+
const info = args[0];
|
|
454
471
|
[site,slug] = info.includes('/')
|
|
455
472
|
? info.split(/\//)
|
|
456
473
|
: [null,info]
|
|
@@ -509,11 +526,19 @@
|
|
|
509
526
|
const url = `//${site}/plugin/mech/run/${slug}/${itemId}?${query}`
|
|
510
527
|
elem.innerHTML = command + ` ⇒ in progress`
|
|
511
528
|
const start = Date.now()
|
|
529
|
+
let result
|
|
512
530
|
try {
|
|
513
|
-
|
|
531
|
+
result = await fetch(url).then(res => res.ok ? res.json() : res.status)
|
|
532
|
+
if('err' in result) return trouble(elem,`RUN received error "${result.err}"`)
|
|
514
533
|
} catch(err) {
|
|
515
534
|
return trouble(elem,`RUN failed with "${err.message}"`)
|
|
516
535
|
}
|
|
536
|
+
state.result = result
|
|
537
|
+
for(const arg of result.args.flat(9)){
|
|
538
|
+
const elem = document.getElementById(arg.key)
|
|
539
|
+
if('status' in arg) elem.innerHTML = arg.command + ` ⇒ ${arg.status}`
|
|
540
|
+
if('trouble' in arg) trouble(elem,arg.trouble)
|
|
541
|
+
}
|
|
517
542
|
const elapsed = ((Date.now() - start)/1000).toFixed(3)
|
|
518
543
|
elem.innerHTML = command + ` ⇒ ${elapsed} seconds`
|
|
519
544
|
}
|
package/package.json
CHANGED
package/server/server.js
CHANGED
|
@@ -11,26 +11,103 @@
|
|
|
11
11
|
var app = params.app,
|
|
12
12
|
argv = params.argv
|
|
13
13
|
|
|
14
|
-
return app.get('/plugin/mech/run/:slug([a-z-]+)/:itemId', (req, res) => {
|
|
14
|
+
return app.get('/plugin/mech/run/:slug([a-z-]+)/:itemId', (req, res, next) => {
|
|
15
15
|
console.log(req.params)
|
|
16
|
-
const uptime = process.uptime()
|
|
17
16
|
try {
|
|
18
17
|
const slug = req.params.slug
|
|
19
18
|
const itemId = req.params.itemId
|
|
20
19
|
const args = JSON.parse(atob(req.query.args || 'W10='))
|
|
21
20
|
const path = `${argv.db}/${slug}`
|
|
22
|
-
fs.readFile(path,(err,data) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
21
|
+
// fs.readFile(path,(err,data) => {
|
|
22
|
+
// const page = JSON.parse(data)
|
|
23
|
+
// const item = page.story.find(item => item.id == itemId) || null
|
|
24
|
+
// return res.json({err,item,args});
|
|
25
|
+
// })
|
|
26
|
+
const context = {path}
|
|
27
|
+
const state = {context,debug:true}
|
|
28
|
+
run(args,state)
|
|
29
|
+
.then(() => {return res.json({args,state})})
|
|
30
|
+
.catch(err => {console.log(err); return res.json({err:err.message+' from promise'})})
|
|
27
31
|
} catch(err) {
|
|
28
|
-
return res.json({err:err.message
|
|
32
|
+
return res.json({err:err.message+' from try'})
|
|
29
33
|
}
|
|
30
34
|
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// I N T E R P R E T E R
|
|
39
|
+
|
|
40
|
+
function status(elem,message) {
|
|
41
|
+
elem.status = message
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function trouble(elem,message) {
|
|
45
|
+
elem.trouble = message
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function run (nest,state={},mock) {
|
|
49
|
+
// const scope = nest.slice()
|
|
50
|
+
// while (scope.length) {
|
|
51
|
+
for (let here = 0; here < nest.length; here++) {
|
|
52
|
+
// const code = scope.shift()
|
|
53
|
+
const code = nest[here]
|
|
54
|
+
if ('command' in code) {
|
|
55
|
+
const command = code.command
|
|
56
|
+
const elem = code
|
|
57
|
+
const [op, ...args] = code.command.split(/ +/)
|
|
58
|
+
const next = nest[here+1]
|
|
59
|
+
const body = next && ('command' in next) ? null : nest[++here]
|
|
60
|
+
const stuff = {command,op,args,body,elem,state}
|
|
61
|
+
if(state.debug) console.log(stuff)
|
|
62
|
+
if (blocks[op])
|
|
63
|
+
await blocks[op].emit.apply(null,[stuff])
|
|
64
|
+
else
|
|
65
|
+
if (op.match(/^[A-Z]+$/))
|
|
66
|
+
trouble(elem,`${op} doesn't name a block we know.`)
|
|
67
|
+
else if (code.command.match(/\S/))
|
|
68
|
+
trouble(elem, `Expected line to begin with all-caps keyword.`)
|
|
69
|
+
} else if(typeof code == 'array') {
|
|
70
|
+
console.warn(`this can't happen.`)
|
|
71
|
+
run(code,state) // when does this even happen?
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// B L O C K S
|
|
31
77
|
|
|
78
|
+
function hello_emit ({elem,args,state}) {
|
|
79
|
+
const world = args[0] == 'world' ? ' 🌎' : ' 😀'
|
|
80
|
+
status(elem,world)
|
|
32
81
|
}
|
|
33
82
|
|
|
83
|
+
function uptime_emit ({elem,args,state}) {
|
|
84
|
+
const uptime = process.uptime()
|
|
85
|
+
status(elem,uptime)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function sleep_emit ({elem,command,args,body,state}) {
|
|
89
|
+
let count = args[0] || '1'
|
|
90
|
+
if (!count.match(/^[1-9][0-9]?$/)) return trouble(elem,`SLEEP expects seconds from 1 to 99`)
|
|
91
|
+
return new Promise(resolve => {
|
|
92
|
+
if(body)
|
|
93
|
+
run(body,state)
|
|
94
|
+
.then(result => {if(state.debug) console.log(command,'children', result)})
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
resolve()
|
|
97
|
+
},1000*count)
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
// C A T A L O G
|
|
103
|
+
|
|
104
|
+
const blocks = {
|
|
105
|
+
HELLO: {emit:hello_emit},
|
|
106
|
+
UPTIME: {emit:uptime_emit},
|
|
107
|
+
SLEEP: {emit:sleep_emit}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
34
111
|
module.exports = {startServer}
|
|
35
112
|
|
|
36
113
|
}).call(this)
|