@fiyuu/runtime 0.4.6 → 0.5.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/package.json +18 -4
- package/LICENSE +0 -674
- package/dist/bundler.d.ts +0 -10
- package/dist/bundler.d.ts.map +0 -1
- package/dist/bundler.js +0 -125
- package/dist/bundler.js.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -26
- package/dist/cli.js.map +0 -1
- package/dist/client-runtime.d.ts +0 -16
- package/dist/client-runtime.d.ts.map +0 -1
- package/dist/client-runtime.js +0 -528
- package/dist/client-runtime.js.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -5
- package/dist/index.js.map +0 -1
- package/dist/inspector.d.ts +0 -39
- package/dist/inspector.d.ts.map +0 -1
- package/dist/inspector.js +0 -262
- package/dist/inspector.js.map +0 -1
- package/dist/server-devtools.d.ts +0 -14
- package/dist/server-devtools.d.ts.map +0 -1
- package/dist/server-devtools.js +0 -123
- package/dist/server-devtools.js.map +0 -1
- package/dist/server-loader.d.ts +0 -27
- package/dist/server-loader.d.ts.map +0 -1
- package/dist/server-loader.js +0 -169
- package/dist/server-loader.js.map +0 -1
- package/dist/server-middleware.d.ts +0 -8
- package/dist/server-middleware.d.ts.map +0 -1
- package/dist/server-middleware.js +0 -50
- package/dist/server-middleware.js.map +0 -1
- package/dist/server-renderer.d.ts +0 -42
- package/dist/server-renderer.d.ts.map +0 -1
- package/dist/server-renderer.js +0 -255
- package/dist/server-renderer.js.map +0 -1
- package/dist/server-router.d.ts +0 -15
- package/dist/server-router.d.ts.map +0 -1
- package/dist/server-router.js +0 -68
- package/dist/server-router.js.map +0 -1
- package/dist/server-types.d.ts +0 -170
- package/dist/server-types.d.ts.map +0 -1
- package/dist/server-types.js +0 -6
- package/dist/server-types.js.map +0 -1
- package/dist/server-utils.d.ts +0 -17
- package/dist/server-utils.d.ts.map +0 -1
- package/dist/server-utils.js +0 -103
- package/dist/server-utils.js.map +0 -1
- package/dist/server-websocket.d.ts +0 -8
- package/dist/server-websocket.d.ts.map +0 -1
- package/dist/server-websocket.js +0 -56
- package/dist/server-websocket.js.map +0 -1
- package/dist/server.d.ts +0 -69
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -849
- package/dist/server.js.map +0 -1
- package/dist/service.d.ts +0 -29
- package/dist/service.d.ts.map +0 -1
- package/dist/service.js +0 -72
- package/dist/service.js.map +0 -1
package/dist/client-runtime.js
DELETED
|
@@ -1,528 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fiyuu Client Runtime
|
|
3
|
-
*
|
|
4
|
-
* A small script injected into every page that provides:
|
|
5
|
-
* - fiyuu.theme — dark/light mode management
|
|
6
|
-
* - fiyuu.state — simple reactive state with DOM binding
|
|
7
|
-
* - fiyuu.bind — shorthand for updating element text / html
|
|
8
|
-
* - fiyuu.router — client-side navigation without page reload
|
|
9
|
-
* - fiyuu.partial — replace a DOM element with a fetched route's content
|
|
10
|
-
* - fiyuu.onError — global client-side error handler
|
|
11
|
-
* - fiyuu.ws — WebSocket connection helper
|
|
12
|
-
*
|
|
13
|
-
* Everything is accessible via window.fiyuu in page scripts.
|
|
14
|
-
*/
|
|
15
|
-
export function buildClientRuntime(websocketPath) {
|
|
16
|
-
return `(function(){
|
|
17
|
-
window.fiyuu = {
|
|
18
|
-
|
|
19
|
-
// ── Theme ──────────────────────────────────────────────────────────────────
|
|
20
|
-
// fiyuu.theme.get() → "light" | "dark"
|
|
21
|
-
// fiyuu.theme.set("dark") → sets theme, saves to localStorage
|
|
22
|
-
// fiyuu.theme.toggle() → flips between light and dark
|
|
23
|
-
// fiyuu.theme.bindToggle("id") → wires a button to toggle + updates its label
|
|
24
|
-
// fiyuu.theme.onChange(fn) → calls fn whenever theme changes
|
|
25
|
-
theme: {
|
|
26
|
-
get: function() {
|
|
27
|
-
return document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
28
|
-
},
|
|
29
|
-
set: function(value) {
|
|
30
|
-
var isDark = value === "dark";
|
|
31
|
-
document.documentElement.classList.toggle("dark", isDark);
|
|
32
|
-
document.documentElement.setAttribute("data-theme", value);
|
|
33
|
-
try { localStorage.setItem("fiyuu-theme", value); } catch(e) {}
|
|
34
|
-
document.dispatchEvent(new CustomEvent("fiyuu:theme", { detail: { theme: value } }));
|
|
35
|
-
},
|
|
36
|
-
toggle: function() {
|
|
37
|
-
this.set(this.get() === "dark" ? "light" : "dark");
|
|
38
|
-
},
|
|
39
|
-
bindToggle: function(elementId) {
|
|
40
|
-
var el = document.getElementById(elementId);
|
|
41
|
-
if (!el) return;
|
|
42
|
-
var self = this;
|
|
43
|
-
var sync = function() { el.textContent = self.get() === "dark" ? "Light" : "Dark"; };
|
|
44
|
-
sync();
|
|
45
|
-
el.addEventListener("click", function() { self.toggle(); sync(); });
|
|
46
|
-
},
|
|
47
|
-
onChange: function(callback) {
|
|
48
|
-
document.addEventListener("fiyuu:theme", function(e) { callback(e.detail.theme); });
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
// ── Bind ───────────────────────────────────────────────────────────────────
|
|
53
|
-
// fiyuu.bind("element-id", value) → sets element's text content
|
|
54
|
-
// fiyuu.bind("element-id", value, true) → sets innerHTML instead
|
|
55
|
-
bind: function(elementId, value, asHtml) {
|
|
56
|
-
var el = document.getElementById(elementId);
|
|
57
|
-
if (!el) return;
|
|
58
|
-
if (asHtml) { el.innerHTML = String(value != null ? value : ""); }
|
|
59
|
-
else { el.textContent = String(value != null ? value : ""); }
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
// ── State ──────────────────────────────────────────────────────────────────
|
|
63
|
-
// var counter = fiyuu.state("counter", 0)
|
|
64
|
-
// counter.get() → current value
|
|
65
|
-
// counter.set(5) → updates value, fires "fiyuu:state:counter" event
|
|
66
|
-
// counter.bind("element-id") → auto-updates element when state changes
|
|
67
|
-
// counter.onChange(fn) → calls fn(newValue) on every update
|
|
68
|
-
state: function(key, initialValue) {
|
|
69
|
-
var current = initialValue;
|
|
70
|
-
var eventName = "fiyuu:state:" + key;
|
|
71
|
-
return {
|
|
72
|
-
get: function() { return current; },
|
|
73
|
-
set: function(next) {
|
|
74
|
-
current = next;
|
|
75
|
-
document.dispatchEvent(new CustomEvent(eventName, { detail: next }));
|
|
76
|
-
},
|
|
77
|
-
bind: function(elementId) {
|
|
78
|
-
window.fiyuu.bind(elementId, current);
|
|
79
|
-
document.addEventListener(eventName, function(e) {
|
|
80
|
-
window.fiyuu.bind(elementId, e.detail);
|
|
81
|
-
});
|
|
82
|
-
return this;
|
|
83
|
-
},
|
|
84
|
-
onChange: function(callback) {
|
|
85
|
-
document.addEventListener(eventName, function(e) { callback(e.detail); });
|
|
86
|
-
return this;
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
// ── Partial ────────────────────────────────────────────────────────────────
|
|
92
|
-
// fiyuu.partial("element-id", "/route") → fetches route body, replaces element
|
|
93
|
-
// fiyuu.partial("element-id", "/route", { loading: "<p>Loading…</p>" })
|
|
94
|
-
partial: async function(elementId, url, options) {
|
|
95
|
-
var el = document.getElementById(elementId);
|
|
96
|
-
if (!el) return;
|
|
97
|
-
if (options && options.loading) el.innerHTML = options.loading;
|
|
98
|
-
try {
|
|
99
|
-
var parsed = new URL(url, location.href);
|
|
100
|
-
var res = await fetch(parsed.pathname + parsed.search, {
|
|
101
|
-
headers: { "x-fiyuu-navigate": "1" },
|
|
102
|
-
credentials: "same-origin",
|
|
103
|
-
});
|
|
104
|
-
if (!res.ok || res.headers.get("x-fiyuu-navigate") !== "1") return;
|
|
105
|
-
var payload = await res.json();
|
|
106
|
-
el.innerHTML = payload.body || "";
|
|
107
|
-
var scripts = el.querySelectorAll("script");
|
|
108
|
-
for (var i = 0; i < scripts.length; i++) {
|
|
109
|
-
var old = scripts[i];
|
|
110
|
-
var next = document.createElement("script");
|
|
111
|
-
for (var j = 0; j < old.attributes.length; j++) next.setAttribute(old.attributes[j].name, old.attributes[j].value);
|
|
112
|
-
next.textContent = old.textContent;
|
|
113
|
-
old.parentNode.replaceChild(next, old);
|
|
114
|
-
}
|
|
115
|
-
} catch(e) {}
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
// ── onError ────────────────────────────────────────────────────────────────
|
|
119
|
-
// fiyuu.onError(function(event) { ... }) → called on unhandled JS errors
|
|
120
|
-
onError: function(callback) {
|
|
121
|
-
window.addEventListener("error", function(event) {
|
|
122
|
-
callback({ message: event.message, error: event.error, source: event.filename, line: event.lineno });
|
|
123
|
-
});
|
|
124
|
-
window.addEventListener("unhandledrejection", function(event) {
|
|
125
|
-
var reason = event.reason instanceof Error ? event.reason : new Error(String(event.reason || "Unhandled rejection"));
|
|
126
|
-
callback({ message: reason.message, error: reason, source: null, line: null });
|
|
127
|
-
});
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
// ── Router ─────────────────────────────────────────────────────────────────
|
|
131
|
-
// fiyuu.router.navigate("/about") → client-side navigation (no reload)
|
|
132
|
-
// fiyuu.router.on("navigate", fn) → called after each navigation with { route, render }
|
|
133
|
-
// fiyuu.router.on("before", fn) → called before navigation; return false to cancel
|
|
134
|
-
// Links with data-fiyuu-link (or all same-origin <a> tags) are intercepted automatically.
|
|
135
|
-
router: (function() {
|
|
136
|
-
var listeners = { navigate: [], before: [] };
|
|
137
|
-
var navCache = new Map();
|
|
138
|
-
var inflightNav = new Map();
|
|
139
|
-
var inflightPrefetch = new Map();
|
|
140
|
-
var prefetchedRoutes = new Set();
|
|
141
|
-
var MAX_NAV_CACHE = 24;
|
|
142
|
-
|
|
143
|
-
function canPrefetch() {
|
|
144
|
-
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
|
|
145
|
-
if (!connection) return true;
|
|
146
|
-
if (connection.saveData) return false;
|
|
147
|
-
var type = connection.effectiveType || "";
|
|
148
|
-
return type !== "slow-2g" && type !== "2g";
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function emit(event, detail) {
|
|
152
|
-
for (var i = 0; i < listeners[event].length; i++) {
|
|
153
|
-
if (listeners[event][i](detail) === false) return false;
|
|
154
|
-
}
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function rerunScripts(container) {
|
|
159
|
-
var scripts = container.querySelectorAll("script");
|
|
160
|
-
for (var i = 0; i < scripts.length; i++) {
|
|
161
|
-
var old = scripts[i];
|
|
162
|
-
var next = document.createElement("script");
|
|
163
|
-
for (var j = 0; j < old.attributes.length; j++) {
|
|
164
|
-
next.setAttribute(old.attributes[j].name, old.attributes[j].value);
|
|
165
|
-
}
|
|
166
|
-
next.textContent = old.textContent;
|
|
167
|
-
old.parentNode.replaceChild(next, old);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function rememberRoute(key, payload) {
|
|
172
|
-
if (!key) return;
|
|
173
|
-
if (navCache.has(key)) navCache.delete(key);
|
|
174
|
-
navCache.set(key, payload);
|
|
175
|
-
if (navCache.size > MAX_NAV_CACHE) {
|
|
176
|
-
var firstKey = navCache.keys().next();
|
|
177
|
-
if (!firstKey.done) navCache.delete(firstKey.value);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function scheduleIdle(task) {
|
|
182
|
-
if (typeof window.requestIdleCallback === "function") {
|
|
183
|
-
window.requestIdleCallback(task, { timeout: 1200 });
|
|
184
|
-
} else {
|
|
185
|
-
setTimeout(task, 80);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function prefetchRouteFromHref(href) {
|
|
190
|
-
if (!canPrefetch()) return;
|
|
191
|
-
if (!href || href.startsWith("#") || href.startsWith("mailto:") || href.startsWith("tel:")) return;
|
|
192
|
-
var parsed = new URL(href, location.href);
|
|
193
|
-
if (parsed.origin !== location.origin) return;
|
|
194
|
-
var cacheKey = parsed.pathname + parsed.search;
|
|
195
|
-
if (prefetchedRoutes.has(cacheKey)) return;
|
|
196
|
-
if (navCache.has(cacheKey) || inflightNav.has(cacheKey) || inflightPrefetch.has(cacheKey)) return;
|
|
197
|
-
|
|
198
|
-
scheduleIdle(function() {
|
|
199
|
-
var pending = fetch(cacheKey, {
|
|
200
|
-
headers: { "x-fiyuu-navigate": "1" },
|
|
201
|
-
credentials: "same-origin",
|
|
202
|
-
}).then(function(res) {
|
|
203
|
-
if (!res.ok || res.headers.get("x-fiyuu-navigate") !== "1") return null;
|
|
204
|
-
return res.json();
|
|
205
|
-
}).then(function(payload) {
|
|
206
|
-
if (payload) {
|
|
207
|
-
prefetchedRoutes.add(cacheKey);
|
|
208
|
-
rememberRoute(cacheKey, payload);
|
|
209
|
-
}
|
|
210
|
-
}).catch(function() {
|
|
211
|
-
return null;
|
|
212
|
-
}).finally(function() {
|
|
213
|
-
inflightPrefetch.delete(cacheKey);
|
|
214
|
-
});
|
|
215
|
-
inflightPrefetch.set(cacheKey, pending);
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function applyPayload(payload, parsed, push) {
|
|
220
|
-
var app = document.getElementById("app");
|
|
221
|
-
if (app) {
|
|
222
|
-
app.innerHTML = payload.body || "";
|
|
223
|
-
rerunScripts(app);
|
|
224
|
-
}
|
|
225
|
-
document.title = payload.title || document.title;
|
|
226
|
-
window.__FIYUU_ROUTE__ = payload.route;
|
|
227
|
-
window.__FIYUU_DATA__ = payload.data;
|
|
228
|
-
window.__FIYUU_RENDER__ = payload.render;
|
|
229
|
-
if (push !== false) history.pushState({ route: payload.route }, payload.title || "", parsed.pathname + parsed.search);
|
|
230
|
-
window.scrollTo(0, 0);
|
|
231
|
-
emit("navigate", { route: payload.route, render: payload.render, title: payload.title });
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
async function navigate(url, push) {
|
|
235
|
-
var href = typeof url === "string" ? url : url.href;
|
|
236
|
-
var parsed = new URL(href, location.href);
|
|
237
|
-
var cacheKey = parsed.pathname + parsed.search;
|
|
238
|
-
if (parsed.origin !== location.origin) { location.href = href; return; }
|
|
239
|
-
if (push !== false && cacheKey === location.pathname + location.search) return;
|
|
240
|
-
if (emit("before", { route: parsed.pathname }) === false) return;
|
|
241
|
-
|
|
242
|
-
if (navCache.has(cacheKey)) {
|
|
243
|
-
applyPayload(navCache.get(cacheKey), parsed, push);
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
try {
|
|
248
|
-
var prefetched = inflightPrefetch.get(cacheKey);
|
|
249
|
-
if (prefetched) {
|
|
250
|
-
var prefetchedPayload = await prefetched;
|
|
251
|
-
inflightPrefetch.delete(cacheKey);
|
|
252
|
-
if (prefetchedPayload) {
|
|
253
|
-
rememberRoute(cacheKey, prefetchedPayload);
|
|
254
|
-
applyPayload(prefetchedPayload, parsed, push);
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
var pending = inflightNav.get(cacheKey);
|
|
260
|
-
if (!pending) {
|
|
261
|
-
pending = fetch(cacheKey, {
|
|
262
|
-
headers: { "x-fiyuu-navigate": "1" },
|
|
263
|
-
credentials: "same-origin",
|
|
264
|
-
});
|
|
265
|
-
inflightNav.set(cacheKey, pending);
|
|
266
|
-
}
|
|
267
|
-
var res = await pending;
|
|
268
|
-
inflightNav.delete(cacheKey);
|
|
269
|
-
if (!res.ok || res.headers.get("x-fiyuu-navigate") !== "1") {
|
|
270
|
-
location.href = href;
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
var payload = await res.json();
|
|
274
|
-
rememberRoute(cacheKey, payload);
|
|
275
|
-
applyPayload(payload, parsed, push);
|
|
276
|
-
} catch(e) {
|
|
277
|
-
inflightNav.delete(cacheKey);
|
|
278
|
-
location.href = href;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
function intercept() {
|
|
283
|
-
document.addEventListener("mouseover", function(event) {
|
|
284
|
-
var target = event.target.closest("a[href]");
|
|
285
|
-
if (!target) return;
|
|
286
|
-
if (target.hasAttribute("data-fiyuu-no-prefetch")) return;
|
|
287
|
-
prefetchRouteFromHref(target.getAttribute("href"));
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
document.addEventListener("focusin", function(event) {
|
|
291
|
-
var target = event.target.closest("a[href]");
|
|
292
|
-
if (!target) return;
|
|
293
|
-
if (target.hasAttribute("data-fiyuu-no-prefetch")) return;
|
|
294
|
-
prefetchRouteFromHref(target.getAttribute("href"));
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
if (typeof window.IntersectionObserver === "function") {
|
|
298
|
-
var observer = new IntersectionObserver(function(entries) {
|
|
299
|
-
entries.forEach(function(entry) {
|
|
300
|
-
if (!entry.isIntersecting) return;
|
|
301
|
-
var link = entry.target;
|
|
302
|
-
if (link.hasAttribute("data-fiyuu-no-prefetch")) {
|
|
303
|
-
observer.unobserve(link);
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
prefetchRouteFromHref(link.getAttribute("href"));
|
|
307
|
-
observer.unobserve(link);
|
|
308
|
-
});
|
|
309
|
-
}, { rootMargin: "280px" });
|
|
310
|
-
|
|
311
|
-
document.querySelectorAll("a[href]").forEach(function(link) {
|
|
312
|
-
observer.observe(link);
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
document.addEventListener("click", function(event) {
|
|
317
|
-
var target = event.target.closest("a[href]");
|
|
318
|
-
if (!target) return;
|
|
319
|
-
var href = target.getAttribute("href");
|
|
320
|
-
if (!href || href.startsWith("#") || href.startsWith("mailto:") || href.startsWith("tel:")) return;
|
|
321
|
-
var parsed = new URL(href, location.href);
|
|
322
|
-
if (parsed.origin !== location.origin) return;
|
|
323
|
-
if (target.hasAttribute("data-fiyuu-reload")) return;
|
|
324
|
-
event.preventDefault();
|
|
325
|
-
navigate(parsed.pathname + parsed.search, true);
|
|
326
|
-
});
|
|
327
|
-
window.addEventListener("popstate", function(event) {
|
|
328
|
-
navigate(location.pathname + location.search, false);
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
document.addEventListener("DOMContentLoaded", intercept);
|
|
333
|
-
|
|
334
|
-
return {
|
|
335
|
-
navigate: function(url) { return navigate(url, true); },
|
|
336
|
-
on: function(event, fn) {
|
|
337
|
-
if (listeners[event]) listeners[event].push(fn);
|
|
338
|
-
return this;
|
|
339
|
-
},
|
|
340
|
-
};
|
|
341
|
-
})(),
|
|
342
|
-
|
|
343
|
-
// ── Action ─────────────────────────────────────────────────────────────────
|
|
344
|
-
// fiyuu.action('/blog', payload)
|
|
345
|
-
// fiyuu.action('/blog', payload, { status: 'el-id', loading: 'Processing...', onSuccess: fn, onError: fn })
|
|
346
|
-
// → POSTs JSON payload to route, returns response body (never throws)
|
|
347
|
-
// → status: element id to display loading/result messages
|
|
348
|
-
// → loading: message shown while request is in flight
|
|
349
|
-
// → errorMessage: message shown on failure (default: 'İşlem başarısız oldu.')
|
|
350
|
-
// → onSuccess(body): called when body.success === true
|
|
351
|
-
// → onError(err): called on network/HTTP error
|
|
352
|
-
action: async function(route, payload, options) {
|
|
353
|
-
var opts = options || {};
|
|
354
|
-
var statusEl = opts.status ? document.getElementById(opts.status) : null;
|
|
355
|
-
if (statusEl && opts.loading != null) statusEl.textContent = opts.loading;
|
|
356
|
-
try {
|
|
357
|
-
var res = await fetch(route, {
|
|
358
|
-
method: "POST",
|
|
359
|
-
headers: { "content-type": "application/json", "accept": "application/json" },
|
|
360
|
-
body: JSON.stringify(payload)
|
|
361
|
-
});
|
|
362
|
-
if (!res.ok) throw new Error("HTTP " + res.status);
|
|
363
|
-
var body = await res.json();
|
|
364
|
-
if (statusEl && body.message) statusEl.textContent = body.message;
|
|
365
|
-
if (body.success && opts.onSuccess) opts.onSuccess(body);
|
|
366
|
-
return body;
|
|
367
|
-
} catch(err) {
|
|
368
|
-
if (statusEl) statusEl.textContent = opts.errorMessage || "İşlem başarısız oldu.";
|
|
369
|
-
if (opts.onError) opts.onError(err);
|
|
370
|
-
return { success: false };
|
|
371
|
-
}
|
|
372
|
-
},
|
|
373
|
-
|
|
374
|
-
// ── Modal ──────────────────────────────────────────────────────────────────
|
|
375
|
-
// fiyuu.modal.open('my-modal') → shows element (display:flex)
|
|
376
|
-
// fiyuu.modal.close('my-modal') → hides element (display:none)
|
|
377
|
-
// fiyuu.modal.toggle('my-modal') → toggles visibility
|
|
378
|
-
//
|
|
379
|
-
// Declarative (auto-wired on DOMContentLoaded):
|
|
380
|
-
// <div id="my-modal" data-fiyuu-modal style="display:none">…</div>
|
|
381
|
-
// <button data-fiyuu-open="my-modal">Open</button>
|
|
382
|
-
// <button data-fiyuu-close="my-modal">Close</button>
|
|
383
|
-
// Clicking backdrop (the modal element itself) auto-closes it.
|
|
384
|
-
modal: {
|
|
385
|
-
open: function(id) {
|
|
386
|
-
var el = document.getElementById(id);
|
|
387
|
-
if (el) el.style.display = "flex";
|
|
388
|
-
},
|
|
389
|
-
close: function(id) {
|
|
390
|
-
var el = document.getElementById(id);
|
|
391
|
-
if (el) el.style.display = "none";
|
|
392
|
-
},
|
|
393
|
-
toggle: function(id) {
|
|
394
|
-
var el = document.getElementById(id);
|
|
395
|
-
if (!el) return;
|
|
396
|
-
el.style.display = el.style.display === "none" ? "flex" : "none";
|
|
397
|
-
}
|
|
398
|
-
},
|
|
399
|
-
|
|
400
|
-
// ── data ───────────────────────────────────────────────────────────────────
|
|
401
|
-
// fiyuu.data('my-id') → parses JSON from <script type="application/json" id="my-id">
|
|
402
|
-
// Use clientData() helper in page.tsx to embed server data safely.
|
|
403
|
-
data: function(id) {
|
|
404
|
-
var el = document.getElementById(id);
|
|
405
|
-
if (!el) return null;
|
|
406
|
-
try { return JSON.parse(el.textContent || "null"); } catch(e) { return null; }
|
|
407
|
-
},
|
|
408
|
-
|
|
409
|
-
// ── WebSocket ──────────────────────────────────────────────────────────────
|
|
410
|
-
// var ws = fiyuu.ws()
|
|
411
|
-
// ws.on("counter:tick", (data) => { ... }) → listens for a message type
|
|
412
|
-
// ws.onOpen(fn) / ws.onClose(fn) / ws.onError(fn)
|
|
413
|
-
// ws.send({ type: "ping" })
|
|
414
|
-
// ws.status() → "connecting" | "connected" | "closed" | "unavailable"
|
|
415
|
-
ws: function(overridePath) {
|
|
416
|
-
var wsPath = overridePath || window.__FIYUU_WS_PATH__ || ${JSON.stringify(websocketPath)};
|
|
417
|
-
var protocol = location.protocol === "https:" ? "wss" : "ws";
|
|
418
|
-
var socket = new WebSocket(protocol + "://" + location.host + wsPath);
|
|
419
|
-
var handlers = {};
|
|
420
|
-
var statusValue = "connecting";
|
|
421
|
-
|
|
422
|
-
socket.addEventListener("open", function() { statusValue = "connected"; });
|
|
423
|
-
socket.addEventListener("close", function() {
|
|
424
|
-
if (statusValue !== "unavailable") statusValue = "closed";
|
|
425
|
-
});
|
|
426
|
-
socket.addEventListener("error", function() { statusValue = "unavailable"; });
|
|
427
|
-
socket.addEventListener("message", function(event) {
|
|
428
|
-
try {
|
|
429
|
-
var payload = JSON.parse(event.data);
|
|
430
|
-
if (payload && payload.type && handlers[payload.type]) {
|
|
431
|
-
handlers[payload.type](payload);
|
|
432
|
-
}
|
|
433
|
-
} catch(e) {}
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
return {
|
|
437
|
-
on: function(type, handler) { handlers[type] = handler; return this; },
|
|
438
|
-
onOpen: function(handler) { socket.addEventListener("open", handler); return this; },
|
|
439
|
-
onClose: function(handler) { socket.addEventListener("close", handler); return this; },
|
|
440
|
-
onError: function(handler) { socket.addEventListener("error", handler); return this; },
|
|
441
|
-
send: function(data) { socket.send(JSON.stringify(data)); return this; },
|
|
442
|
-
status: function() { return statusValue; },
|
|
443
|
-
socket: socket
|
|
444
|
-
};
|
|
445
|
-
},
|
|
446
|
-
|
|
447
|
-
// ── Channel (realtime) ─────────────────────────────────────────────────────
|
|
448
|
-
// fiyuu.channel('chat').on('new-message', (data) => { ... })
|
|
449
|
-
// fiyuu.channel('chat').emit('message', { text: 'hello' })
|
|
450
|
-
channel: function(name) {
|
|
451
|
-
var channelHandlers = {};
|
|
452
|
-
var ws = window.fiyuu.ws();
|
|
453
|
-
|
|
454
|
-
ws.socket.addEventListener("message", function(event) {
|
|
455
|
-
try {
|
|
456
|
-
var payload = JSON.parse(event.data);
|
|
457
|
-
if (payload && payload.channel === name && payload.event && channelHandlers[payload.event]) {
|
|
458
|
-
channelHandlers[payload.event](payload.data);
|
|
459
|
-
}
|
|
460
|
-
} catch(e) {}
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
return {
|
|
464
|
-
on: function(event, handler) {
|
|
465
|
-
channelHandlers[event] = handler;
|
|
466
|
-
return this;
|
|
467
|
-
},
|
|
468
|
-
emit: function(event, data) {
|
|
469
|
-
ws.send({ channel: name, event: event, data: data, ts: Date.now() });
|
|
470
|
-
return this;
|
|
471
|
-
},
|
|
472
|
-
off: function(event) {
|
|
473
|
-
delete channelHandlers[event];
|
|
474
|
-
return this;
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
// ── Declarative wiring (runs after DOM is ready) ───────────────────────────
|
|
482
|
-
// Wires [data-fiyuu-open], [data-fiyuu-close], [data-fiyuu-modal] automatically.
|
|
483
|
-
// Also handles forms with [data-fiyuu-action] for zero-boilerplate action calls.
|
|
484
|
-
document.addEventListener("DOMContentLoaded", function() {
|
|
485
|
-
// Modal openers: <button data-fiyuu-open="modal-id">
|
|
486
|
-
document.querySelectorAll("[data-fiyuu-open]").forEach(function(el) {
|
|
487
|
-
el.addEventListener("click", function() {
|
|
488
|
-
window.fiyuu.modal.open(el.getAttribute("data-fiyuu-open"));
|
|
489
|
-
});
|
|
490
|
-
});
|
|
491
|
-
// Modal closers: <button data-fiyuu-close="modal-id">
|
|
492
|
-
document.querySelectorAll("[data-fiyuu-close]").forEach(function(el) {
|
|
493
|
-
el.addEventListener("click", function() {
|
|
494
|
-
window.fiyuu.modal.close(el.getAttribute("data-fiyuu-close"));
|
|
495
|
-
});
|
|
496
|
-
});
|
|
497
|
-
// Backdrop close: <div id="modal-id" data-fiyuu-modal …>
|
|
498
|
-
document.querySelectorAll("[data-fiyuu-modal]").forEach(function(modal) {
|
|
499
|
-
modal.addEventListener("click", function(e) {
|
|
500
|
-
if (e.target === modal) window.fiyuu.modal.close(modal.id);
|
|
501
|
-
});
|
|
502
|
-
});
|
|
503
|
-
// Declarative form actions:
|
|
504
|
-
// <form data-fiyuu-action="/route" data-fiyuu-status="el-id" data-fiyuu-success="reload|close:modal-id">
|
|
505
|
-
document.querySelectorAll("form[data-fiyuu-action]").forEach(function(form) {
|
|
506
|
-
form.addEventListener("submit", async function(e) {
|
|
507
|
-
e.preventDefault();
|
|
508
|
-
var route = form.getAttribute("data-fiyuu-action");
|
|
509
|
-
var statusId = form.getAttribute("data-fiyuu-status") || undefined;
|
|
510
|
-
var successAction = form.getAttribute("data-fiyuu-success") || "reload";
|
|
511
|
-
var loadingMsg = form.getAttribute("data-fiyuu-loading") || "İşleniyor...";
|
|
512
|
-
var data = {};
|
|
513
|
-
new FormData(form).forEach(function(value, key) { data[key] = value; });
|
|
514
|
-
form.querySelectorAll("input[type=checkbox]").forEach(function(input) {
|
|
515
|
-
data[input.name] = input.checked;
|
|
516
|
-
});
|
|
517
|
-
var body = await window.fiyuu.action(route, data, { status: statusId, loading: loadingMsg });
|
|
518
|
-
if (body.success) {
|
|
519
|
-
if (successAction === "reload") { setTimeout(function() { location.reload(); }, 300); }
|
|
520
|
-
else if (successAction.startsWith("close:")) { window.fiyuu.modal.close(successAction.slice(6)); }
|
|
521
|
-
}
|
|
522
|
-
});
|
|
523
|
-
});
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
})();`;
|
|
527
|
-
}
|
|
528
|
-
//# sourceMappingURL=client-runtime.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-runtime.js","sourceRoot":"","sources":["../../../../packages/runtime/src/client-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,UAAU,kBAAkB,CAAC,aAAqB;IACtD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+DAgZsD,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA8GtF,CAAC;AACP,CAAC"}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/runtime/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
|
package/dist/index.js
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/runtime/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
|
package/dist/inspector.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { FeatureRecord, FiyuuConfig } from "@fiyuu/core";
|
|
2
|
-
type InsightCategory = "security" | "performance" | "design" | "architecture";
|
|
3
|
-
type InsightSeverity = "low" | "medium" | "high";
|
|
4
|
-
export interface InsightItem {
|
|
5
|
-
id: string;
|
|
6
|
-
category: InsightCategory;
|
|
7
|
-
severity: InsightSeverity;
|
|
8
|
-
title: string;
|
|
9
|
-
summary: string;
|
|
10
|
-
recommendation: string;
|
|
11
|
-
route?: string;
|
|
12
|
-
file?: string;
|
|
13
|
-
fixable: boolean;
|
|
14
|
-
}
|
|
15
|
-
export interface InsightsReport {
|
|
16
|
-
generatedAt: string;
|
|
17
|
-
summary: {
|
|
18
|
-
total: number;
|
|
19
|
-
high: number;
|
|
20
|
-
medium: number;
|
|
21
|
-
low: number;
|
|
22
|
-
};
|
|
23
|
-
items: InsightItem[];
|
|
24
|
-
assistant: {
|
|
25
|
-
mode: "rule-only";
|
|
26
|
-
status: "ready";
|
|
27
|
-
details: string;
|
|
28
|
-
suggestions: string[];
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
interface BuildInsightsOptions {
|
|
32
|
-
rootDirectory: string;
|
|
33
|
-
appDirectory: string;
|
|
34
|
-
features: FeatureRecord[];
|
|
35
|
-
config?: FiyuuConfig;
|
|
36
|
-
}
|
|
37
|
-
export declare function buildInsightsReport(options: BuildInsightsOptions): Promise<InsightsReport>;
|
|
38
|
-
export {};
|
|
39
|
-
//# sourceMappingURL=inspector.d.ts.map
|
package/dist/inspector.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inspector.d.ts","sourceRoot":"","sources":["../../../../packages/runtime/src/inspector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9D,KAAK,eAAe,GAAG,UAAU,GAAG,aAAa,GAAG,QAAQ,GAAG,cAAc,CAAC;AAC9E,KAAK,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,EAAE;QACT,IAAI,EAAE,WAAW,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;CACH;AAED,UAAU,oBAAoB;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiBhG"}
|