wiki-plugin-mech 0.1.15 → 0.1.17
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 +47 -4
- package/package.json +1 -1
- package/server/server.js +85 -3
package/client/mech.js
CHANGED
|
@@ -237,8 +237,8 @@
|
|
|
237
237
|
story.push(...state.items)
|
|
238
238
|
break
|
|
239
239
|
case 'synopsis':
|
|
240
|
-
{const text = `This page
|
|
241
|
-
story.push({type:'paragraph',text})}
|
|
240
|
+
{const text = `This page created with Mech command: "${command}". See [[${state.context.title}]].`
|
|
241
|
+
story.push({type:'paragraph',text,id:state.context.itemId})}
|
|
242
242
|
break
|
|
243
243
|
default:
|
|
244
244
|
return trouble(elem,`"${type}" doesn't name an item we can preview`)
|
|
@@ -246,6 +246,10 @@
|
|
|
246
246
|
}
|
|
247
247
|
const title = "Mech Preview" + (state.tick ? ` ${state.tick}` : '')
|
|
248
248
|
const page = {title,story}
|
|
249
|
+
for (const item of page.story) item.id ||= (Math.random()*10**20).toFixed(0)
|
|
250
|
+
const item = JSON.parse(JSON.stringify(page))
|
|
251
|
+
const date = Date.now()
|
|
252
|
+
page.journal = [{type:'create', date, item}]
|
|
249
253
|
const options = {$page:$(elem.closest('.page'))}
|
|
250
254
|
wiki.showResult(wiki.newPage(page), options)
|
|
251
255
|
}
|
|
@@ -495,6 +499,32 @@
|
|
|
495
499
|
return Promise.all(children)
|
|
496
500
|
}
|
|
497
501
|
|
|
502
|
+
// http://localhost:3000/plugin/mech/run/testing-mechs-synchronization/5e269010fc81aebe?args=WyJoZWxsbyIsIndvcmxkIl0
|
|
503
|
+
async function get_emit({elem,command,args,body,state}) {
|
|
504
|
+
if (!body) return trouble(elem,`GET expects indented commands to run on the server.`)
|
|
505
|
+
const site = state.context.site
|
|
506
|
+
const slug = state.context.slug
|
|
507
|
+
const itemId = state.context.itemId
|
|
508
|
+
const query = `args=${btoa(JSON.stringify(body))}`
|
|
509
|
+
const url = `//${site}/plugin/mech/run/${slug}/${itemId}?${query}`
|
|
510
|
+
elem.innerHTML = command + ` ⇒ in progress`
|
|
511
|
+
const start = Date.now()
|
|
512
|
+
let result
|
|
513
|
+
try {
|
|
514
|
+
result = await fetch(url).then(res => res.ok ? res.json() : res.status)
|
|
515
|
+
} catch(err) {
|
|
516
|
+
return trouble(elem,`RUN failed with "${err.message}"`)
|
|
517
|
+
}
|
|
518
|
+
state.result = result
|
|
519
|
+
for(const arg of result.args.flat(9)){
|
|
520
|
+
const elem = document.getElementById(arg.key)
|
|
521
|
+
if('status' in arg) elem.innerHTML = arg.command + ` ⇒ ${arg.status}`
|
|
522
|
+
if('trouble' in arg) trouble(elem,arg.trouble)
|
|
523
|
+
}
|
|
524
|
+
const elapsed = ((Date.now() - start)/1000).toFixed(3)
|
|
525
|
+
elem.innerHTML = command + ` ⇒ ${elapsed} seconds`
|
|
526
|
+
}
|
|
527
|
+
|
|
498
528
|
|
|
499
529
|
// C A T A L O G
|
|
500
530
|
|
|
@@ -517,7 +547,8 @@
|
|
|
517
547
|
SHOW: {emit:show_emit},
|
|
518
548
|
RANDOM: {emit:random_emit},
|
|
519
549
|
SLEEP: {emit:sleep_emit},
|
|
520
|
-
TOGETHER:{emit:together_emit}
|
|
550
|
+
TOGETHER:{emit:together_emit},
|
|
551
|
+
GET: {emit:get_emit}
|
|
521
552
|
}
|
|
522
553
|
|
|
523
554
|
|
|
@@ -527,7 +558,19 @@
|
|
|
527
558
|
const lines = item.text.split(/\n/)
|
|
528
559
|
const nest = tree(lines,[],0)
|
|
529
560
|
const html = format(nest)
|
|
530
|
-
const
|
|
561
|
+
const $page = $item.parents('.page')
|
|
562
|
+
const pageKey = $page.data("key")
|
|
563
|
+
const context = {
|
|
564
|
+
item,
|
|
565
|
+
itemId: item.id,
|
|
566
|
+
pageKey,
|
|
567
|
+
page: wiki.lineup.atKey(pageKey).getRawPage(),
|
|
568
|
+
origin: window.origin,
|
|
569
|
+
site: $page.data("site") || window.location.host,
|
|
570
|
+
slug: $page.attr("id"),
|
|
571
|
+
title: $page.data("data").title,
|
|
572
|
+
}
|
|
573
|
+
const state = {context}
|
|
531
574
|
$item.append(`<div style="background-color:#eee;padding:15px;border-top:8px;">${html}</div>`)
|
|
532
575
|
run(nest,state)
|
|
533
576
|
}
|
package/package.json
CHANGED
package/server/server.js
CHANGED
|
@@ -1,17 +1,99 @@
|
|
|
1
1
|
// mech plugin, server-side component
|
|
2
2
|
// These handlers are launched with the wiki server.
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
(function() {
|
|
6
|
+
|
|
7
|
+
const fs = require('fs')
|
|
8
|
+
const process = require('process')
|
|
9
|
+
|
|
5
10
|
function startServer(params) {
|
|
6
11
|
var app = params.app,
|
|
7
12
|
argv = params.argv
|
|
8
13
|
|
|
9
|
-
return app.get('/plugin/mech/:
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
return app.get('/plugin/mech/run/:slug([a-z-]+)/:itemId', async (req, res) => {
|
|
15
|
+
console.log(req.params)
|
|
16
|
+
try {
|
|
17
|
+
const slug = req.params.slug
|
|
18
|
+
const itemId = req.params.itemId
|
|
19
|
+
const args = JSON.parse(atob(req.query.args || 'W10='))
|
|
20
|
+
const path = `${argv.db}/${slug}`
|
|
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}
|
|
28
|
+
run(args,state)
|
|
29
|
+
return res.json({args,state})
|
|
30
|
+
|
|
31
|
+
} catch(err) {
|
|
32
|
+
return res.json({err:err.message})
|
|
33
|
+
}
|
|
12
34
|
})
|
|
13
35
|
}
|
|
14
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
|
+
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
|
|
77
|
+
|
|
78
|
+
function hello_emit ({elem,args,state}) {
|
|
79
|
+
const world = args[0] == 'world' ? ' 🌎' : ' 😀'
|
|
80
|
+
status(elem,world)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function uptime_emit ({elem,args,state}) {
|
|
84
|
+
const uptime = process.uptime()
|
|
85
|
+
status(elem,uptime)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
// C A T A L O G
|
|
90
|
+
|
|
91
|
+
const blocks = {
|
|
92
|
+
HELLO: {emit:hello_emit},
|
|
93
|
+
UPTIME: {emit:uptime_emit}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
15
97
|
module.exports = {startServer}
|
|
16
98
|
|
|
17
99
|
}).call(this)
|