instaserve 0.0.44 → 0.1.3
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/README.md +31 -2
- package/bun/http.js +45 -0
- package/deno/server.js +35 -0
- package/module.mjs +31 -0
- package/package.json +15 -10
- package/public/enigmatic.js +149 -149
- package/public/index.html +12 -7
- package/public/sw.js +17 -17
- package/routes.mjs +4 -4
- package/server.mjs +21 -48
package/README.md
CHANGED
|
@@ -1,2 +1,31 @@
|
|
|
1
|
-
# instaserve
|
|
2
|
-
Instant web stack
|
|
1
|
+
# instaserve
|
|
2
|
+
Instant web stack
|
|
3
|
+
|
|
4
|
+
> npx instaserve (node)
|
|
5
|
+
Starts a server in the current directory
|
|
6
|
+
Creates a routes.mjs file if none exists
|
|
7
|
+
Create a public folder and add files for static file serving
|
|
8
|
+
|
|
9
|
+
> npm run deno (deno)
|
|
10
|
+
Starts a deno server using routes.mjs and static serving
|
|
11
|
+
|
|
12
|
+
> npm run bun (bun)
|
|
13
|
+
Starts a bun server
|
|
14
|
+
|
|
15
|
+
###Script usage
|
|
16
|
+
````
|
|
17
|
+
import serve from 'instaserve'
|
|
18
|
+
serve({
|
|
19
|
+
'_log': (r, s) => console.log(r.method, r.url),
|
|
20
|
+
'/api': (r, s, body) => s.end('an api response'),
|
|
21
|
+
})
|
|
22
|
+
````
|
|
23
|
+
|
|
24
|
+
###Routes.mjs file example
|
|
25
|
+
````
|
|
26
|
+
export default {
|
|
27
|
+
_debug: ({ method, url }, s, data) => !console.log(method, url, data),
|
|
28
|
+
_example: (r, s, data) => console.log('returning a falsy value (above) will stop the chain'),
|
|
29
|
+
'/api': (r, s, data) => s.end('an example api response')
|
|
30
|
+
}
|
|
31
|
+
````
|
package/bun/http.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {existsSync} from 'fs'
|
|
2
|
+
import routes from '../routes.mjs'
|
|
3
|
+
console.log(routes)
|
|
4
|
+
|
|
5
|
+
class s {
|
|
6
|
+
end(s) {
|
|
7
|
+
this.resp = s
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
Bun.serve({
|
|
12
|
+
port: 3000,
|
|
13
|
+
async fetch(r) {
|
|
14
|
+
|
|
15
|
+
let url = new URL(r.url).pathname
|
|
16
|
+
const data = await r.text()
|
|
17
|
+
|
|
18
|
+
const ru = {method: r.method, url: url}
|
|
19
|
+
const rs = new s()
|
|
20
|
+
|
|
21
|
+
const midware = Object.keys(routes)
|
|
22
|
+
.filter(k => k.startsWith('_'))
|
|
23
|
+
.find(k => routes[k](ru, rs, data))
|
|
24
|
+
|
|
25
|
+
// Routes.mjs
|
|
26
|
+
if(routes[url]) {
|
|
27
|
+
const f = routes[url](ru, rs, data)
|
|
28
|
+
return new Response(rs.resp)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Static
|
|
32
|
+
const fn = (url == '/') ? `public/index.html` : `public/${url}`
|
|
33
|
+
if (existsSync(fn))
|
|
34
|
+
return new Response(Bun.file(fn))
|
|
35
|
+
|
|
36
|
+
return new Response('', { status: 404 })
|
|
37
|
+
|
|
38
|
+
},
|
|
39
|
+
error(e) {
|
|
40
|
+
console.error(e)
|
|
41
|
+
return new Response('', { status: 404 })
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
console.log('Running on 3000')
|
package/deno/server.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync } from "https://deno.land/std/fs/mod.ts";
|
|
2
|
+
import routes from '../routes.mjs'
|
|
3
|
+
console.log(routes)
|
|
4
|
+
|
|
5
|
+
class s {
|
|
6
|
+
end(s) {
|
|
7
|
+
this.resp = s
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
Deno.serve(async (r) => {
|
|
12
|
+
|
|
13
|
+
const data = await r.text()
|
|
14
|
+
let url = new URL(r.url).pathname
|
|
15
|
+
const ru = { method: r.method, url: url }
|
|
16
|
+
const rs = new s()
|
|
17
|
+
|
|
18
|
+
const midware = Object.keys(routes)
|
|
19
|
+
.filter((k) => k.startsWith('_'))
|
|
20
|
+
.find((k) => routes[k](ru, rs, data))
|
|
21
|
+
|
|
22
|
+
// Routes.mjs
|
|
23
|
+
if (routes[url]) {
|
|
24
|
+
const f = routes[url](ru, rs, data)
|
|
25
|
+
return new Response(rs.resp)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Static
|
|
29
|
+
const fn = (url == '/') ? `public/index.html` : `public/${url}`
|
|
30
|
+
if (existsSync(fn))
|
|
31
|
+
return new Response(await Deno.readTextFile(fn), { headers: { 'Content-Type': 'text/html' } })
|
|
32
|
+
|
|
33
|
+
return new Response('', { status: 404 })
|
|
34
|
+
|
|
35
|
+
}, {port: 3000})
|
package/module.mjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import http from 'node:http'
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
|
|
4
|
+
export default function(routes = {_debug: ({method, url}, s) => console.log(method, url)}, port = 3000) {
|
|
5
|
+
http.createServer(async (r, s) => {
|
|
6
|
+
try {
|
|
7
|
+
let data = ''
|
|
8
|
+
r.on('data', (s) => (data += s.toString()))
|
|
9
|
+
r.on('end', (x) => {
|
|
10
|
+
try {
|
|
11
|
+
data = JSON.parse(data)
|
|
12
|
+
} catch { }
|
|
13
|
+
})
|
|
14
|
+
const midware = Object.keys(routes)
|
|
15
|
+
.filter((k) => k.startsWith('_'))
|
|
16
|
+
.find((k) => routes[k](r, s, data))
|
|
17
|
+
if (r.url == '/') r.url = '/index.html'
|
|
18
|
+
const fn = `./public${r.url.replace('..', '')}`
|
|
19
|
+
if (fs.existsSync(fn)) {
|
|
20
|
+
if (fn.match(/sw\.js/)) s.writeHead(200, { 'Content-Type': 'application/javascript' })
|
|
21
|
+
return s.end(fs.readFileSync(fn, 'utf-8'))
|
|
22
|
+
}
|
|
23
|
+
if (routes[r.url]) return routes[r.url](r, s, data)
|
|
24
|
+
else s.writeHead(404).end()
|
|
25
|
+
} catch (e) {
|
|
26
|
+
console.log(e)
|
|
27
|
+
s.writeHead(404).end()
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
.listen(port, (x) => console.log('listening on ' + port))
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "instaserve",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Instant web stack",
|
|
5
|
-
"main": "
|
|
6
|
-
"bin": "./server.mjs",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"start": "node server.mjs"
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "instaserve",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Instant web stack",
|
|
5
|
+
"main": "module.mjs",
|
|
6
|
+
"bin": "./server.mjs",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node server.mjs",
|
|
9
|
+
"deno": "deno run --unstable --allow-net --allow-read deno/server.js",
|
|
10
|
+
"bun": "bun run bun/http.js"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"instaserve": "^0.1.1"
|
|
14
|
+
}
|
|
15
|
+
}
|
package/public/enigmatic.js
CHANGED
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
const w = {}, d = document
|
|
2
|
-
|
|
3
|
-
// helpers
|
|
4
|
-
|
|
5
|
-
w.$ = d.querySelector.bind(d)
|
|
6
|
-
w.$$ = d.querySelectorAll.bind(d)
|
|
7
|
-
w.loadJS = (src) => {
|
|
8
|
-
return new Promise((r, j) => {
|
|
9
|
-
if ($(`script[src="${src}"]`)) return r(true)
|
|
10
|
-
const s = d.createElement('script')
|
|
11
|
-
s.src = src
|
|
12
|
-
s.addEventListener('load', r)
|
|
13
|
-
d.head.appendChild(s)
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
w.loadCSS = (src) => {
|
|
17
|
-
return new Promise((r, j) => {
|
|
18
|
-
const s = document.createElement('link')
|
|
19
|
-
s.rel = 'stylesheet'
|
|
20
|
-
s.href = src
|
|
21
|
-
s.addEventListener('load', r)
|
|
22
|
-
d.head.appendChild(s)
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
w.wait = (ms) => new Promise((r) => setTimeout(r, ms))
|
|
26
|
-
w.ready = async () => {
|
|
27
|
-
return new Promise((r) => {
|
|
28
|
-
if (document.readyState === 'complete') r(true)
|
|
29
|
-
document.onreadystatechange = () => {
|
|
30
|
-
if (document.readyState === 'complete') r()
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
w.child = (type = 'div', html = '') => {
|
|
35
|
-
const e = d.createElement(type)
|
|
36
|
-
e.innerHTML = html
|
|
37
|
-
d.body.appendChild(e)
|
|
38
|
-
return e
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Custom element
|
|
42
|
-
|
|
43
|
-
w.element = (name, { onMount = x => x, beforeData = x => x, style, template = '' }) => {
|
|
44
|
-
customElements.define(name, class extends HTMLElement {
|
|
45
|
-
async connectedCallback(props) {
|
|
46
|
-
await onMount()
|
|
47
|
-
if (style) {
|
|
48
|
-
const s = document.createElement('style')
|
|
49
|
-
s.innerHTML = `${name} {${style}}`
|
|
50
|
-
d.body.appendChild(s)
|
|
51
|
-
}
|
|
52
|
-
this.template = template
|
|
53
|
-
if (!this.template.match('{'))
|
|
54
|
-
this.innerHTML = this.template
|
|
55
|
-
}
|
|
56
|
-
set(o) {
|
|
57
|
-
this.innerHTML = ''
|
|
58
|
-
o = beforeData(o)
|
|
59
|
-
if (!Array.isArray(o)) o = [o]
|
|
60
|
-
const m = new Function('o', 'return `' + this.template + '`')
|
|
61
|
-
o.map((i) => (this.innerHTML += m(o)))
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (window.components) {
|
|
67
|
-
for (let name in window.components)
|
|
68
|
-
w.element(name, window.components[name])
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Data
|
|
72
|
-
|
|
73
|
-
w.state = new Proxy(
|
|
74
|
-
{}, {
|
|
75
|
-
set: (obj, prop, value) => {
|
|
76
|
-
let ret = []
|
|
77
|
-
for (const e of $$(`[data*=${prop}]`)) {
|
|
78
|
-
console.log(['setting e', e.tagName, e.id, value])
|
|
79
|
-
e.set(value)
|
|
80
|
-
}
|
|
81
|
-
obj[prop] = value
|
|
82
|
-
},
|
|
83
|
-
get: (obj, prop, receiver) => {
|
|
84
|
-
if (prop == '_state') return obj
|
|
85
|
-
return obj[prop]
|
|
86
|
-
},
|
|
87
|
-
}
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
w.dataEvent = (x) => console.log(`dataevent: ${x}`)
|
|
91
|
-
|
|
92
|
-
w.fetchJSON = async (url, key) => {
|
|
93
|
-
const j = await (await fetch(url)).json()
|
|
94
|
-
if (key) state[key] = j
|
|
95
|
-
dataEvent(j)
|
|
96
|
-
return j
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
w.streamJSON = async (url, key) => {
|
|
100
|
-
const ev = new EventSource(url)
|
|
101
|
-
ev.onmessage = (ev) => {
|
|
102
|
-
const j = JSON.parse(ev.data)
|
|
103
|
-
if (key) state[key] = j
|
|
104
|
-
dataEvent(j)
|
|
105
|
-
return j
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// State changes
|
|
110
|
-
|
|
111
|
-
w.trackStateChanges = () =>
|
|
112
|
-
(w.dataEvent = (o) =>
|
|
113
|
-
localStorage.set(new Date().toISOString(), JSON.stringify(o)))
|
|
114
|
-
w.untrackStateChanges = () =>
|
|
115
|
-
(w.dataEvent = (o) => console.log('dataevent:', o))
|
|
116
|
-
|
|
117
|
-
// Startup
|
|
118
|
-
|
|
119
|
-
w.start = async () => {
|
|
120
|
-
await w.ready();
|
|
121
|
-
[...$$('div')].map((e) => {
|
|
122
|
-
if (!e.id)
|
|
123
|
-
e.id = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 3)
|
|
124
|
-
e.pr = {};
|
|
125
|
-
[...e.attributes].map((a) => (e.pr[a.name] = a.value))
|
|
126
|
-
if (e.pr.fetch) e.fetch = fetchJSON.bind(null, e.pr.fetch, e.id)
|
|
127
|
-
if ('immediate' in e.pr) e.fetch()
|
|
128
|
-
if (e.pr.stream) e.stream = streamJSON.bind(null, e.pr.stream, e.id)
|
|
129
|
-
if (e.pr.data) {
|
|
130
|
-
if (e.innerHTML && e.innerHTML.includes('{')) {
|
|
131
|
-
e.template = e.innerHTML.replaceAll('{', '${')
|
|
132
|
-
e.innerHTML = ''
|
|
133
|
-
}
|
|
134
|
-
e.set = (o) => {
|
|
135
|
-
e.innerHTML = ''
|
|
136
|
-
if (!Array.isArray(o)) o = [o]
|
|
137
|
-
const m = new Function('o', 'return `' + e.template + '`')
|
|
138
|
-
o.map((i) => (e.innerHTML += m(i)))
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
})
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
w.enigmatic = { version: '2022-03-05 0.10.2' }
|
|
145
|
-
Object.assign(window, w);
|
|
146
|
-
|
|
147
|
-
(async () => {
|
|
148
|
-
await w.start()
|
|
149
|
-
if (window.main) window.main()
|
|
1
|
+
const w = {}, d = document
|
|
2
|
+
|
|
3
|
+
// helpers
|
|
4
|
+
|
|
5
|
+
w.$ = d.querySelector.bind(d)
|
|
6
|
+
w.$$ = d.querySelectorAll.bind(d)
|
|
7
|
+
w.loadJS = (src) => {
|
|
8
|
+
return new Promise((r, j) => {
|
|
9
|
+
if ($(`script[src="${src}"]`)) return r(true)
|
|
10
|
+
const s = d.createElement('script')
|
|
11
|
+
s.src = src
|
|
12
|
+
s.addEventListener('load', r)
|
|
13
|
+
d.head.appendChild(s)
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
w.loadCSS = (src) => {
|
|
17
|
+
return new Promise((r, j) => {
|
|
18
|
+
const s = document.createElement('link')
|
|
19
|
+
s.rel = 'stylesheet'
|
|
20
|
+
s.href = src
|
|
21
|
+
s.addEventListener('load', r)
|
|
22
|
+
d.head.appendChild(s)
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
w.wait = (ms) => new Promise((r) => setTimeout(r, ms))
|
|
26
|
+
w.ready = async () => {
|
|
27
|
+
return new Promise((r) => {
|
|
28
|
+
if (document.readyState === 'complete') r(true)
|
|
29
|
+
document.onreadystatechange = () => {
|
|
30
|
+
if (document.readyState === 'complete') r()
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
w.child = (type = 'div', html = '') => {
|
|
35
|
+
const e = d.createElement(type)
|
|
36
|
+
e.innerHTML = html
|
|
37
|
+
d.body.appendChild(e)
|
|
38
|
+
return e
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Custom element
|
|
42
|
+
|
|
43
|
+
w.element = (name, { onMount = x => x, beforeData = x => x, style, template = '' }) => {
|
|
44
|
+
customElements.define(name, class extends HTMLElement {
|
|
45
|
+
async connectedCallback(props) {
|
|
46
|
+
await onMount()
|
|
47
|
+
if (style) {
|
|
48
|
+
const s = document.createElement('style')
|
|
49
|
+
s.innerHTML = `${name} {${style}}`
|
|
50
|
+
d.body.appendChild(s)
|
|
51
|
+
}
|
|
52
|
+
this.template = template
|
|
53
|
+
if (!this.template.match('{'))
|
|
54
|
+
this.innerHTML = this.template
|
|
55
|
+
}
|
|
56
|
+
set(o) {
|
|
57
|
+
this.innerHTML = ''
|
|
58
|
+
o = beforeData(o)
|
|
59
|
+
if (!Array.isArray(o)) o = [o]
|
|
60
|
+
const m = new Function('o', 'return `' + this.template + '`')
|
|
61
|
+
o.map((i) => (this.innerHTML += m(o)))
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (window.components) {
|
|
67
|
+
for (let name in window.components)
|
|
68
|
+
w.element(name, window.components[name])
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Data
|
|
72
|
+
|
|
73
|
+
w.state = new Proxy(
|
|
74
|
+
{}, {
|
|
75
|
+
set: (obj, prop, value) => {
|
|
76
|
+
let ret = []
|
|
77
|
+
for (const e of $$(`[data*=${prop}]`)) {
|
|
78
|
+
console.log(['setting e', e.tagName, e.id, value])
|
|
79
|
+
e.set(value)
|
|
80
|
+
}
|
|
81
|
+
obj[prop] = value
|
|
82
|
+
},
|
|
83
|
+
get: (obj, prop, receiver) => {
|
|
84
|
+
if (prop == '_state') return obj
|
|
85
|
+
return obj[prop]
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
w.dataEvent = (x) => console.log(`dataevent: ${x}`)
|
|
91
|
+
|
|
92
|
+
w.fetchJSON = async (url, key) => {
|
|
93
|
+
const j = await (await fetch(url)).json()
|
|
94
|
+
if (key) state[key] = j
|
|
95
|
+
dataEvent(j)
|
|
96
|
+
return j
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
w.streamJSON = async (url, key) => {
|
|
100
|
+
const ev = new EventSource(url)
|
|
101
|
+
ev.onmessage = (ev) => {
|
|
102
|
+
const j = JSON.parse(ev.data)
|
|
103
|
+
if (key) state[key] = j
|
|
104
|
+
dataEvent(j)
|
|
105
|
+
return j
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// State changes
|
|
110
|
+
|
|
111
|
+
w.trackStateChanges = () =>
|
|
112
|
+
(w.dataEvent = (o) =>
|
|
113
|
+
localStorage.set(new Date().toISOString(), JSON.stringify(o)))
|
|
114
|
+
w.untrackStateChanges = () =>
|
|
115
|
+
(w.dataEvent = (o) => console.log('dataevent:', o))
|
|
116
|
+
|
|
117
|
+
// Startup
|
|
118
|
+
|
|
119
|
+
w.start = async () => {
|
|
120
|
+
await w.ready();
|
|
121
|
+
[...$$('div')].map((e) => {
|
|
122
|
+
if (!e.id)
|
|
123
|
+
e.id = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 3)
|
|
124
|
+
e.pr = {};
|
|
125
|
+
[...e.attributes].map((a) => (e.pr[a.name] = a.value))
|
|
126
|
+
if (e.pr.fetch) e.fetch = fetchJSON.bind(null, e.pr.fetch, e.id)
|
|
127
|
+
if ('immediate' in e.pr) e.fetch()
|
|
128
|
+
if (e.pr.stream) e.stream = streamJSON.bind(null, e.pr.stream, e.id)
|
|
129
|
+
if (e.pr.data) {
|
|
130
|
+
if (e.innerHTML && e.innerHTML.includes('{')) {
|
|
131
|
+
e.template = e.innerHTML.replaceAll('{', '${')
|
|
132
|
+
e.innerHTML = ''
|
|
133
|
+
}
|
|
134
|
+
e.set = (o) => {
|
|
135
|
+
e.innerHTML = ''
|
|
136
|
+
if (!Array.isArray(o)) o = [o]
|
|
137
|
+
const m = new Function('o', 'return `' + e.template + '`')
|
|
138
|
+
o.map((i) => (e.innerHTML += m(i)))
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
w.enigmatic = { version: '2022-03-05 0.10.2' }
|
|
145
|
+
Object.assign(window, w);
|
|
146
|
+
|
|
147
|
+
(async () => {
|
|
148
|
+
await w.start()
|
|
149
|
+
if (window.main) window.main()
|
|
150
150
|
})()
|
package/public/index.html
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<script>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<script src="enigmatic.js"></script>
|
|
3
|
+
|
|
4
|
+
<script>
|
|
5
|
+
// navigator.serviceWorker.register('sw.js')
|
|
6
|
+
</script>
|
|
7
|
+
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css'>
|
|
8
|
+
|
|
9
|
+
<div class='bg-yellow-200'>hello</div>
|
|
10
|
+
<script>
|
|
11
|
+
document.write(enigmatic.version)
|
|
12
|
+
</script>
|
package/public/sw.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
self.addEventListener('fetch', event => {
|
|
2
|
-
const cache = await caches.open('e')
|
|
3
|
-
const req = event.request
|
|
4
|
-
|
|
5
|
-
event.respondWith(async () => {
|
|
6
|
-
if(!req.url.match(/\.js$|\.css$/))
|
|
7
|
-
return fetch(req)
|
|
8
|
-
|
|
9
|
-
const response = await cache.match(req)
|
|
10
|
-
if(response) return response
|
|
11
|
-
response = await fetch(req)
|
|
12
|
-
|
|
13
|
-
if(response.status == 200)
|
|
14
|
-
cache.put(req, response)
|
|
15
|
-
|
|
16
|
-
return response
|
|
17
|
-
})
|
|
1
|
+
self.addEventListener('fetch', event => {
|
|
2
|
+
const cache = await caches.open('e')
|
|
3
|
+
const req = event.request
|
|
4
|
+
|
|
5
|
+
event.respondWith(async () => {
|
|
6
|
+
if(!req.url.match(/\.js$|\.css$/))
|
|
7
|
+
return fetch(req)
|
|
8
|
+
|
|
9
|
+
const response = await cache.match(req)
|
|
10
|
+
if(response) return response
|
|
11
|
+
response = await fetch(req)
|
|
12
|
+
|
|
13
|
+
if(response.status == 200)
|
|
14
|
+
cache.put(req, response)
|
|
15
|
+
|
|
16
|
+
return response
|
|
17
|
+
})
|
|
18
18
|
})
|
package/routes.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
_debug: ({ method, url }, s, data) => !console.log(method, url, data),
|
|
3
|
+
_example: (r, s, data) => console.log('returning a falsy value (above) will stop the chain'),
|
|
4
|
+
'/api': (r, s, data) => s.end('an example api response')
|
|
5
|
+
}
|
package/server.mjs
CHANGED
|
@@ -1,48 +1,21 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import { pathToFileURL } from 'node:url'
|
|
5
|
-
import { resolve } from 'node:path'
|
|
6
|
-
import fs from 'node:fs'
|
|
7
|
-
|
|
8
|
-
const routesfile = resolve('routes.mjs')
|
|
9
|
-
|
|
10
|
-
if (!fs.existsSync(routesfile)) {
|
|
11
|
-
fs.writeFileSync(routesfile, `export default {
|
|
12
|
-
_debug: ({method, url}, s) => !console.log(method, url),
|
|
13
|
-
_example: (r, s) => console.log('returning a falsy value (above) will stop the chain'),
|
|
14
|
-
'/api': (r, s) => s.end('an example api response')
|
|
15
|
-
}`)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const routesurl = pathToFileURL(routesfile).href
|
|
19
|
-
console.log(routesfile, routesurl)
|
|
20
|
-
const routes = (await import(routesurl)).default
|
|
21
|
-
|
|
22
|
-
http
|
|
23
|
-
.createServer(async (r, s) => {
|
|
24
|
-
try {
|
|
25
|
-
let data = ''
|
|
26
|
-
r.on('data', (s) => (data += s.toString()))
|
|
27
|
-
r.on('end', (x) => {
|
|
28
|
-
try {
|
|
29
|
-
data = JSON.parse(data)
|
|
30
|
-
} catch {}
|
|
31
|
-
});
|
|
32
|
-
const midware = Object.keys(routes)
|
|
33
|
-
.filter((k) => k.startsWith('_'))
|
|
34
|
-
.find((k) => routes[k](r, s, data));
|
|
35
|
-
if (r.url == '/') r.url = '/index.html'
|
|
36
|
-
const fn = `./public${r.url.replace('..', '')}`
|
|
37
|
-
if (fs.existsSync(fn)) {
|
|
38
|
-
if (fn.match(/sw\.js/)) s.writeHead(200, { 'Content-Type': 'application/javascript' })
|
|
39
|
-
return s.end(fs.readFileSync(fn, 'utf-8'))
|
|
40
|
-
}
|
|
41
|
-
if (routes[r.url]) return routes[r.url](r, s, data)
|
|
42
|
-
else s.writeHead(404).end()
|
|
43
|
-
} catch (e) {
|
|
44
|
-
console.log(e)
|
|
45
|
-
s.writeHead(404).end()
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
.listen(3000, (x) => console.log('listening on 3000'))
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import server from './module.mjs'
|
|
4
|
+
import { pathToFileURL } from 'node:url'
|
|
5
|
+
import { resolve } from 'node:path'
|
|
6
|
+
import fs from 'node:fs'
|
|
7
|
+
|
|
8
|
+
const routesfile = resolve('routes.mjs')
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(routesfile)) {
|
|
11
|
+
fs.writeFileSync(routesfile, `export default {
|
|
12
|
+
_debug: ({method, url}, s) => !console.log(method, url),
|
|
13
|
+
_example: (r, s) => console.log('returning a falsy value (above) will stop the chain'),
|
|
14
|
+
'/api': (r, s) => s.end('an example api response')
|
|
15
|
+
}`)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const routesurl = pathToFileURL(routesfile).href
|
|
19
|
+
console.log(routesfile, routesurl)
|
|
20
|
+
const routes = (await import(routesurl)).default
|
|
21
|
+
server(routes)
|