webvas 0.3.0 → 0.3.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -5
- data/LICENSE.txt +1 -1
- data/README.md +68 -77
- data/exe/webvas +3 -267
- data/js/bridge.js +117 -19
- data/js/loader.js +114 -52
- data/{site → js}/worker.js +2 -30
- data/lib/webvas/backend.rb +8 -1
- data/lib/webvas/bridge.rb +4 -5
- data/lib/webvas/cli.rb +319 -0
- data/lib/webvas/shader.rb +4 -27
- data/lib/webvas/version.rb +1 -1
- data/lib/webvas.rb +4 -3
- data/sig/webvas.rbs +8 -11
- metadata +5 -35
- data/docs/performance.md +0 -12
- data/docs/security.md +0 -9
- data/docs/spikes.md +0 -18
- data/runtime/Gemfile +0 -22
- data/runtime/Gemfile.lock +0 -101
- data/script/build_site +0 -52
- data/site/app.js +0 -466
- data/site/index.html +0 -56
- data/site/loader-example.html +0 -26
- data/site/style.css +0 -89
data/site/loader-example.html
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
-
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://cdn.jsdelivr.net 'wasm-unsafe-eval' 'unsafe-eval'; worker-src 'self' blob:; connect-src 'self' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self'">
|
|
7
|
-
<title>Webvas loader example</title>
|
|
8
|
-
<style>
|
|
9
|
-
body { margin: 2rem; background: #111417; color: #e5e6df; font: 1rem system-ui, sans-serif; }
|
|
10
|
-
canvas { display: block; width: min(80vw, 640px); height: auto; aspect-ratio: 4 / 3; background: #111417; }
|
|
11
|
-
output { display: block; margin-top: .75rem; white-space: pre-wrap; }
|
|
12
|
-
</style>
|
|
13
|
-
</head>
|
|
14
|
-
<body>
|
|
15
|
-
<canvas id="screen" width="320" height="240" aria-label="Ruby sketch"></canvas>
|
|
16
|
-
<script type="text/ruby" data-webvas>
|
|
17
|
-
require "gesso"
|
|
18
|
-
Gesso.run(width: 320, height: 240, runner: :web) do
|
|
19
|
-
draw do
|
|
20
|
-
background mouse_pressed? ? "#e5b36a" : "#123456"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
</script>
|
|
24
|
-
<script src="./loader.js"></script>
|
|
25
|
-
</body>
|
|
26
|
-
</html>
|
data/site/style.css
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
color-scheme: dark;
|
|
3
|
-
--paper: #111211;
|
|
4
|
-
--panel: #181a18;
|
|
5
|
-
--panel-raised: #202220;
|
|
6
|
-
--line: #303330;
|
|
7
|
-
--muted: #828780;
|
|
8
|
-
--ink: #e8eae5;
|
|
9
|
-
--copper: #d38a62;
|
|
10
|
-
--green: #99b493;
|
|
11
|
-
--mono: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
12
|
-
--sans: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
13
|
-
}
|
|
14
|
-
* { box-sizing: border-box; }
|
|
15
|
-
body { margin: 0; min-width: 320px; background: var(--paper); color: var(--ink); font-family: var(--sans); }
|
|
16
|
-
button, select, textarea { font: inherit; }
|
|
17
|
-
button, select { color: inherit; }
|
|
18
|
-
.topbar { height: 64px; display: flex; align-items: center; justify-content: space-between; padding: 0 clamp(18px, 5vw, 76px); border-bottom: 1px solid #252725; }
|
|
19
|
-
.wordmark { display: flex; gap: 10px; align-items: center; color: var(--ink); text-decoration: none; font-weight: 800; letter-spacing: -.04em; }
|
|
20
|
-
.mark { display: grid; place-items: center; width: 27px; height: 27px; border-radius: 7px 7px 7px 2px; background: var(--copper); color: #211812; font: 700 15px var(--mono); }
|
|
21
|
-
.top-meta { display: flex; align-items: center; gap: 11px; color: var(--muted); font: 11px var(--mono); }
|
|
22
|
-
.top-meta a { color: #c8cbc5; text-decoration: none; margin-left: 18px; }
|
|
23
|
-
.live-dot, .console-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--green); }
|
|
24
|
-
main { width: min(1180px, calc(100% - 40px)); margin: 0 auto; }
|
|
25
|
-
.intro { display: grid; grid-template-columns: 1fr 1fr; column-gap: 40px; align-items: end; padding: 58px 0 34px; }
|
|
26
|
-
h1 { margin: 0; font-size: clamp(38px, 5vw, 58px); line-height: .98; font-weight: 700; text-wrap: balance; }
|
|
27
|
-
h1 span { color: #858b84; }
|
|
28
|
-
.lede { justify-self: end; margin: 0 3px 4px 0; color: #a3a79f; font-size: 14px; line-height: 1.8; }
|
|
29
|
-
.workbench { overflow: hidden; border: 1px solid #393c38; border-radius: 11px; background: var(--panel); box-shadow: 0 16px 50px #0004; }
|
|
30
|
-
.toolbar { min-height: 54px; display: flex; align-items: center; gap: 20px; padding: 8px 12px 8px 17px; border-bottom: 1px solid var(--line); }
|
|
31
|
-
.file-label { display: flex; align-items: center; gap: 9px; min-width: 160px; font: 11px var(--mono); color: #d8dbd4; }
|
|
32
|
-
.file-icon { color: var(--copper); font-size: 15px; }
|
|
33
|
-
.dirty { visibility: hidden; color: var(--copper); font-size: 9px; }
|
|
34
|
-
.dirty.visible { visibility: visible; }
|
|
35
|
-
.example-select select { max-width: 190px; padding: 7px 28px 7px 10px; border: 1px solid var(--line); border-radius: 5px; background: #20221f; font: 11px var(--mono); }
|
|
36
|
-
.toolbar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
|
|
37
|
-
.quiet-button, .run-button { height: 34px; padding: 0 12px; border: 1px solid transparent; border-radius: 5px; background: transparent; cursor: pointer; font-size: 11px; }
|
|
38
|
-
.quiet-button { color: #b8bcb4; }
|
|
39
|
-
.quiet-button:hover { background: #272a27; }
|
|
40
|
-
.run-button { display: flex; align-items: center; gap: 8px; background: var(--copper); color: #231a15; font-weight: 800; }
|
|
41
|
-
.run-button:hover { background: #e09a72; }
|
|
42
|
-
.run-button kbd { margin-left: 5px; padding: 2px 4px; border: 1px solid #624735; border-radius: 3px; background: #cc8057; font: 9px var(--mono); }
|
|
43
|
-
button:focus-visible, select:focus-visible, textarea:focus-visible, a:focus-visible { outline: 2px solid var(--copper); outline-offset: 3px; }
|
|
44
|
-
.panes { display: grid; grid-template-columns: 1fr 1fr; min-height: 438px; }
|
|
45
|
-
.editor-pane, .stage-pane { min-width: 0; display: flex; flex-direction: column; }
|
|
46
|
-
.editor-pane { border-right: 1px solid var(--line); }
|
|
47
|
-
.pane-heading { height: 38px; display: flex; align-items: center; justify-content: space-between; padding: 0 16px; border-bottom: 1px solid #292c29; color: #9da29a; font: 9px var(--mono); }
|
|
48
|
-
.pane-heading span + span { color: #717770; }
|
|
49
|
-
textarea { flex: 1; width: 100%; min-height: 399px; resize: vertical; padding: 20px; border: 0; outline-offset: -3px; background: #151715; color: #d9ddd5; font: 12px/1.75 var(--mono); tab-size: 2; }
|
|
50
|
-
textarea::selection { background: #79533d; color: #fff4e8; }
|
|
51
|
-
.stage-wrap { position: relative; flex: 1; min-height: 399px; padding: 20px; background: #131513; }
|
|
52
|
-
.stage-wrap canvas { display: block; width: 100%; height: 100%; min-height: 359px; border: 1px solid #3a3e39; background: #1c1f1d; object-fit: contain; outline: none; }
|
|
53
|
-
.stage-wrap canvas:focus-visible { outline: 2px solid var(--copper); outline-offset: 2px; }
|
|
54
|
-
.stage-wrap canvas[hidden] { display: none; }
|
|
55
|
-
.loading { position: absolute; inset: 20px; display: flex; align-items: center; justify-content: center; gap: 10px; background: #171917; color: #9ca198; font: 11px var(--mono); }
|
|
56
|
-
.loading.hidden { display: none; }
|
|
57
|
-
.spinner { width: 13px; height: 13px; border: 1px solid #555d53; border-top-color: var(--copper); border-radius: 50%; }
|
|
58
|
-
.console { min-height: 39px; display: flex; align-items: center; gap: 9px; padding: 0 16px; border-top: 1px solid var(--line); color: #a3a79f; font: 10px var(--mono); }
|
|
59
|
-
.console-dot { flex: 0 0 auto; width: 6px; height: 6px; }
|
|
60
|
-
.console.error { color: #e1a08a; }
|
|
61
|
-
.console.error .console-dot { background: #d27861; }
|
|
62
|
-
.workbench-foot { min-height: 34px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 14px; padding: 8px 15px; border-top: 1px solid #252825; color: #72776f; font: 9px var(--mono); }
|
|
63
|
-
#performance-state { font-variant-numeric: tabular-nums; }
|
|
64
|
-
.note { margin: 15px 0 48px; color: #747a72; font-size: 11px; text-wrap: pretty; }
|
|
65
|
-
.note span { color: var(--copper); margin-right: 5px; }
|
|
66
|
-
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
|
|
67
|
-
@media (max-width: 720px) {
|
|
68
|
-
.top-meta > span:not(.live-dot) { display: none; }
|
|
69
|
-
.top-meta a { margin-left: 0; }
|
|
70
|
-
.intro { grid-template-columns: 1fr; row-gap: 18px; padding-top: 42px; }
|
|
71
|
-
.lede { justify-self: start; font-size: 12px; }
|
|
72
|
-
.toolbar { flex-wrap: wrap; gap: 7px; }
|
|
73
|
-
.file-label { min-width: 0; margin-right: auto; }
|
|
74
|
-
.example-select { order: 3; }
|
|
75
|
-
.toolbar-actions { width: 100%; flex-wrap: wrap; justify-content: space-between; margin-left: 0; gap: 2px; }
|
|
76
|
-
.quiet-button { padding: 0 7px; }
|
|
77
|
-
.run-button { padding: 0 9px; }
|
|
78
|
-
.run-button kbd { display: none; }
|
|
79
|
-
.panes { grid-template-columns: 1fr; }
|
|
80
|
-
.editor-pane { border-right: 0; border-bottom: 1px solid var(--line); }
|
|
81
|
-
textarea { min-height: 280px; }
|
|
82
|
-
.stage-wrap { min-height: 300px; padding: 12px; }
|
|
83
|
-
.stage-wrap canvas { min-height: 276px; }
|
|
84
|
-
.loading { inset: 12px; }
|
|
85
|
-
.workbench-foot span:nth-child(2) { display: none; }
|
|
86
|
-
}
|
|
87
|
-
@media (prefers-reduced-motion: reduce) {
|
|
88
|
-
*, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; transition-duration: .01ms !important; }
|
|
89
|
-
}
|