@creately/rdm-canvas 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/bin/rdm-canvas.ts +108 -0
- package/package.json +31 -0
- package/server/browserLauncher.ts +32 -0
- package/server/fileScanner.ts +69 -0
- package/server/fileWatcher.ts +74 -0
- package/server/index.ts +492 -0
- package/server/indexPage.ts +108 -0
- package/static/index.html +109 -0
- package/static/rdm-viewer.iife.js +8862 -0
|
@@ -0,0 +1,109 @@
|
|
|
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.0" />
|
|
6
|
+
<title>rdm-canvas</title>
|
|
7
|
+
<style>
|
|
8
|
+
html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; }
|
|
9
|
+
#rdm-root { width: 100%; height: 100%; }
|
|
10
|
+
</style>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<div id="rdm-root"></div>
|
|
14
|
+
<script src="/rdm-viewer.iife.js?v=5"></script>
|
|
15
|
+
<script>
|
|
16
|
+
let viewer = null;
|
|
17
|
+
let ws = null;
|
|
18
|
+
let reconnectTimer = null;
|
|
19
|
+
let sendDebounce = null;
|
|
20
|
+
|
|
21
|
+
function connect() {
|
|
22
|
+
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
23
|
+
const filePath = window.__RDM_FILE__ || '';
|
|
24
|
+
const wsUrl = filePath
|
|
25
|
+
? protocol + '//' + location.host + '/ws?file=' + encodeURIComponent(filePath)
|
|
26
|
+
: protocol + '//' + location.host + '/ws';
|
|
27
|
+
ws = new WebSocket(wsUrl);
|
|
28
|
+
|
|
29
|
+
ws.onopen = () => {
|
|
30
|
+
if (viewer) viewer.setConnectionStatus('connected');
|
|
31
|
+
if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
ws.onmessage = (event) => {
|
|
35
|
+
try {
|
|
36
|
+
const msg = JSON.parse(event.data);
|
|
37
|
+
if (msg.type === 'rdm') {
|
|
38
|
+
if (!viewer) {
|
|
39
|
+
viewer = window._Viewer.mount(document.getElementById('rdm-root'), {
|
|
40
|
+
rdmText: msg.text,
|
|
41
|
+
editable: true,
|
|
42
|
+
connectionStatus: 'connected',
|
|
43
|
+
onPatch: (op) => {
|
|
44
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
45
|
+
ws.send(JSON.stringify({ type: 'rdm-patch', op: op }));
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
onRdmChange: (rdmText) => {
|
|
49
|
+
// Fallback full-text sync (only used when onPatch is not triggered)
|
|
50
|
+
if (sendDebounce) clearTimeout(sendDebounce);
|
|
51
|
+
sendDebounce = setTimeout(() => {
|
|
52
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
53
|
+
ws.send(JSON.stringify({ type: 'rdm-update', text: rdmText }));
|
|
54
|
+
}
|
|
55
|
+
}, 500);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
viewer.updateRdm(msg.text);
|
|
60
|
+
}
|
|
61
|
+
} else if (msg.type === 'error') {
|
|
62
|
+
console.error('RDM errors:', msg.errors);
|
|
63
|
+
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.error('WS message parse error:', e);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
ws.onclose = () => {
|
|
70
|
+
if (viewer) viewer.setConnectionStatus('disconnected');
|
|
71
|
+
reconnectTimer = setTimeout(connect, 2000);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
ws.onerror = () => {
|
|
75
|
+
ws.close();
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Resolve Vite IIFE double-nesting: window.RdmViewer.RdmViewer.mount or window.RdmViewer.mount
|
|
80
|
+
function resolveViewer() {
|
|
81
|
+
var V = window.RdmViewer;
|
|
82
|
+
if (!V) return null;
|
|
83
|
+
if (V.mount) return V;
|
|
84
|
+
if (V.RdmViewer && V.RdmViewer.mount) return V.RdmViewer;
|
|
85
|
+
if (V.default && V.default.mount) return V.default;
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
var Viewer = resolveViewer();
|
|
90
|
+
if (Viewer) {
|
|
91
|
+
window._Viewer = Viewer;
|
|
92
|
+
connect();
|
|
93
|
+
} else {
|
|
94
|
+
window.addEventListener('load', () => {
|
|
95
|
+
Viewer = resolveViewer();
|
|
96
|
+
if (Viewer) {
|
|
97
|
+
window._Viewer = Viewer;
|
|
98
|
+
connect();
|
|
99
|
+
} else {
|
|
100
|
+
document.getElementById('rdm-root').innerHTML =
|
|
101
|
+
'<div style="display:flex;align-items:center;justify-content:center;height:100%;font-family:system-ui;color:#666;">' +
|
|
102
|
+
'<div style="text-align:center"><h2>Viewer bundle not found</h2>' +
|
|
103
|
+
'<p style="margin-top:8px">Run <code>bun run build:rdm-viewer</code> first</p></div></div>';
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
</script>
|
|
108
|
+
</body>
|
|
109
|
+
</html>
|