@threadedstack/wmd-web 0.0.0-stage → 0.1.13

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.
Files changed (92) hide show
  1. package/README.md +2601 -2
  2. package/RELEASE.json +123 -0
  3. package/export-page/coi-sw.js +20 -0
  4. package/export-page/index.html +17 -0
  5. package/export-page/run.css +10 -0
  6. package/export-page/run.js +236 -0
  7. package/guest/arm64/Image +4 -0
  8. package/guest/arm64/Image-4k +4 -0
  9. package/guest/arm64/initramfs.cpio.gz +0 -0
  10. package/guest/arm64/vm.wasm +0 -0
  11. package/package.json +36 -4
  12. package/page/sw.js +381 -0
  13. package/relay/control.ts +139 -0
  14. package/relay/engine.ts +787 -0
  15. package/relay/hosted.ts +660 -0
  16. package/relay/keys.ts +53 -0
  17. package/relay/local-tls.ts +121 -0
  18. package/relay/lock.ts +81 -0
  19. package/relay/logfile.ts +138 -0
  20. package/relay/main.ts +642 -0
  21. package/relay/policy.ts +241 -0
  22. package/relay/relay.ts +266 -0
  23. package/relay/token.ts +116 -0
  24. package/relay/v1.ts +107 -0
  25. package/relay/wisp.ts +615 -0
  26. package/src/base.js +325 -0
  27. package/src/boot.js +2037 -0
  28. package/src/calib-worker.js +40 -0
  29. package/src/fs/9p/codec.js +303 -0
  30. package/src/fs/9p/server.js +521 -0
  31. package/src/fs/errno.js +43 -0
  32. package/src/fs/graph.js +380 -0
  33. package/src/fs/overlay.js +1018 -0
  34. package/src/fs/pack-write.js +165 -0
  35. package/src/fs/pack.js +427 -0
  36. package/src/fs/seed.js +22 -0
  37. package/src/fs/svc-snapshot.js +65 -0
  38. package/src/fs/upper-pack.js +112 -0
  39. package/src/host/base-cache.js +195 -0
  40. package/src/host/base-file.js +328 -0
  41. package/src/host/base-io.js +93 -0
  42. package/src/host/boot-events.js +209 -0
  43. package/src/host/chan-service.js +300 -0
  44. package/src/host/chan-services.js +689 -0
  45. package/src/host/chan.js +655 -0
  46. package/src/host/ckpt-file.js +395 -0
  47. package/src/host/ckpt-io.js +207 -0
  48. package/src/host/ckpt-point.js +160 -0
  49. package/src/host/ckpt-save.js +64 -0
  50. package/src/host/ckpt.js +434 -0
  51. package/src/host/clock.js +111 -0
  52. package/src/host/ctl.js +778 -0
  53. package/src/host/errno.js +18 -0
  54. package/src/host/fs.js +167 -0
  55. package/src/host/gcnudge.js +83 -0
  56. package/src/host/i64shim.js +81 -0
  57. package/src/host/jit-cache.js +341 -0
  58. package/src/host/jit-hub-core.js +208 -0
  59. package/src/host/jit-hub.js +93 -0
  60. package/src/host/jit-snap.js +226 -0
  61. package/src/host/jit.js +1903 -0
  62. package/src/host/layout.js +100 -0
  63. package/src/host/monitor.js +110 -0
  64. package/src/host/p9mount.js +27 -0
  65. package/src/host/ram-mem.js +125 -0
  66. package/src/host/stdio.js +143 -0
  67. package/src/host/threads.js +109 -0
  68. package/src/host/wasi.js +335 -0
  69. package/src/host/wmd-imports.js +71 -0
  70. package/src/host/yamux.js +387 -0
  71. package/src/image-files.js +154 -0
  72. package/src/net/dhcp-dns.js +126 -0
  73. package/src/net/net-worker.js +172 -0
  74. package/src/net/packet.js +227 -0
  75. package/src/net/peer.js +230 -0
  76. package/src/net/proto.js +189 -0
  77. package/src/net/relay-client.js +226 -0
  78. package/src/net/stack.js +867 -0
  79. package/src/net/switch.js +160 -0
  80. package/src/net/wisp-client.js +570 -0
  81. package/src/net/wisp-transport.js +196 -0
  82. package/src/net/wisp.js +511 -0
  83. package/src/registry/client.js +176 -0
  84. package/src/registry/converter.js +68 -0
  85. package/src/registry/hub.js +221 -0
  86. package/src/registry/oci.js +76 -0
  87. package/src/registry/pack-worker.js +70 -0
  88. package/src/registry/pull.js +258 -0
  89. package/src/registry/ref.js +110 -0
  90. package/src/registry/wasi-mem.js +355 -0
  91. package/src/worker.js +315 -0
  92. package/wmdpack.wasm +0 -0
package/relay/v1.ts ADDED
@@ -0,0 +1,107 @@
1
+ // W59: the wmd-relay.v1 adapter (src/net/proto.js) over the relay engine (engine.ts).
2
+ // Its bytes, close codes, HTTP refusals and log lines are pinned by test/unit/relay-v1-golden.test.js.
3
+
4
+ import { E, MAX_DATA, PROTOCOL, T, WINDOW, abortMsg, connectedMsg, dnsReplyMsg, msg, parse, u32Msg } from '../src/net/proto.js'
5
+ import type { Engine, Principal, Session, Wire } from './engine.ts'
6
+ import { verifyToken } from './token.ts'
7
+
8
+ function send(s: Session, m: Uint8Array) {
9
+ if (s.closed) return
10
+ s.ws.send(m)
11
+ }
12
+
13
+ const wire: Wire = {
14
+ connected(s, st, detail) {
15
+ // the first window is upload credit too: it comes out of the bucket (the rest is owed)
16
+ const g = s.p.up.take(WINDOW)
17
+ st.ourGrant = g
18
+ send(s, connectedMsg(st.id, E.OK, g, detail))
19
+ if (g < WINDOW) s.w.engine.owe(s, st.id, WINDOW - g)
20
+ },
21
+ refused: (s, id, code, why) => send(s, connectedMsg(id, code, 0, why)),
22
+ data: (s, st, bytes) => send(s, msg(T.RDATA, st.id, bytes)),
23
+ end: (s, st) => send(s, msg(T.REND, st.id)),
24
+ abort: (s, st, code, why) => send(s, abortMsg(st.id, code, why)),
25
+ grant(s, st, n) {
26
+ st.ourGrant += n
27
+ send(s, u32Msg(T.RCREDIT, st.id, n))
28
+ },
29
+ dnsReply: (s, id, rcode, ttl, addrs, why) => send(s, dnsReplyMsg(id, rcode, ttl, addrs, why)),
30
+ }
31
+
32
+ export function createV1(engine: Engine, o: { secret: string; origins?: string[] }) {
33
+ const stats = engine.stats
34
+
35
+ /** The HTTP upgrade at /relay: origin, subprotocol, token, then the engine's admission. */
36
+ function fetch(req: Request, srv: any): Response | undefined {
37
+ const origin = req.headers.get('origin') || ''
38
+ if (o.origins?.length && !o.origins.includes(origin)) {
39
+ stats.refusedSessions++
40
+ return new Response('origin not allowed\n', { status: 403 })
41
+ }
42
+ const protos = (req.headers.get('sec-websocket-protocol') || '').split(',').map(x => x.trim())
43
+ if (!protos.includes(PROTOCOL)) return new Response(`subprotocol ${PROTOCOL} required\n`, { status: 400 })
44
+ const tok = protos.find(p => p.startsWith('t.'))
45
+ const info = tok ? verifyToken(o.secret, tok.slice(2)) : 'no token'
46
+ if (typeof info === 'string') {
47
+ engine.refusedSession(info, { origin })
48
+ return new Response(`${info}\n`, { status: 401 })
49
+ }
50
+ if (engine.hasSession(info.sid)) {
51
+ stats.refusedSessions++
52
+ return new Response('session already connected\n', { status: 409 })
53
+ }
54
+ const uid = info.uid || info.sid
55
+ const a = engine.admit(uid, info.grp || uid, info.exp)
56
+ if (!a.ok) return new Response(a.body, { status: a.status })
57
+ const ok = srv.upgrade(req, { data: { kind: 'v1', sid: info.sid, exp: info.exp, p: a.p }, headers: { 'Sec-WebSocket-Protocol': PROTOCOL } })
58
+ return ok ? undefined : new Response('upgrade failed\n', { status: 400 })
59
+ }
60
+
61
+ function open(ws: any) {
62
+ const { sid, exp, p } = ws.data as { sid: string; exp: number; p: Principal }
63
+ const s = engine.open(ws, sid, p, exp, wire, WINDOW)
64
+ if (!s) return
65
+ s.w = { engine }
66
+ ws.data.session = s
67
+ ws.send(JSON.stringify({ t: 'hello', protocol: PROTOCOL, limits: engine.limits(p) }))
68
+ }
69
+
70
+ function message(ws: any, raw: ArrayBuffer | Uint8Array | string) {
71
+ const s = ws.data.session as Session
72
+ if (!s || typeof raw === 'string') return
73
+ const u8 = raw instanceof Uint8Array ? raw : new Uint8Array(raw)
74
+ if (u8.length > MAX_DATA + 1024) return s.ws.close(1009, 'message too large') // the server's frame limit may be higher for Wisp
75
+ const m: any = parse(u8)
76
+ if (!m) return s.ws.close(4002, 'malformed message')
77
+ switch (m.type) {
78
+ case T.CONNECT:
79
+ engine.connectSafe(s, m.id, m.host, m.port)
80
+ break
81
+ case T.DATA: {
82
+ const st = s.streams.get(m.id)
83
+ if (!st || !st.connected || !st.sock || st.clientEnded) return // a stream that just failed: its ABORT is on the way
84
+ if (m.payload.length > st.ourGrant) return engine.fail(s, st, E.BAD, 'data over the granted credit')
85
+ st.ourGrant -= m.payload.length
86
+ engine.write(s, st, m.payload)
87
+ break
88
+ }
89
+ case T.END:
90
+ engine.clientEnd(s, m.id)
91
+ break
92
+ case T.ABORT:
93
+ engine.clientAbort(s, m.id)
94
+ break
95
+ case T.CREDIT:
96
+ engine.credit(s, m.id, m.n)
97
+ break
98
+ case T.DNS:
99
+ engine.dns(s, m.id, m.name, m.qtype).catch(e => engine.log({ ev: 'error', sid: s.sid, error: String(e) }))
100
+ break
101
+ default:
102
+ s.ws.close(4002, 'unknown message type')
103
+ }
104
+ }
105
+
106
+ return { fetch, open, message }
107
+ }