@mauroandre/velojs 0.0.42 → 0.0.44
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/agent/skills/velojs-loaders/SKILL.md +4 -2
- package/dist/graph-viewer.js +16 -15
- package/dist/loader-store.d.ts +11 -6
- package/dist/loader-store.js +77 -61
- package/package.json +1 -1
|
@@ -127,8 +127,10 @@ Understanding the data flow helps you debug issues:
|
|
|
127
127
|
|
|
128
128
|
**Client-side navigation (SPA):**
|
|
129
129
|
1. User clicks a link
|
|
130
|
-
2. VeloJS
|
|
130
|
+
2. VeloJS marks stale the modules whose **declared params** changed — or that **were not part of the previous location** (they unmounted and are remounting now)
|
|
131
131
|
3. One `?_data=1` request serves all of them
|
|
132
132
|
4. Only the stale modules are written — a module the client owns locally (a filtered list, an optimistic edit) is left alone
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
The second rule is why returning to a page always shows fresh data: leaving `/` for `/leads` unmounts the Dashboard, so navigating back re-runs its loader. The first rule is why `/leads/1` → `/leads/2` refetches.
|
|
135
|
+
|
|
136
|
+
That last point is why a layout at `/admin/empresas` keeps a filtered list while you navigate among its children: it stays matched the whole time — no param changed and it never unmounted, so nothing invalidates it. (Leaving the subtree entirely and coming back *does* revalidate it — the layout remounted.)
|
package/dist/graph-viewer.js
CHANGED
|
@@ -60,7 +60,8 @@ var ctx = canvas.getContext("2d");
|
|
|
60
60
|
var W = 0, H = 0;
|
|
61
61
|
|
|
62
62
|
function resize() {
|
|
63
|
-
|
|
63
|
+
var tb = document.getElementById("topbar");
|
|
64
|
+
W = window.innerWidth; H = window.innerHeight - tb.offsetHeight;
|
|
64
65
|
canvas.width = W * devicePixelRatio; canvas.height = H * devicePixelRatio;
|
|
65
66
|
canvas.style.width = W + "px"; canvas.style.height = H + "px";
|
|
66
67
|
ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);
|
|
@@ -240,26 +241,26 @@ function nodeAt(sx, sy) {
|
|
|
240
241
|
return null;
|
|
241
242
|
}
|
|
242
243
|
canvas.addEventListener("mousedown", function (e) {
|
|
243
|
-
var n = nodeAt(e.
|
|
244
|
+
var n = nodeAt(e.offsetX, e.offsetY);
|
|
244
245
|
if (n && view === "modules") { dragNode = n; alpha = Math.max(alpha, 0.3); }
|
|
245
246
|
else panning = true;
|
|
246
|
-
lastX = e.
|
|
247
|
+
lastX = e.offsetX; lastY = e.offsetY; moved = false;
|
|
247
248
|
});
|
|
248
249
|
canvas.addEventListener("mousemove", function (e) {
|
|
249
|
-
var dx = e.
|
|
250
|
+
var dx = e.offsetX - lastX, dy = e.offsetY - lastY;
|
|
250
251
|
if (Math.abs(dx) + Math.abs(dy) > 3) moved = true;
|
|
251
|
-
if (dragNode) { var w = toWorld(e.
|
|
252
|
+
if (dragNode) { var w = toWorld(e.offsetX, e.offsetY); dragNode.x = w[0]; dragNode.y = w[1]; dragNode.vx = dragNode.vy = 0; }
|
|
252
253
|
else if (panning) { cam.x += dx; cam.y += dy; }
|
|
253
254
|
else {
|
|
254
|
-
var n = nodeAt(e.
|
|
255
|
+
var n = nodeAt(e.offsetX, e.offsetY);
|
|
255
256
|
hoverHL = n ? { list: relatedNodes(n), origin: n } : null;
|
|
256
257
|
canvas.style.cursor = n ? "pointer" : "grab";
|
|
257
258
|
}
|
|
258
|
-
lastX = e.
|
|
259
|
+
lastX = e.offsetX; lastY = e.offsetY;
|
|
259
260
|
});
|
|
260
261
|
canvas.addEventListener("mouseup", function (e) {
|
|
261
262
|
if (!moved) {
|
|
262
|
-
var n = nodeAt(e.
|
|
263
|
+
var n = nodeAt(e.offsetX, e.offsetY);
|
|
263
264
|
if (n) {
|
|
264
265
|
pinnedHL = { list: relatedNodes(n), origin: n };
|
|
265
266
|
var id = view === "modules" ? n.id : n.data.moduleId;
|
|
@@ -274,9 +275,9 @@ canvas.addEventListener("mouseup", function (e) {
|
|
|
274
275
|
canvas.addEventListener("wheel", function (e) {
|
|
275
276
|
e.preventDefault();
|
|
276
277
|
var k = Math.exp(-e.deltaY * 0.0012);
|
|
277
|
-
var w = toWorld(e.
|
|
278
|
+
var w = toWorld(e.offsetX, e.offsetY);
|
|
278
279
|
cam.k *= k;
|
|
279
|
-
cam.x = e.
|
|
280
|
+
cam.x = e.offsetX - w[0] * cam.k; cam.y = e.offsetY - w[1] * cam.k;
|
|
280
281
|
}, { passive: false });
|
|
281
282
|
|
|
282
283
|
// ---------- rendering ----------
|
|
@@ -389,8 +390,8 @@ fetch("/graph.json").then(function (r) { return r.json(); }).then(function (g) {
|
|
|
389
390
|
<\/script>
|
|
390
391
|
</body>
|
|
391
392
|
</html>`;
|
|
392
|
-
async function
|
|
393
|
-
const i = l.join(
|
|
393
|
+
async function m(a) {
|
|
394
|
+
const i = l.join(a, ".velojs", "graph.json"), o = r.createServer((n, e) => {
|
|
394
395
|
if (n.url === "/graph.json") {
|
|
395
396
|
let t;
|
|
396
397
|
try {
|
|
@@ -405,12 +406,12 @@ async function f(o) {
|
|
|
405
406
|
e.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }), e.end(s);
|
|
406
407
|
});
|
|
407
408
|
return await new Promise((n) => {
|
|
408
|
-
|
|
409
|
-
const e =
|
|
409
|
+
o.listen(0, "127.0.0.1", () => {
|
|
410
|
+
const e = o.address(), t = typeof e == "object" && e ? e.port : 0;
|
|
410
411
|
n(`http://127.0.0.1:${t}`);
|
|
411
412
|
});
|
|
412
413
|
});
|
|
413
414
|
}
|
|
414
415
|
export {
|
|
415
|
-
|
|
416
|
+
m as serveGraphViewer
|
|
416
417
|
};
|
package/dist/loader-store.d.ts
CHANGED
|
@@ -7,9 +7,12 @@
|
|
|
7
7
|
* no module-scope mirror to keep in sync.
|
|
8
8
|
*
|
|
9
9
|
* Invalidation follows the route tree: an entry is stale when the params its own
|
|
10
|
-
* route declares have changed
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* route declares have changed — or when the module was not part of the previous
|
|
11
|
+
* location's matched chain (it unmounted and is now remounting). The first rule
|
|
12
|
+
* mirrors the server (a loader re-runs when a request arrives with different
|
|
13
|
+
* params); the second mirrors user expectation (returning to a page shows fresh
|
|
14
|
+
* data). A layout keeps its data while navigating among its children because it
|
|
15
|
+
* stays matched the whole time — its client-owned state survives.
|
|
13
16
|
*
|
|
14
17
|
* Deliberately NOT invalidated by:
|
|
15
18
|
* - a query-string change: `routes.tsx` declares path params, never `?x=`, so
|
|
@@ -32,14 +35,16 @@ export declare function registerRoutePatterns(routes: AppRoutes): void;
|
|
|
32
35
|
/**
|
|
33
36
|
* Extract the params a pattern declares from a pathname. Layout patterns are
|
|
34
37
|
* prefixes of the URL (`/x/:id` covers `/x/1/tab`), mirroring how the client
|
|
35
|
-
* router matches them, so the match is prefix-tolerant.
|
|
38
|
+
* router matches them, so the match is prefix-tolerant. Leaf patterns (routes
|
|
39
|
+
* without children) match exactly, mirroring wouter's exact `<Route>` for them.
|
|
36
40
|
*
|
|
37
41
|
* Returns null when the pattern does not cover the pathname at all.
|
|
38
42
|
*/
|
|
39
|
-
export declare function extractParams(pattern: string, pathname: string): Record<string, string> | null;
|
|
43
|
+
export declare function extractParams(pattern: string, pathname: string, exact?: boolean): Record<string, string> | null;
|
|
40
44
|
/**
|
|
41
45
|
* Called on every client navigation. Refetches exactly the entries whose
|
|
42
|
-
* declared params changed
|
|
46
|
+
* declared params changed OR that were not matched at the previous location
|
|
47
|
+
* (they unmounted and are remounting now), in one coalesced request.
|
|
43
48
|
*/
|
|
44
49
|
export declare function syncLocation(pathname: string): void;
|
|
45
50
|
/** Explicit refresh. Never coalesced: a caller asking after a mutation must not
|
package/dist/loader-store.js
CHANGED
|
@@ -1,103 +1,119 @@
|
|
|
1
|
-
import { signal as
|
|
2
|
-
const
|
|
3
|
-
let u =
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { signal as d } from "@preact/signals";
|
|
2
|
+
const S = d(!1), c = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Map();
|
|
3
|
+
let u = /* @__PURE__ */ new Set();
|
|
4
|
+
const l = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new WeakSet();
|
|
5
|
+
let w = !1;
|
|
6
|
+
function E(t) {
|
|
7
|
+
v();
|
|
6
8
|
let e = c.get(t);
|
|
7
|
-
return e || (e =
|
|
9
|
+
return e || (e = d(null), c.set(t, e)), e;
|
|
8
10
|
}
|
|
9
|
-
function
|
|
10
|
-
let e =
|
|
11
|
-
return e || (e =
|
|
11
|
+
function g(t) {
|
|
12
|
+
let e = _.get(t);
|
|
13
|
+
return e || (e = d(!1), _.set(t, e)), e;
|
|
12
14
|
}
|
|
13
|
-
function
|
|
14
|
-
if (
|
|
15
|
-
|
|
15
|
+
function v() {
|
|
16
|
+
if (w || typeof window > "u") return;
|
|
17
|
+
w = !0;
|
|
16
18
|
const t = window.__PAGE_DATA__;
|
|
17
19
|
if (t)
|
|
18
20
|
for (const e of Object.keys(t)) {
|
|
19
21
|
if (e.startsWith("__")) continue;
|
|
20
22
|
let n = c.get(e);
|
|
21
|
-
n || (n =
|
|
23
|
+
n || (n = d(null), c.set(e, n)), n.value = t[e];
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
|
-
function
|
|
25
|
-
if (
|
|
26
|
-
|
|
26
|
+
function x(t) {
|
|
27
|
+
if (y.has(t)) return;
|
|
28
|
+
y.add(t);
|
|
27
29
|
const e = (n) => {
|
|
28
30
|
for (const o of n) {
|
|
29
31
|
const i = o.module?.metadata;
|
|
30
|
-
i?.moduleId && i.fullPath !== void 0 &&
|
|
32
|
+
i?.moduleId && i.fullPath !== void 0 && (f.set(i.moduleId, i.fullPath), (!o.children || o.children.length === 0) && h.add(i.moduleId)), o.children && e(o.children);
|
|
31
33
|
}
|
|
32
34
|
};
|
|
33
35
|
if (e(t), typeof window < "u") {
|
|
34
|
-
|
|
35
|
-
for (const n of c.keys())
|
|
36
|
+
v();
|
|
37
|
+
for (const n of c.keys()) M(n, window.location.pathname);
|
|
38
|
+
u = L(window.location.pathname);
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
|
-
const
|
|
39
|
-
function
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
const P = (t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
42
|
+
function m(t, e, n = !1) {
|
|
43
|
+
const o = [], i = t.split("/").map((s) => s.startsWith(":") ? (o.push(s.slice(1)), "([^/]+)") : P(s)).join("/"), a = e.match(
|
|
44
|
+
new RegExp(n ? `^${i}/?$` : `^${i}(?:/.*)?$`)
|
|
45
|
+
);
|
|
46
|
+
if (!a) return null;
|
|
47
|
+
const r = {};
|
|
48
|
+
return o.forEach((s, A) => {
|
|
49
|
+
r[s] = a[A + 1];
|
|
50
|
+
}), r;
|
|
46
51
|
}
|
|
47
|
-
function
|
|
48
|
-
const n =
|
|
52
|
+
function O(t, e) {
|
|
53
|
+
const n = f.get(t);
|
|
54
|
+
return n === void 0 ? !1 : m(n, e, h.has(t)) !== null;
|
|
55
|
+
}
|
|
56
|
+
function L(t) {
|
|
57
|
+
const e = /* @__PURE__ */ new Set();
|
|
58
|
+
for (const n of f.keys())
|
|
59
|
+
O(n, t) && e.add(n);
|
|
60
|
+
return e;
|
|
61
|
+
}
|
|
62
|
+
function k(t, e) {
|
|
63
|
+
const n = f.get(t);
|
|
49
64
|
if (n === void 0) return null;
|
|
50
|
-
const o =
|
|
65
|
+
const o = m(n, e, h.has(t));
|
|
51
66
|
return o === null ? null : JSON.stringify(o);
|
|
52
67
|
}
|
|
53
|
-
function
|
|
54
|
-
const n =
|
|
55
|
-
n !== null &&
|
|
68
|
+
function M(t, e) {
|
|
69
|
+
const n = k(t, e);
|
|
70
|
+
n !== null && p.set(t, n);
|
|
56
71
|
}
|
|
57
|
-
function
|
|
72
|
+
function H(t) {
|
|
58
73
|
if (typeof __VELO_STATIC__ < "u" && __VELO_STATIC__) return `${t === "/" ? "" : t}/index.json`;
|
|
59
74
|
const n = new URLSearchParams(window.location.search);
|
|
60
75
|
return n.set("_data", "1"), `${t}?${n.toString()}`;
|
|
61
76
|
}
|
|
62
|
-
async function
|
|
77
|
+
async function $(t, e, n) {
|
|
63
78
|
if (typeof window > "u" || t.length === 0) return;
|
|
64
|
-
const o =
|
|
65
|
-
for (const a of t)
|
|
66
|
-
let i = n ?
|
|
67
|
-
i || (i = fetch(o, { cache: "no-cache" }).then((a) => a.json()), n && (
|
|
68
|
-
}).then(() =>
|
|
79
|
+
const o = H(e);
|
|
80
|
+
for (const a of t) g(a).value = !0;
|
|
81
|
+
let i = n ? l.get(o) : void 0;
|
|
82
|
+
i || (i = fetch(o, { cache: "no-cache" }).then((a) => a.json()), n && (l.set(o, i), i.catch(() => {
|
|
83
|
+
}).then(() => l.delete(o))));
|
|
69
84
|
try {
|
|
70
85
|
const a = await i;
|
|
71
|
-
typeof __VELO_BUILD_HASH__ < "u" && a.__buildHash && a.__buildHash !== __VELO_BUILD_HASH__ && (
|
|
86
|
+
typeof __VELO_BUILD_HASH__ < "u" && a.__buildHash && a.__buildHash !== __VELO_BUILD_HASH__ && (S.value = !0);
|
|
72
87
|
for (const r of t)
|
|
73
|
-
r in a && (
|
|
88
|
+
r in a && (E(r).value = a[r], M(r, e));
|
|
74
89
|
} catch {
|
|
75
90
|
} finally {
|
|
76
|
-
for (const a of t)
|
|
91
|
+
for (const a of t) g(a).value = !1;
|
|
77
92
|
}
|
|
78
93
|
}
|
|
79
|
-
function
|
|
94
|
+
function T(t) {
|
|
80
95
|
if (typeof window > "u") return;
|
|
81
|
-
const e = [];
|
|
82
|
-
for (const
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
const e = [], n = L(t);
|
|
97
|
+
for (const o of c.keys()) {
|
|
98
|
+
if (!n.has(o)) continue;
|
|
99
|
+
const i = k(o, t);
|
|
100
|
+
p.get(o) === i && u.has(o) || e.push(o);
|
|
85
101
|
}
|
|
86
|
-
|
|
102
|
+
u = n, $(e, t, !0);
|
|
87
103
|
}
|
|
88
|
-
function
|
|
89
|
-
typeof window > "u" ||
|
|
104
|
+
function U(t) {
|
|
105
|
+
typeof window > "u" || $([t], window.location.pathname, !1);
|
|
90
106
|
}
|
|
91
|
-
function
|
|
92
|
-
c.clear(),
|
|
107
|
+
function D() {
|
|
108
|
+
c.clear(), _.clear(), f.clear(), h.clear(), p.clear(), u = /* @__PURE__ */ new Set(), l.clear(), w = !1, S.value = !1;
|
|
93
109
|
}
|
|
94
110
|
export {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
D as __resetLoaderStore,
|
|
112
|
+
S as __veloUpdatePending,
|
|
113
|
+
m as extractParams,
|
|
114
|
+
E as loaderEntry,
|
|
115
|
+
g as loaderLoading,
|
|
116
|
+
U as refetchModule,
|
|
117
|
+
x as registerRoutePatterns,
|
|
118
|
+
T as syncLocation
|
|
103
119
|
};
|