@zenithbuild/runtime 0.2.1 → 0.5.0-beta.2.12
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/HYDRATION_CONTRACT.md +112 -0
- package/README.md +3 -0
- package/RUNTIME_CONTRACT.md +183 -0
- package/dist/cleanup.js +88 -0
- package/dist/diagnostics.js +309 -0
- package/dist/effect.js +3 -0
- package/dist/events.js +59 -0
- package/dist/hydrate.js +1641 -0
- package/dist/index.js +4 -505
- package/dist/ref.js +23 -0
- package/dist/runtime.js +57 -0
- package/dist/signal.js +58 -0
- package/dist/state.js +79 -0
- package/dist/template.js +360 -0
- package/dist/zeneffect.js +640 -0
- package/package.json +17 -7
- package/dist/dom-hydration.d.ts +0 -44
- package/dist/dom-hydration.d.ts.map +0 -1
- package/dist/dom-hydration.js +0 -272
- package/dist/dom-hydration.js.map +0 -1
- package/dist/index.d.ts +0 -90
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/thin-runtime.d.ts +0 -24
- package/dist/thin-runtime.d.ts.map +0 -1
- package/dist/thin-runtime.js +0 -159
- package/dist/thin-runtime.js.map +0 -1
- package/src/dom-hydration.ts +0 -297
- package/src/index.ts +0 -488
- package/src/thin-runtime.ts +0 -159
package/dist/state.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// state.js — Zenith Runtime V0
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Proxy-free immutable state helper.
|
|
5
|
+
//
|
|
6
|
+
// API:
|
|
7
|
+
// const store = state({ count: 0 });
|
|
8
|
+
// store.get();
|
|
9
|
+
// store.set({ count: 1 });
|
|
10
|
+
// store.set((prev) => ({ ...prev, count: prev.count + 1 }));
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
import { _nextReactiveId, _trackDependency } from './zeneffect.js';
|
|
13
|
+
|
|
14
|
+
function isPlainObject(value) {
|
|
15
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return Object.prototype.toString.call(value) === '[object Object]';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function cloneSnapshot(value) {
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
return [...value];
|
|
24
|
+
}
|
|
25
|
+
if (isPlainObject(value)) {
|
|
26
|
+
return { ...value };
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create a proxy-free immutable state container.
|
|
33
|
+
*
|
|
34
|
+
* @param {object} initialValue
|
|
35
|
+
* @returns {{ get: () => object, set: (patch: object | ((prev: object) => object)) => object, subscribe: (fn: (next: object) => void) => () => void }}
|
|
36
|
+
*/
|
|
37
|
+
export function state(initialValue) {
|
|
38
|
+
let current = Object.freeze(cloneSnapshot(initialValue));
|
|
39
|
+
const subscribers = new Set();
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
get() {
|
|
43
|
+
return current;
|
|
44
|
+
},
|
|
45
|
+
set(nextPatch) {
|
|
46
|
+
const nextValue = typeof nextPatch === 'function'
|
|
47
|
+
? nextPatch(current)
|
|
48
|
+
: { ...current, ...nextPatch };
|
|
49
|
+
|
|
50
|
+
if (!nextValue || typeof nextValue !== 'object' || Array.isArray(nextValue)) {
|
|
51
|
+
throw new Error('[Zenith Runtime] state.set(next) must resolve to a plain object');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const nextSnapshot = Object.freeze(cloneSnapshot(nextValue));
|
|
55
|
+
if (Object.is(current, nextSnapshot)) {
|
|
56
|
+
return current;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
current = nextSnapshot;
|
|
60
|
+
|
|
61
|
+
const snapshot = [...subscribers];
|
|
62
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
63
|
+
snapshot[i](current);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return current;
|
|
67
|
+
},
|
|
68
|
+
subscribe(fn) {
|
|
69
|
+
if (typeof fn !== 'function') {
|
|
70
|
+
throw new Error('[Zenith Runtime] state.subscribe(fn) requires a function');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
subscribers.add(fn);
|
|
74
|
+
return function unsubscribe() {
|
|
75
|
+
subscribers.delete(fn);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
package/dist/template.js
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = dirname(__filename);
|
|
7
|
+
|
|
8
|
+
function normalizeNewlines(value) {
|
|
9
|
+
return String(value).replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function readRuntimeSourceFile(fileName) {
|
|
13
|
+
const fullPath = join(__dirname, fileName);
|
|
14
|
+
return normalizeNewlines(readFileSync(fullPath, 'utf8'));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function stripImports(source) {
|
|
18
|
+
return source.replace(/^\s*import\s+[^;]+;\s*$/gm, '').trim();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function buildRuntimeModuleSource() {
|
|
22
|
+
const segments = [
|
|
23
|
+
stripImports(readRuntimeSourceFile('zeneffect.js')),
|
|
24
|
+
stripImports(readRuntimeSourceFile('ref.js')),
|
|
25
|
+
stripImports(readRuntimeSourceFile('signal.js')),
|
|
26
|
+
stripImports(readRuntimeSourceFile('state.js')),
|
|
27
|
+
stripImports(readRuntimeSourceFile('diagnostics.js')),
|
|
28
|
+
stripImports(readRuntimeSourceFile('cleanup.js')),
|
|
29
|
+
stripImports(readRuntimeSourceFile('hydrate.js'))
|
|
30
|
+
].filter(Boolean);
|
|
31
|
+
|
|
32
|
+
return normalizeNewlines(segments.join('\n\n'));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const RUNTIME_MODULE_SOURCE = buildRuntimeModuleSource();
|
|
36
|
+
|
|
37
|
+
export function runtimeModuleSource() {
|
|
38
|
+
return RUNTIME_MODULE_SOURCE;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const RUNTIME_DEV_CLIENT_SOURCE = `(() => {
|
|
42
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') return;
|
|
43
|
+
if (window.__zenithDevClientActive === true) return;
|
|
44
|
+
window.__zenithDevClientActive = true;
|
|
45
|
+
|
|
46
|
+
const DEV_KEY = '__ZENITH_DEV__';
|
|
47
|
+
const STORAGE_KEY = '__ZENITH_DEBUG__';
|
|
48
|
+
const DEFAULT_LOGS = { route: false, bindings: false, events: false, hmr: false };
|
|
49
|
+
|
|
50
|
+
function readStoredLogs() {
|
|
51
|
+
try {
|
|
52
|
+
const raw = window.localStorage.getItem(STORAGE_KEY);
|
|
53
|
+
if (!raw) return { ...DEFAULT_LOGS };
|
|
54
|
+
if (raw === '1') return { route: true, bindings: true, events: true, hmr: true };
|
|
55
|
+
const parsed = JSON.parse(raw);
|
|
56
|
+
if (!parsed || typeof parsed !== 'object') return { ...DEFAULT_LOGS };
|
|
57
|
+
return {
|
|
58
|
+
route: parsed.route === true,
|
|
59
|
+
bindings: parsed.bindings === true,
|
|
60
|
+
events: parsed.events === true,
|
|
61
|
+
hmr: parsed.hmr === true
|
|
62
|
+
};
|
|
63
|
+
} catch {
|
|
64
|
+
return { ...DEFAULT_LOGS };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function persistLogs(logs) {
|
|
69
|
+
try {
|
|
70
|
+
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(logs));
|
|
71
|
+
} catch {
|
|
72
|
+
// ignore storage failures in private mode
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function ensureDevState() {
|
|
77
|
+
const current = window[DEV_KEY] && typeof window[DEV_KEY] === 'object' ? window[DEV_KEY] : {};
|
|
78
|
+
const logs = current.logs && typeof current.logs === 'object' ? current.logs : readStoredLogs();
|
|
79
|
+
const overlay = current.overlay && typeof current.overlay === 'object' ? current.overlay : {};
|
|
80
|
+
const state = {
|
|
81
|
+
logs: {
|
|
82
|
+
route: logs.route === true,
|
|
83
|
+
bindings: logs.bindings === true,
|
|
84
|
+
events: logs.events === true,
|
|
85
|
+
hmr: logs.hmr === true
|
|
86
|
+
},
|
|
87
|
+
overlay: {
|
|
88
|
+
open: overlay.open === true
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
window[DEV_KEY] = state;
|
|
92
|
+
persistLogs(state.logs);
|
|
93
|
+
return state;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function parseEventData(raw) {
|
|
97
|
+
if (typeof raw !== 'string' || raw.length === 0) return {};
|
|
98
|
+
try {
|
|
99
|
+
const parsed = JSON.parse(raw);
|
|
100
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
101
|
+
} catch {
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function fetchDevState() {
|
|
107
|
+
return fetch('/__zenith_dev/state', { cache: 'no-store' })
|
|
108
|
+
.then(function (response) {
|
|
109
|
+
if (!response || !response.ok) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return response.json().catch(function () { return null; });
|
|
113
|
+
})
|
|
114
|
+
.then(function (payload) {
|
|
115
|
+
return payload && typeof payload === 'object' ? payload : null;
|
|
116
|
+
})
|
|
117
|
+
.catch(function () {
|
|
118
|
+
return null;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function swapStylesheet(nextHref) {
|
|
123
|
+
if (typeof nextHref !== 'string' || nextHref.length === 0) {
|
|
124
|
+
window.location.reload();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const links = Array.from(document.querySelectorAll('link[rel="stylesheet"]'));
|
|
128
|
+
if (links.length === 0) {
|
|
129
|
+
window.location.reload();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const separator = nextHref.includes('?') ? '&' : '?';
|
|
133
|
+
links[0].setAttribute('href', nextHref + separator + '__zenith_dev=' + Date.now());
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const state = ensureDevState();
|
|
137
|
+
const shell = document.createElement('div');
|
|
138
|
+
shell.setAttribute('data-zenith-dev-overlay', 'true');
|
|
139
|
+
shell.style.position = 'fixed';
|
|
140
|
+
shell.style.left = '12px';
|
|
141
|
+
shell.style.bottom = '12px';
|
|
142
|
+
shell.style.zIndex = '2147483647';
|
|
143
|
+
shell.style.fontFamily = 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace';
|
|
144
|
+
shell.style.fontSize = '12px';
|
|
145
|
+
shell.style.pointerEvents = 'none';
|
|
146
|
+
|
|
147
|
+
const pill = document.createElement('button');
|
|
148
|
+
pill.type = 'button';
|
|
149
|
+
pill.textContent = 'Zenith Dev';
|
|
150
|
+
pill.style.pointerEvents = 'auto';
|
|
151
|
+
pill.style.border = '1px solid rgba(255,255,255,0.2)';
|
|
152
|
+
pill.style.background = 'rgba(20,20,24,0.88)';
|
|
153
|
+
pill.style.color = '#ecf2ff';
|
|
154
|
+
pill.style.borderRadius = '999px';
|
|
155
|
+
pill.style.padding = '6px 10px';
|
|
156
|
+
pill.style.cursor = 'pointer';
|
|
157
|
+
pill.style.boxShadow = '0 8px 24px rgba(0,0,0,0.25)';
|
|
158
|
+
|
|
159
|
+
const panel = document.createElement('div');
|
|
160
|
+
panel.style.display = state.overlay.open ? 'block' : 'none';
|
|
161
|
+
panel.style.width = '360px';
|
|
162
|
+
panel.style.marginTop = '8px';
|
|
163
|
+
panel.style.pointerEvents = 'auto';
|
|
164
|
+
panel.style.background = 'rgba(14,16,20,0.94)';
|
|
165
|
+
panel.style.color = '#dbe6ff';
|
|
166
|
+
panel.style.border = '1px solid rgba(255,255,255,0.16)';
|
|
167
|
+
panel.style.borderRadius = '10px';
|
|
168
|
+
panel.style.padding = '10px';
|
|
169
|
+
panel.style.boxShadow = '0 14px 30px rgba(0,0,0,0.35)';
|
|
170
|
+
|
|
171
|
+
const status = document.createElement('div');
|
|
172
|
+
status.textContent = 'status: connecting';
|
|
173
|
+
status.style.marginBottom = '6px';
|
|
174
|
+
|
|
175
|
+
const info = document.createElement('div');
|
|
176
|
+
info.textContent = 'route: ' + window.location.pathname;
|
|
177
|
+
info.style.opacity = '0.85';
|
|
178
|
+
info.style.marginBottom = '8px';
|
|
179
|
+
info.style.whiteSpace = 'pre-wrap';
|
|
180
|
+
|
|
181
|
+
const controls = document.createElement('div');
|
|
182
|
+
controls.style.display = 'grid';
|
|
183
|
+
controls.style.gridTemplateColumns = '1fr 1fr';
|
|
184
|
+
controls.style.gap = '6px';
|
|
185
|
+
controls.style.marginBottom = '8px';
|
|
186
|
+
|
|
187
|
+
function makeButton(label) {
|
|
188
|
+
const button = document.createElement('button');
|
|
189
|
+
button.type = 'button';
|
|
190
|
+
button.textContent = label;
|
|
191
|
+
button.style.border = '1px solid rgba(255,255,255,0.2)';
|
|
192
|
+
button.style.borderRadius = '6px';
|
|
193
|
+
button.style.padding = '6px 8px';
|
|
194
|
+
button.style.cursor = 'pointer';
|
|
195
|
+
button.style.background = 'rgba(36,41,51,0.85)';
|
|
196
|
+
button.style.color = '#ecf2ff';
|
|
197
|
+
return button;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const reloadButton = makeButton('Reload');
|
|
201
|
+
const copyButton = makeButton('Copy URL');
|
|
202
|
+
const debugButton = makeButton('Toggle Debug');
|
|
203
|
+
const overlayButton = makeButton('Toggle Overlay');
|
|
204
|
+
|
|
205
|
+
controls.append(reloadButton, copyButton, debugButton, overlayButton);
|
|
206
|
+
|
|
207
|
+
const logs = document.createElement('pre');
|
|
208
|
+
logs.style.margin = '0';
|
|
209
|
+
logs.style.padding = '8px';
|
|
210
|
+
logs.style.maxHeight = '190px';
|
|
211
|
+
logs.style.overflow = 'auto';
|
|
212
|
+
logs.style.border = '1px solid rgba(255,255,255,0.12)';
|
|
213
|
+
logs.style.borderRadius = '6px';
|
|
214
|
+
logs.style.background = 'rgba(8,10,14,0.8)';
|
|
215
|
+
logs.style.whiteSpace = 'pre-wrap';
|
|
216
|
+
logs.textContent = '[zenith-dev] waiting for server events...';
|
|
217
|
+
|
|
218
|
+
panel.append(status, info, controls, logs);
|
|
219
|
+
shell.append(pill, panel);
|
|
220
|
+
|
|
221
|
+
function setOpen(open) {
|
|
222
|
+
state.overlay.open = open === true;
|
|
223
|
+
panel.style.display = state.overlay.open ? 'block' : 'none';
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function appendLog(line) {
|
|
227
|
+
logs.textContent += '\\n' + line;
|
|
228
|
+
logs.scrollTop = logs.scrollHeight;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function updateInfo(payload) {
|
|
232
|
+
const route = typeof payload.route === 'string' ? payload.route : window.location.pathname;
|
|
233
|
+
const hash = typeof payload.buildHash === 'string' ? payload.buildHash : 'n/a';
|
|
234
|
+
const durationValue = Number.isFinite(payload.durationMs) ? payload.durationMs : payload.lastBuildMs;
|
|
235
|
+
const duration = Number.isFinite(durationValue) ? durationValue + 'ms' : 'n/a';
|
|
236
|
+
const changed = Array.isArray(payload.changedFiles) ? payload.changedFiles.join(', ') : '';
|
|
237
|
+
const serverUrl = typeof payload.serverUrl === 'string' ? payload.serverUrl : window.location.origin;
|
|
238
|
+
const buildId = Number.isInteger(payload.buildId) ? payload.buildId : 'n/a';
|
|
239
|
+
const buildStatus = typeof payload.status === 'string' ? payload.status : 'unknown';
|
|
240
|
+
info.textContent =
|
|
241
|
+
'server: ' + serverUrl + '\\n' +
|
|
242
|
+
'route: ' + route + '\\n' +
|
|
243
|
+
'buildId: ' + buildId + '\\n' +
|
|
244
|
+
'status: ' + buildStatus + '\\n' +
|
|
245
|
+
'hash: ' + hash + '\\n' +
|
|
246
|
+
'duration: ' + duration + '\\n' +
|
|
247
|
+
'changed: ' + changed;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function allLogsEnabled() {
|
|
251
|
+
return state.logs.route && state.logs.bindings && state.logs.events && state.logs.hmr;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function setAllLogs(enabled) {
|
|
255
|
+
state.logs.route = enabled;
|
|
256
|
+
state.logs.bindings = enabled;
|
|
257
|
+
state.logs.events = enabled;
|
|
258
|
+
state.logs.hmr = enabled;
|
|
259
|
+
persistLogs(state.logs);
|
|
260
|
+
appendLog('[zenith-dev] debug logs ' + (enabled ? 'enabled' : 'disabled'));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function emitDebug(label, payload) {
|
|
264
|
+
if (state.logs.hmr === true) {
|
|
265
|
+
console.log('[zenith-dev] ' + label, payload);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
pill.addEventListener('click', function () {
|
|
270
|
+
setOpen(!state.overlay.open);
|
|
271
|
+
});
|
|
272
|
+
overlayButton.addEventListener('click', function () {
|
|
273
|
+
setOpen(!state.overlay.open);
|
|
274
|
+
});
|
|
275
|
+
reloadButton.addEventListener('click', function () {
|
|
276
|
+
window.location.reload();
|
|
277
|
+
});
|
|
278
|
+
copyButton.addEventListener('click', function () {
|
|
279
|
+
const target = window.location.origin;
|
|
280
|
+
if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
|
|
281
|
+
navigator.clipboard.writeText(target).catch(() => {});
|
|
282
|
+
}
|
|
283
|
+
appendLog('[zenith-dev] copied ' + target);
|
|
284
|
+
});
|
|
285
|
+
debugButton.addEventListener('click', function () {
|
|
286
|
+
setAllLogs(!allLogsEnabled());
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
function mount() {
|
|
290
|
+
if (document.body) {
|
|
291
|
+
document.body.appendChild(shell);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (document.readyState === 'loading') {
|
|
295
|
+
document.addEventListener('DOMContentLoaded', mount, { once: true });
|
|
296
|
+
} else {
|
|
297
|
+
mount();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const source = new EventSource('/__zenith_dev/events');
|
|
301
|
+
source.addEventListener('connected', function (event) {
|
|
302
|
+
const payload = parseEventData(event.data);
|
|
303
|
+
status.textContent = 'status: connected';
|
|
304
|
+
updateInfo(payload);
|
|
305
|
+
appendLog('[connected] dev channel online');
|
|
306
|
+
emitDebug('connected', payload);
|
|
307
|
+
fetchDevState().then(function (statePayload) {
|
|
308
|
+
if (!statePayload) return;
|
|
309
|
+
updateInfo({ ...payload, ...statePayload });
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
source.addEventListener('build_start', function (event) {
|
|
313
|
+
const payload = parseEventData(event.data);
|
|
314
|
+
status.textContent = 'status: rebuilding';
|
|
315
|
+
appendLog('[build_start] ' + (Array.isArray(payload.changedFiles) ? payload.changedFiles.join(', ') : ''));
|
|
316
|
+
emitDebug('build_start', payload);
|
|
317
|
+
});
|
|
318
|
+
source.addEventListener('build_complete', function (event) {
|
|
319
|
+
const payload = parseEventData(event.data);
|
|
320
|
+
status.textContent = 'status: ready';
|
|
321
|
+
updateInfo(payload);
|
|
322
|
+
appendLog('[build_complete] ' + (Number.isFinite(payload.durationMs) ? payload.durationMs + 'ms' : 'done'));
|
|
323
|
+
emitDebug('build_complete', payload);
|
|
324
|
+
});
|
|
325
|
+
source.addEventListener('build_error', function (event) {
|
|
326
|
+
const payload = parseEventData(event.data);
|
|
327
|
+
status.textContent = 'status: error';
|
|
328
|
+
appendLog('[build_error] ' + (payload.message || 'Unknown error'));
|
|
329
|
+
emitDebug('build_error', payload);
|
|
330
|
+
});
|
|
331
|
+
source.addEventListener('reload', function (event) {
|
|
332
|
+
const payload = parseEventData(event.data);
|
|
333
|
+
appendLog('[reload] refreshing page');
|
|
334
|
+
emitDebug('reload', payload);
|
|
335
|
+
setTimeout(function () {
|
|
336
|
+
window.location.reload();
|
|
337
|
+
}, 30);
|
|
338
|
+
});
|
|
339
|
+
source.addEventListener('css_update', function (event) {
|
|
340
|
+
const payload = parseEventData(event.data);
|
|
341
|
+
appendLog('[css_update] ' + (payload.href || ''));
|
|
342
|
+
emitDebug('css_update', payload);
|
|
343
|
+
fetchDevState().then(function (statePayload) {
|
|
344
|
+
if (statePayload && typeof statePayload.cssHref === 'string' && statePayload.cssHref.length > 0) {
|
|
345
|
+
updateInfo({ ...payload, ...statePayload });
|
|
346
|
+
swapStylesheet(statePayload.cssHref);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
swapStylesheet(payload.href);
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
source.addEventListener('error', function () {
|
|
353
|
+
status.textContent = 'status: disconnected';
|
|
354
|
+
appendLog('[error] lost dev server connection');
|
|
355
|
+
});
|
|
356
|
+
})();`;
|
|
357
|
+
|
|
358
|
+
export function runtimeDevClientSource() {
|
|
359
|
+
return RUNTIME_DEV_CLIENT_SOURCE;
|
|
360
|
+
}
|