@mauroandre/velojs 0.0.59 → 0.0.61
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/README.md +182 -1
- package/agent/AGENTS.md +84 -0
- package/agent/skills/velojs-actions/SKILL.md +32 -0
- package/agent/skills/velojs-hooks/SKILL.md +26 -0
- package/agent/skills/velojs-live-actions/SKILL.md +211 -0
- package/agent/skills/velojs-telemetry/SKILL.md +6 -1
- package/agent/skills/velojs-type-reference/SKILL.md +1 -0
- package/agent/skills/velojs-vite-plugin/SKILL.md +51 -2
- package/dist/channels.d.ts +117 -11
- package/dist/channels.js +459 -284
- package/dist/config.d.ts +8 -0
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.js +34 -32
- package/dist/leak-diagnostic.d.ts +77 -0
- package/dist/leak-diagnostic.js +14 -0
- package/dist/live-action.d.ts +86 -0
- package/dist/live-action.js +52 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +165 -143
- package/dist/telemetry-cli.d.ts +1 -0
- package/dist/telemetry-cli.js +116 -113
- package/dist/telemetry.d.ts +3 -3
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +500 -453
- package/dist/testing/subscription.d.ts +7 -0
- package/dist/testing/types.d.ts +43 -2
- package/dist/types.d.ts +12 -0
- package/dist/vite.d.ts +47 -1
- package/dist/vite.js +869 -401
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -40,5 +40,13 @@ export interface VeloConfig {
|
|
|
40
40
|
* @hono/vite-dev-server, não os substituem.
|
|
41
41
|
*/
|
|
42
42
|
devServerExclude?: (string | RegExp)[];
|
|
43
|
+
/**
|
|
44
|
+
* Padrões de glob (`*`, `**`, `?`) que declaram módulos só de servidor ao
|
|
45
|
+
* diagnóstico de vazamento server->client, casados contra o caminho do
|
|
46
|
+
* arquivo do módulo relativo à raiz do projeto, com `/` como separador
|
|
47
|
+
* (ex.: `serverOnly: ["src/fsm/**", "server/**"]`). Serve só ao
|
|
48
|
+
* diagnóstico — nada é bloqueado ou alterado por causa da declaração.
|
|
49
|
+
*/
|
|
50
|
+
serverOnly?: string[];
|
|
43
51
|
}
|
|
44
52
|
export declare function defineConfig(config: VeloConfig): VeloConfig;
|
package/dist/hooks.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { SocketHandler, SocketStub } from "./sockets.js";
|
|
|
4
4
|
import { __veloUpdatePending } from "./loader-store.js";
|
|
5
5
|
import { type Freshness } from "./live-loader.js";
|
|
6
6
|
export type { Freshness } from "./live-loader.js";
|
|
7
|
+
export { useLiveAction } from "./live-action.js";
|
|
8
|
+
export type { LiveActionStub, LiveActionHandle, } from "./live-action.js";
|
|
7
9
|
/**
|
|
8
10
|
* What `Loader()`/`useLoader()` return. `freshness` is the page-level state of
|
|
9
11
|
* the live loader: `"live"` (connected), `"stale"` (connection closed,
|
package/dist/hooks.js
CHANGED
|
@@ -4,14 +4,15 @@ import { useLocation as b, useParams as $, useSearch as B } from "wouter-preact"
|
|
|
4
4
|
import { refetchModule as C, loaderLoading as D, loaderEntry as N } from "./loader-store.js";
|
|
5
5
|
import { __veloUpdatePending as X } from "./loader-store.js";
|
|
6
6
|
import { loaderFreshness as w, moduleChannelFreshness as O } from "./live-loader.js";
|
|
7
|
+
import { useLiveAction as Z } from "./live-action.js";
|
|
7
8
|
function j() {
|
|
8
9
|
return typeof window > "u" ? {} : window.__VELO_BOOT__ ?? {};
|
|
9
10
|
}
|
|
10
|
-
function
|
|
11
|
+
function x(e) {
|
|
11
12
|
const t = e.value;
|
|
12
13
|
t === null || typeof t != "object" || (e.value = Array.isArray(t) ? [...t] : { ...t });
|
|
13
14
|
}
|
|
14
|
-
function
|
|
15
|
+
function F(e) {
|
|
15
16
|
return typeof window > "u" ? {
|
|
16
17
|
data: {
|
|
17
18
|
get value() {
|
|
@@ -38,7 +39,7 @@ function J(e) {
|
|
|
38
39
|
freshnessByChannel: S({})
|
|
39
40
|
};
|
|
40
41
|
}
|
|
41
|
-
function
|
|
42
|
+
function J(e, t) {
|
|
42
43
|
let n, r;
|
|
43
44
|
if (Array.isArray(e) ? r = e : (n = e, r = t), typeof window > "u") {
|
|
44
45
|
let a = null;
|
|
@@ -64,16 +65,16 @@ function M(e, t) {
|
|
|
64
65
|
freshness: w(),
|
|
65
66
|
freshnessByChannel: s({})
|
|
66
67
|
};
|
|
67
|
-
const
|
|
68
|
+
const c = N(n), o = D(n), u = () => C(n), h = w(), y = E(!0);
|
|
68
69
|
return m(() => {
|
|
69
|
-
y.current && (y.current = !1,
|
|
70
|
-
}, r ?? []), { data:
|
|
70
|
+
y.current && (y.current = !1, c.value !== null) || u();
|
|
71
|
+
}, r ?? []), { data: c, loading: o, refetch: u, freshness: h, freshnessByChannel: O(n) };
|
|
71
72
|
}
|
|
72
|
-
function
|
|
73
|
+
function M() {
|
|
73
74
|
const [, e] = b();
|
|
74
75
|
return e;
|
|
75
76
|
}
|
|
76
|
-
function
|
|
77
|
+
function q() {
|
|
77
78
|
return typeof window > "u" ? globalThis.__veloServerData?.getStore?.()?.__params ?? {} : $();
|
|
78
79
|
}
|
|
79
80
|
function G() {
|
|
@@ -88,14 +89,14 @@ function Q() {
|
|
|
88
89
|
return typeof window > "u" ? globalThis.__veloServerData?.getStore?.()?.__pathname ?? "/" : (b(), window.location.pathname);
|
|
89
90
|
}
|
|
90
91
|
function V(e, t = {}) {
|
|
91
|
-
const n = s(null), r = s(null),
|
|
92
|
+
const n = s(null), r = s(null), c = s(!1), o = s(null), { channel: u, enabled: h = !0 } = t;
|
|
92
93
|
return m(() => {
|
|
93
94
|
if (typeof window > "u" || !h) return;
|
|
94
95
|
if (!e.__path) {
|
|
95
96
|
console.warn("[velojs] useEventStream: stream has no __path");
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
98
|
-
|
|
99
|
+
c.value = !1, o.value = null;
|
|
99
100
|
const y = u ? `${e.__path}?channel=${encodeURIComponent(u)}` : e.__path, a = new EventSource(y);
|
|
100
101
|
return a.addEventListener("snapshot", (g) => {
|
|
101
102
|
try {
|
|
@@ -111,47 +112,47 @@ function V(e, t = {}) {
|
|
|
111
112
|
}
|
|
112
113
|
}), a.addEventListener("heartbeat", () => {
|
|
113
114
|
}), a.addEventListener("close", () => {
|
|
114
|
-
|
|
115
|
+
c.value = !0, a.close();
|
|
115
116
|
}), a.addEventListener("error", () => {
|
|
116
|
-
a.readyState === EventSource.CLOSED && (
|
|
117
|
+
a.readyState === EventSource.CLOSED && (c.value = !0);
|
|
117
118
|
}), () => {
|
|
118
119
|
a.close();
|
|
119
120
|
};
|
|
120
|
-
}, [e, u, h]), { data: n, snapshot: r, closed:
|
|
121
|
+
}, [e, u, h]), { data: n, snapshot: r, closed: c, error: o };
|
|
121
122
|
}
|
|
122
123
|
function z(e, t = {}) {
|
|
123
|
-
const n = s("connecting"), r = s(null),
|
|
124
|
+
const n = s("connecting"), r = s(null), c = s(null), o = E(null), u = E([]), { channel: h, onMessage: y, onOpen: a, onClose: g, onError: v, enabled: L = !0 } = t;
|
|
124
125
|
return m(() => {
|
|
125
126
|
if (typeof window > "u" || !L) return;
|
|
126
127
|
if (!e.__path) {
|
|
127
128
|
console.warn("[velojs] useSocket: stub has no __path");
|
|
128
129
|
return;
|
|
129
130
|
}
|
|
130
|
-
n.value = "connecting",
|
|
131
|
+
n.value = "connecting", c.value = null;
|
|
131
132
|
const d = `${window.location.protocol === "https:" ? "wss:" : "ws:"}//${window.location.host}`, i = h ? `${d}${e.__path}?channel=${encodeURIComponent(h)}` : `${d}${e.__path}`, f = new WebSocket(i);
|
|
132
133
|
return f.binaryType = "arraybuffer", o.current = f, f.addEventListener("open", () => {
|
|
133
134
|
n.value = "open";
|
|
134
|
-
const
|
|
135
|
+
const l = u.current;
|
|
135
136
|
u.current = [];
|
|
136
|
-
for (const _ of
|
|
137
|
+
for (const _ of l)
|
|
137
138
|
try {
|
|
138
139
|
f.send(_);
|
|
139
140
|
} catch {
|
|
140
141
|
}
|
|
141
142
|
a?.();
|
|
142
|
-
}), f.addEventListener("message", (
|
|
143
|
+
}), f.addEventListener("message", (l) => {
|
|
143
144
|
let _;
|
|
144
|
-
if (typeof
|
|
145
|
-
_ =
|
|
146
|
-
else if (
|
|
147
|
-
_ = new Uint8Array(
|
|
145
|
+
if (typeof l.data == "string")
|
|
146
|
+
_ = l.data;
|
|
147
|
+
else if (l.data instanceof ArrayBuffer)
|
|
148
|
+
_ = new Uint8Array(l.data);
|
|
148
149
|
else
|
|
149
150
|
return;
|
|
150
151
|
r.value = _, y?.(_);
|
|
151
|
-
}), f.addEventListener("close", (
|
|
152
|
-
n.value = "closed", o.current = null, g?.(
|
|
153
|
-
}), f.addEventListener("error", (
|
|
154
|
-
|
|
152
|
+
}), f.addEventListener("close", (l) => {
|
|
153
|
+
n.value = "closed", o.current = null, g?.(l);
|
|
154
|
+
}), f.addEventListener("error", (l) => {
|
|
155
|
+
c.value = l, v?.(l);
|
|
155
156
|
}), () => {
|
|
156
157
|
o.current = null;
|
|
157
158
|
try {
|
|
@@ -176,17 +177,18 @@ function z(e, t = {}) {
|
|
|
176
177
|
i.close(p, d);
|
|
177
178
|
} catch {
|
|
178
179
|
}
|
|
179
|
-
}, status: n, lastMessage: r, error:
|
|
180
|
+
}, status: n, lastMessage: r, error: c };
|
|
180
181
|
}
|
|
181
182
|
export {
|
|
182
|
-
|
|
183
|
+
F as Loader,
|
|
183
184
|
X as __veloUpdatePending,
|
|
184
|
-
|
|
185
|
+
x as touch,
|
|
185
186
|
j as useBoot,
|
|
186
187
|
V as useEventStream,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
Z as useLiveAction,
|
|
189
|
+
J as useLoader,
|
|
190
|
+
M as useNavigate,
|
|
191
|
+
q as useParams,
|
|
190
192
|
Q as usePathname,
|
|
191
193
|
G as useQuery,
|
|
192
194
|
z as useSocket
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** One import in the chain: `from` imports `to` at `line` (`null` = generated). */
|
|
2
|
+
export interface LeakLink {
|
|
3
|
+
from: string;
|
|
4
|
+
line: number | null;
|
|
5
|
+
to: string;
|
|
6
|
+
}
|
|
7
|
+
export interface LeakItem {
|
|
8
|
+
/** Display path of the leaked server module. */
|
|
9
|
+
target: string;
|
|
10
|
+
/** Why it qualifies as a server module (English). */
|
|
11
|
+
qualifiers: string[];
|
|
12
|
+
/** Full import chain, client entry -> target, one link per import. */
|
|
13
|
+
chain: LeakLink[];
|
|
14
|
+
/** Index in `chain` of the entry-point link — the cut. */
|
|
15
|
+
entryIndex: number;
|
|
16
|
+
}
|
|
17
|
+
export interface LeakReport {
|
|
18
|
+
leaks: LeakItem[];
|
|
19
|
+
/** True when the enumeration stopped at its safety budget. */
|
|
20
|
+
truncated: boolean;
|
|
21
|
+
/** Stable fingerprint of what ships to the client (dev re-emit trigger). */
|
|
22
|
+
signature: string;
|
|
23
|
+
/** How many modules the walk visited (informational). */
|
|
24
|
+
moduleCount: number;
|
|
25
|
+
}
|
|
26
|
+
export type ResolveFn = (spec: string, importer: string) => string | null;
|
|
27
|
+
export interface ModuleInfo {
|
|
28
|
+
file: string;
|
|
29
|
+
display: string;
|
|
30
|
+
edges: RawEdge[];
|
|
31
|
+
builtins: string[];
|
|
32
|
+
patterns: string[];
|
|
33
|
+
}
|
|
34
|
+
export interface CachedModule {
|
|
35
|
+
mtimeMs: number;
|
|
36
|
+
info: ModuleInfo;
|
|
37
|
+
}
|
|
38
|
+
export interface LeakAnalyzerOptions {
|
|
39
|
+
/** Project root — display paths and `serverOnly` matching are relative to it. */
|
|
40
|
+
rootDir: string;
|
|
41
|
+
/** Absolute app directory (velo:transform's scope). */
|
|
42
|
+
appDir: string;
|
|
43
|
+
/** Routes file name inside appDir (default "routes.tsx"). */
|
|
44
|
+
routesFile?: string | undefined;
|
|
45
|
+
/** The client entry's import specifiers (the virtual entry's imports). */
|
|
46
|
+
entrySpecs: string[];
|
|
47
|
+
/** Glob patterns declaring server-only modules (VeloConfig.serverOnly). */
|
|
48
|
+
serverOnly?: readonly string[] | undefined;
|
|
49
|
+
/** Import resolver: (specifier, importer file) -> absolute file or null. */
|
|
50
|
+
resolve?: ResolveFn | undefined;
|
|
51
|
+
/** Optional parse cache shared across runs (dev). */
|
|
52
|
+
cache?: Map<string, CachedModule> | undefined;
|
|
53
|
+
}
|
|
54
|
+
interface RawEdge {
|
|
55
|
+
spec: string;
|
|
56
|
+
line: number;
|
|
57
|
+
kind: "static" | "dynamic";
|
|
58
|
+
locals: string[];
|
|
59
|
+
}
|
|
60
|
+
/** True when the specifier names a Node builtin (with or without the `node:` prefix). */
|
|
61
|
+
export declare function isBuiltinSpec(spec: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Compiles a glob (`*` = within a segment, `**` across segments, `?` = one
|
|
64
|
+
* char) into a full-match regex over the module path relative to the project
|
|
65
|
+
* root, always with `/` separators.
|
|
66
|
+
*/
|
|
67
|
+
export declare function globToRegex(glob: string): RegExp;
|
|
68
|
+
/**
|
|
69
|
+
* Resolution mirroring what the client build follows: relative specifiers with
|
|
70
|
+
* TS extension completion, bare specifiers through `node_modules` with the
|
|
71
|
+
* package's browser/import `exports` conditions. Returns null for anything
|
|
72
|
+
* that does not resolve to a file (external, virtual or unresolvable).
|
|
73
|
+
*/
|
|
74
|
+
export declare function defaultResolve(spec: string, importer: string): string | null;
|
|
75
|
+
export declare function analyzeClientLeaks(options: LeakAnalyzerOptions): LeakReport;
|
|
76
|
+
export declare function formatLeakReport(report: LeakReport): string;
|
|
77
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import "node:fs";
|
|
2
|
+
import "node:path";
|
|
3
|
+
import "node:module";
|
|
4
|
+
import "@babel/parser";
|
|
5
|
+
import "@babel/traverse";
|
|
6
|
+
import "@babel/types";
|
|
7
|
+
import { a as s, d as l, f, g, i as n } from "./vite.js";
|
|
8
|
+
export {
|
|
9
|
+
s as analyzeClientLeaks,
|
|
10
|
+
l as defaultResolve,
|
|
11
|
+
f as formatLeakReport,
|
|
12
|
+
g as globToRegex,
|
|
13
|
+
n as isBuiltinSpec
|
|
14
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live actions — client runtime.
|
|
3
|
+
*
|
|
4
|
+
* A tab is not a route: it is client state, and its content loads at open time
|
|
5
|
+
* from an action with its own arguments (the resource id, the file path). When
|
|
6
|
+
* that content is a **value that tracks server state over time**, the action
|
|
7
|
+
* declares interest in living (`liveActions` in the route module) and the tab
|
|
8
|
+
* subscribes:
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* const { data, loading, freshness } = useLiveAction(action_abrirFicha, { id });
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* The hook receives the action itself — its client stub, which the Vite plugin
|
|
15
|
+
* marks with the subscription address (`__path`, the socket-stub ruler) — and
|
|
16
|
+
* the args. It opens ONE SSE connection per subscription at
|
|
17
|
+
* `GET /_live/{moduleId}/{actionName}?_args=<json>`; the connect snapshot (the
|
|
18
|
+
* action executed once with the declared args) is the whole loading gesture —
|
|
19
|
+
* there is no initial POST. Every `emit()` in any of the action's declared
|
|
20
|
+
* channels re-executes the action server-side with the same args and pushes the
|
|
21
|
+
* fresh value, which **replaces** `data` whole (no merge — the updated payload
|
|
22
|
+
* has the same shape as the original answer).
|
|
23
|
+
*
|
|
24
|
+
* The subscription's life is the mount: the tab component unmounts (tab closed,
|
|
25
|
+
* page left) and the connection closes — nothing arrives afterwards and the
|
|
26
|
+
* server holds nothing for the gone. It remounts (tab reopened, refresh
|
|
27
|
+
* restored the tabs) and the subscription is born again with a snapshot of the
|
|
28
|
+
* current state: reopening is indistinguishable from never having closed. The
|
|
29
|
+
* args are the identity — changing them reconnects (new subscription, new
|
|
30
|
+
* snapshot), the twin of the loader connection keyed by its route params.
|
|
31
|
+
*
|
|
32
|
+
* `freshness` is the subscription's own `"live"` / `"stale"` / `"error"` signal
|
|
33
|
+
* — the same three states and the same 60s silence detector as the live loader
|
|
34
|
+
* — and it never touches the page aggregate: a stale tab does not stale the
|
|
35
|
+
* page, and the other way around.
|
|
36
|
+
*
|
|
37
|
+
* On the server (SSR) the hook does not connect: the tab is client state the
|
|
38
|
+
* server does not know, so it returns `data` null with `loading` true. In a
|
|
39
|
+
* static build the load really failed (there is no server to run the action):
|
|
40
|
+
* no connection is opened and the handle is `data` undefined, `loading` false,
|
|
41
|
+
* `freshness` `"error"` — the deliberate contrast with a channel, which stays
|
|
42
|
+
* `"live"` because there is nothing to sync.
|
|
43
|
+
*/
|
|
44
|
+
import { type Signal } from "@preact/signals";
|
|
45
|
+
import { type Freshness } from "./live-loader.js";
|
|
46
|
+
/**
|
|
47
|
+
* The client stub of a live action — the form the Vite plugin generates for an
|
|
48
|
+
* action the module declares in `liveActions`. The call signature is the
|
|
49
|
+
* action's own (typed from its `ActionArgs` and return); the live marks are
|
|
50
|
+
* what `useLiveAction` reads to find the subscription address.
|
|
51
|
+
*/
|
|
52
|
+
export interface LiveActionStub<TArgs extends Record<string, unknown>, TData> {
|
|
53
|
+
(args: {
|
|
54
|
+
body: TArgs;
|
|
55
|
+
}): Promise<TData>;
|
|
56
|
+
/** Set by the Vite plugin on every stub the module declares live. */
|
|
57
|
+
__isVeloLiveAction?: boolean;
|
|
58
|
+
/** `/_live/{moduleId}/{actionName}` — the subscription address. */
|
|
59
|
+
__path?: string;
|
|
60
|
+
}
|
|
61
|
+
/** What `useLiveAction` returns. */
|
|
62
|
+
export interface LiveActionHandle<T> {
|
|
63
|
+
/** The action's return, replaced whole by every snapshot. */
|
|
64
|
+
data: Signal<T | null | undefined>;
|
|
65
|
+
/** True until the first snapshot or error of the current subscription. */
|
|
66
|
+
loading: Signal<boolean>;
|
|
67
|
+
/** The subscription's own freshness — never the page aggregate's. */
|
|
68
|
+
freshness: Signal<Freshness>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Subscribes to a live action and reads its value as it tracks server state.
|
|
72
|
+
*
|
|
73
|
+
* The connection is keyed by the args: passing different args is a different
|
|
74
|
+
* subscription (the old one closes, the new one opens with a fresh snapshot).
|
|
75
|
+
* The life is the mount — unmount closes, remount reopens with the current
|
|
76
|
+
* state. See the module docs for the full contract.
|
|
77
|
+
*
|
|
78
|
+
* ```tsx
|
|
79
|
+
* export const Component = () => {
|
|
80
|
+
* const { data, loading, freshness } = useLiveAction(action_abrirFicha, { id: 7 });
|
|
81
|
+
* if (loading.value) return <div class="tab-loading" />;
|
|
82
|
+
* return <article class={freshness.value}>{data.value?.nome}</article>;
|
|
83
|
+
* };
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare function useLiveAction<TArgs extends Record<string, unknown>, TData>(action: LiveActionStub<TArgs, TData>, args: TArgs): LiveActionHandle<TData>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useSignal as s } from "@preact/signals";
|
|
2
|
+
import { useEffect as d } from "preact/hooks";
|
|
3
|
+
import { CHANNEL_SILENCE_MS as _ } from "./live-loader.js";
|
|
4
|
+
const p = "snapshot";
|
|
5
|
+
function S(n, v) {
|
|
6
|
+
const l = s(null), t = s(!0), e = s("live"), i = JSON.stringify(v ?? {});
|
|
7
|
+
return d(() => {
|
|
8
|
+
if (typeof window > "u") return;
|
|
9
|
+
if (typeof __VELO_STATIC__ < "u" && __VELO_STATIC__) {
|
|
10
|
+
t.value = !1, e.value = "error", l.value = void 0;
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (!n.__isVeloLiveAction || !n.__path) {
|
|
14
|
+
console.warn(
|
|
15
|
+
'[velojs] useLiveAction: this action has no live declaration — add it to the module\'s `liveActions` export (e.g. `export const liveActions = { abrirFicha: ["fichaProjeto"] };`).'
|
|
16
|
+
), t.value = !1, e.value = "error";
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
t.value = !0;
|
|
20
|
+
const f = `${n.__path}?_args=${encodeURIComponent(i)}`, o = new EventSource(f);
|
|
21
|
+
let r = null;
|
|
22
|
+
const u = () => {
|
|
23
|
+
r !== null && clearTimeout(r), r = setTimeout(() => {
|
|
24
|
+
r = null, e.value = "stale";
|
|
25
|
+
}, _);
|
|
26
|
+
};
|
|
27
|
+
return u(), o.addEventListener(p, (a) => {
|
|
28
|
+
try {
|
|
29
|
+
l.value = JSON.parse(a.data), t.value = !1, e.value = "live", u();
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
}), o.addEventListener("error", (a) => {
|
|
33
|
+
const c = a.data;
|
|
34
|
+
if (typeof c == "string" && c.length > 0) {
|
|
35
|
+
t.value = !1, e.value = "error";
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
e.value = "stale";
|
|
39
|
+
}), o.addEventListener("close", () => {
|
|
40
|
+
e.value = "stale";
|
|
41
|
+
}), () => {
|
|
42
|
+
r !== null && clearTimeout(r);
|
|
43
|
+
try {
|
|
44
|
+
o.close();
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}, [n.__path, i]), { data: l, loading: t, freshness: e };
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
S as useLiveAction
|
|
52
|
+
};
|
package/dist/server.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Hono } from "hono";
|
|
|
2
2
|
import type { AppRoutes } from "./types.js";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
export { emit, inspectChannels, registerChannels } from "./channels.js";
|
|
5
|
-
export type { ChannelDefinition, ChannelMap, ChannelScopeContext, ChannelGroupOpenContext, ChannelGroupCloseContext, ChannelScopeResult, ChannelRegistryOptions, ChannelEmitModule, ChannelEmitKind, ChannelSlice, ChannelInspectGroup, ChannelInspectChannel, ChannelInspectWindow, ChannelInspectReport, } from "./channels.js";
|
|
5
|
+
export type { ChannelDefinition, ChannelMap, ChannelScopeContext, ChannelGroupOpenContext, ChannelGroupCloseContext, ChannelScopeResult, ChannelRegistryOptions, ChannelEmitModule, ChannelEmitKind, ChannelSlice, ChannelInspectGroup, ChannelInspectChannel, ChannelInspectWindow, ChannelInspectLiveAction, ChannelInspectReport, } from "./channels.js";
|
|
6
6
|
export declare const serverDataStorage: AsyncLocalStorage<Record<string, unknown>>;
|
|
7
7
|
type ServerCallback = (server: import("http").Server) => void;
|
|
8
8
|
export declare function onServer(fn: ServerCallback): void;
|