instaserve 0.0.44 → 0.1.0

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 CHANGED
@@ -1,2 +1,2 @@
1
- # instaserve
2
- Instant web stack
1
+ # instaserve
2
+ Instant web stack
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/package.json CHANGED
@@ -1,10 +1,12 @@
1
- {
2
- "name": "instaserve",
3
- "version": "0.0.44",
4
- "description": "Instant web stack",
5
- "main": "server.mjs",
6
- "bin": "./server.mjs",
7
- "scripts": {
8
- "start": "node server.mjs"
9
- }
10
- }
1
+ {
2
+ "name": "instaserve",
3
+ "version": "0.1.0",
4
+ "description": "Instant web stack",
5
+ "main": "server.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
+ }
@@ -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
- // navigator.serviceWorker.register('sw.js')
4
- </script>
5
- <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css'>
6
-
7
- <div class='bg-yellow-200'>hello</div>
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
- _debug: ({method, url}, s) => !console.log(method, url),
3
- _example: (r, s) => console.log('returning a falsy value (above) will stop the chain'),
4
- '/api': (r, s) => s.end('an example api response')
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
5
  }
package/server.mjs CHANGED
@@ -1,48 +1,48 @@
1
- #!/usr/bin/env node
2
-
3
- import http from 'node:http'
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 http from 'node:http'
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'))