pulse-ui-client 0.1.51 → 0.1.54

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 CHANGED
@@ -1,15 +1,122 @@
1
- # pulse-client
1
+ # Pulse JS Client
2
2
 
3
- To install dependencies:
3
+ React client library that renders server-driven VDOM and handles WebSocket communication with the Pulse Python server.
4
4
 
5
- ```bash
6
- bun install
5
+ ## Architecture
6
+
7
+ Client receives VDOM updates via Socket.IO and renders using React. Events are serialized and sent back to server.
8
+
9
+ ```
10
+ ┌─────────────────────────────────────────────────────────────────┐
11
+ │ Browser │
12
+ │ ┌──────────────┐ ┌────────────┐ ┌─────────────────────────┐ │
13
+ │ │ PulseProvider│──│ PulseClient│──│ Transport (Socket.IO) │ │
14
+ │ └──────────────┘ └────────────┘ └─────────────────────────┘ │
15
+ │ │ │ │
16
+ │ ▼ ▼ │
17
+ │ ┌──────────────┐ ┌────────────┐ │
18
+ │ │ PulseView │ │ Renderer │ │
19
+ │ │ (per route) │ │ (VDOM→DOM)│ │
20
+ │ └──────────────┘ └────────────┘ │
21
+ └─────────────────────────────────────────────────────────────────┘
22
+ ▲ │
23
+ │ VDOM updates │ Events/callbacks
24
+ │ ▼
25
+ ┌─────────────────────────────────────────────────────────────────┐
26
+ │ Python Server │
27
+ └─────────────────────────────────────────────────────────────────┘
28
+ ```
29
+
30
+ ## Folder Structure
31
+
32
+ ```
33
+ src/
34
+ ├── index.ts # Public API exports
35
+ ├── pulse.tsx # PulseProvider, PulseView, context
36
+ ├── client.tsx # PulseClient - manages connection & views
37
+ ├── renderer.tsx # VDOM-to-React rendering
38
+ ├── channel.ts # Channel bridge for real-time messaging
39
+ ├── transport.ts # Socket.IO transport layer
40
+ ├── messages.ts # Client<->server message types
41
+ ├── form.tsx # PulseForm component
42
+ ├── helpers.ts # Route info extraction utilities
43
+ ├── vdom.ts # VDOM types (VDOMNode, VDOMElement)
44
+ ├── usePulseChannel.ts # React hook for channels
45
+
46
+ └── serialize/ # Data serialization
47
+ ├── serializer.ts # Main serialize/deserialize
48
+ ├── clean.ts # Data cleaning for wire transfer
49
+ ├── elements.ts # Element extraction from refs
50
+ ├── events.ts # Event serialization
51
+ └── extractor.ts # Data extraction utilities
52
+ ```
53
+
54
+ ## Key Concepts
55
+
56
+ ### PulseProvider
57
+
58
+ Root provider establishing server connection:
59
+
60
+ ```tsx
61
+ import { PulseProvider } from "pulse-client";
62
+
63
+ function App() {
64
+ return (
65
+ <PulseProvider config={{ serverUrl: "http://localhost:8000" }}>
66
+ <Routes />
67
+ </PulseProvider>
68
+ );
69
+ }
70
+ ```
71
+
72
+ ### PulseView
73
+
74
+ Renders server-driven view for a route:
75
+
76
+ ```tsx
77
+ import { PulseView } from "pulse-client";
78
+
79
+ function Dashboard() {
80
+ return <PulseView path="/dashboard" />;
81
+ }
7
82
  ```
8
83
 
9
- To run:
84
+ ### PulseClient
85
+
86
+ Manages WebSocket connection, route mounting, message handling. Access via `usePulseClient()`.
87
+
88
+ ### Renderer
89
+
90
+ Converts VDOM to React:
91
+ - Handles element types (div, span, etc.)
92
+ - Resolves component references
93
+ - Binds event handlers to server
94
+ - Manages refs and lazy loading
95
+
96
+ ### Transport
97
+
98
+ Socket.IO transport with automatic reconnection, message queuing, connection status.
10
99
 
11
- ```bash
12
- bun run index.ts
100
+ ### Channels
101
+
102
+ Real-time messaging:
103
+
104
+ ```tsx
105
+ import { usePulseChannel } from "pulse-client";
106
+
107
+ function Chat() {
108
+ const channel = usePulseChannel("chat");
109
+ channel.on("new_message", (msg) => { /* handle */ });
110
+ channel.emit("message", { text: "Hello" });
111
+ }
13
112
  ```
14
113
 
15
- This project was created using `bun init` in bun v1.2.18. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
114
+ ## Main Exports
115
+
116
+ **Components**: `PulseProvider`, `PulseView`, `PulseForm`, `RenderLazy`
117
+
118
+ **Hooks**: `usePulseClient()`, `usePulseChannel(name)`
119
+
120
+ **Functions**: `serialize`, `deserialize`, `extractServerRouteInfo`, `submitForm`
121
+
122
+ **Types**: `VDOM`, `VDOMNode`, `VDOMElement`, `PulseClient`, `Transport`, `ComponentRegistry`
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react3 from "react";
2
- import { ComponentPropsWithoutRef, ComponentType, FC, FormEvent, PropsWithChildren, ReactNode } from "react";
3
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import { ComponentPropsWithoutRef, FormEvent, ReactNode } from "react";
4
3
  import { LoaderFunctionArgs, NavigateFunction } from "react-router";
4
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
5
5
 
6
6
  //#region src/helpers.d.ts
7
7
  interface RouteInfo {
@@ -29,16 +29,91 @@ declare function extractServerRouteInfo({
29
29
  };
30
30
  //#endregion
31
31
  //#region src/vdom.d.ts
32
- type ComponentRegistry = Record<string, ComponentType<any>>;
32
+ type ComponentRegistry = Record<string, unknown>;
33
+ type JsonPrimitive = string | number | boolean | null;
34
+ type JsonValue = JsonPrimitive | JsonValue[] | {
35
+ [k: string]: JsonValue;
36
+ };
37
+ type VDOMExpr = RegistryRefExpr | IdentifierExpr | LiteralExpr | UndefinedExpr | ArrayExpr | ObjectExpr | MemberExpr | SubscriptExpr | CallExpr | UnaryExpr | BinaryExpr | TernaryExpr | TemplateExpr | ArrowExpr | NewExpr;
38
+ interface RegistryRefExpr {
39
+ t: "ref";
40
+ key: string;
41
+ }
42
+ interface IdentifierExpr {
43
+ t: "id";
44
+ name: string;
45
+ }
46
+ interface LiteralExpr {
47
+ t: "lit";
48
+ value: JsonPrimitive;
49
+ }
50
+ interface UndefinedExpr {
51
+ t: "undef";
52
+ }
53
+ interface ArrayExpr {
54
+ t: "array";
55
+ items: VDOMNode[];
56
+ }
57
+ interface ObjectExpr {
58
+ t: "object";
59
+ props: Record<string, VDOMNode>;
60
+ }
61
+ interface MemberExpr {
62
+ t: "member";
63
+ obj: VDOMNode;
64
+ prop: string;
65
+ }
66
+ interface SubscriptExpr {
67
+ t: "sub";
68
+ obj: VDOMNode;
69
+ key: VDOMNode;
70
+ }
71
+ interface CallExpr {
72
+ t: "call";
73
+ callee: VDOMNode;
74
+ args: VDOMNode[];
75
+ }
76
+ interface UnaryExpr {
77
+ t: "unary";
78
+ op: string;
79
+ arg: VDOMNode;
80
+ }
81
+ interface BinaryExpr {
82
+ t: "binary";
83
+ op: string;
84
+ left: VDOMNode;
85
+ right: VDOMNode;
86
+ }
87
+ interface TernaryExpr {
88
+ t: "ternary";
89
+ cond: VDOMNode;
90
+ then: VDOMNode;
91
+ else_: VDOMNode;
92
+ }
93
+ interface TemplateExpr {
94
+ t: "template";
95
+ parts: Array<string | VDOMNode>;
96
+ }
97
+ interface ArrowExpr {
98
+ t: "arrow";
99
+ params: string[];
100
+ body: VDOMNode;
101
+ }
102
+ interface NewExpr {
103
+ t: "new";
104
+ ctor: VDOMNode;
105
+ args: VDOMNode[];
106
+ }
107
+ type CallbackPlaceholder = "$cb";
108
+ type VDOMPropValue = JsonValue | VDOMExpr | VDOMElement | CallbackPlaceholder;
33
109
  interface VDOMElement {
34
110
  tag: string;
35
- props?: Record<string, any>;
36
- children?: VDOMNode[];
37
111
  key?: string;
38
- lazy?: boolean;
112
+ props?: Record<string, VDOMPropValue>;
113
+ children?: VDOMNode[];
114
+ eval?: string[];
39
115
  }
40
- type PrimitiveNode = string | number | boolean;
41
- type VDOMNode = PrimitiveNode | VDOMElement;
116
+ type VDOMNode = JsonPrimitive | VDOMElement | VDOMExpr;
42
117
  type VDOM = VDOMNode;
43
118
  interface VDOMUpdateBase {
44
119
  type: string;
@@ -46,13 +121,14 @@ interface VDOMUpdateBase {
46
121
  }
47
122
  interface ReplaceUpdate extends VDOMUpdateBase {
48
123
  type: "replace";
49
- data: VDOMNode;
124
+ data: VDOM;
50
125
  }
51
126
  interface UpdatePropsUpdate extends VDOMUpdateBase {
52
127
  type: "update_props";
53
128
  data: {
54
- set?: Record<string, any>;
129
+ set?: Record<string, VDOMPropValue>;
55
130
  remove?: string[];
131
+ eval?: string[];
56
132
  };
57
133
  }
58
134
  interface ReconciliationUpdate {
@@ -62,39 +138,20 @@ interface ReconciliationUpdate {
62
138
  new: [number[], VDOM[]];
63
139
  reuse: [number[], number[]];
64
140
  }
65
- interface PathDelta {
66
- add?: string[];
67
- remove?: string[];
68
- }
69
- interface UpdateCallbacksUpdate extends VDOMUpdateBase {
70
- type: "update_callbacks";
71
- data: PathDelta;
72
- }
73
- interface UpdateRenderPropsUpdate extends VDOMUpdateBase {
74
- type: "update_render_props";
75
- data: PathDelta;
76
- }
77
- interface UpdateJsExprPathsUpdate extends VDOMUpdateBase {
78
- type: "update_jsexpr_paths";
79
- data: PathDelta;
80
- }
81
- type VDOMUpdate = ReplaceUpdate | UpdatePropsUpdate | ReconciliationUpdate | UpdateCallbacksUpdate | UpdateRenderPropsUpdate | UpdateJsExprPathsUpdate;
141
+ type VDOMUpdate = ReplaceUpdate | UpdatePropsUpdate | ReconciliationUpdate;
82
142
  //#endregion
83
143
  //#region src/messages.d.ts
84
144
  interface ServerInitMessage {
85
145
  type: "vdom_init";
86
146
  path: string;
87
147
  vdom: VDOM;
88
- callbacks: string[];
89
- render_props: string[];
90
- jsexpr_paths: string[];
91
148
  }
92
149
  interface ServerUpdateMessage {
93
150
  type: "vdom_update";
94
151
  path: string;
95
152
  ops: VDOMUpdate[];
96
153
  }
97
- interface ServerErrorInfo {
154
+ interface ServerError {
98
155
  message: string;
99
156
  stack?: string;
100
157
  phase: "render" | "callback" | "mount" | "unmount" | "navigate" | "server";
@@ -103,7 +160,7 @@ interface ServerErrorInfo {
103
160
  interface ServerErrorMessage {
104
161
  type: "server_error";
105
162
  path: string;
106
- error: ServerErrorInfo;
163
+ error: ServerError;
107
164
  }
108
165
  interface ServerApiCallMessage {
109
166
  type: "api_call";
@@ -143,7 +200,7 @@ interface ServerJsExecMessage {
143
200
  type: "js_exec";
144
201
  path: string;
145
202
  id: string;
146
- code: string;
203
+ expr: VDOMNode;
147
204
  }
148
205
  type ServerMessage = ServerInitMessage | ServerUpdateMessage | ServerErrorMessage | ServerApiCallMessage | ServerNavigateToMessage | ServerChannelRequestMessage | ServerChannelResponseMessage | ServerJsExecMessage;
149
206
  interface ClientCallbackMessage {
@@ -152,18 +209,18 @@ interface ClientCallbackMessage {
152
209
  callback: string;
153
210
  args: any[];
154
211
  }
155
- interface ClientMountMessage {
156
- type: "mount";
212
+ interface ClientAttachMessage {
213
+ type: "attach";
157
214
  path: string;
158
215
  routeInfo: RouteInfo;
159
216
  }
160
- interface ClientNavigateMessage {
161
- type: "navigate";
217
+ interface ClientUpdateMessage {
218
+ type: "update";
162
219
  path: string;
163
220
  routeInfo: RouteInfo;
164
221
  }
165
- interface ClientUnmountMessage {
166
- type: "unmount";
222
+ interface ClientDetachMessage {
223
+ type: "detach";
167
224
  path: string;
168
225
  }
169
226
  interface ClientApiResultMessage {
@@ -199,7 +256,7 @@ interface ClientJsResultMessage {
199
256
  result: any;
200
257
  error: string | null;
201
258
  }
202
- type ClientMessage = ClientMountMessage | ClientCallbackMessage | ClientNavigateMessage | ClientUnmountMessage | ClientApiResultMessage | ClientChannelRequestMessage | ClientChannelResponseMessage | ClientJsResultMessage;
259
+ type ClientMessage = ClientAttachMessage | ClientCallbackMessage | ClientUpdateMessage | ClientDetachMessage | ClientApiResultMessage | ClientChannelRequestMessage | ClientChannelResponseMessage | ClientJsResultMessage;
203
260
  //#endregion
204
261
  //#region src/pulse.d.ts
205
262
  interface ConnectionStatusConfig {
@@ -213,9 +270,6 @@ interface PulseConfig {
213
270
  }
214
271
  type PulsePrerenderView = {
215
272
  vdom: VDOM;
216
- callbacks: string[];
217
- render_props: string[];
218
- jsexpr_paths: string[];
219
273
  };
220
274
  type PulsePrerender = {
221
275
  views: Record<string, PulsePrerenderView>;
@@ -254,20 +308,20 @@ interface MountedView {
254
308
  routeInfo: RouteInfo;
255
309
  onInit: (view: PulsePrerenderView) => void;
256
310
  onUpdate: (ops: VDOMUpdate[]) => void;
257
- onJsExec?: (msg: ServerJsExecMessage) => void;
311
+ onJsExec: (msg: ServerJsExecMessage) => void;
312
+ onServerError: (error: ServerError) => void;
258
313
  }
259
314
  type ConnectionStatus = "ok" | "connecting" | "reconnecting" | "error";
260
315
  type ConnectionStatusListener = (status: ConnectionStatus) => void;
261
- type ServerErrorListener = (path: string, error: ServerErrorInfo | null) => void;
262
316
  interface PulseClient {
263
317
  connect(): Promise<void>;
264
318
  disconnect(): void;
265
319
  isConnected(): boolean;
266
320
  onConnectionChange(listener: ConnectionStatusListener): () => void;
267
- navigate(path: string, routeInfo: RouteInfo): Promise<void>;
268
- leave(path: string): Promise<void>;
269
- invokeCallback(path: string, callback: string, args: any[]): Promise<void>;
270
- mountView(path: string, view: MountedView): () => void;
321
+ updateRoute(path: string, routeInfo: RouteInfo): void;
322
+ invokeCallback(path: string, callback: string, args: any[]): void;
323
+ attach(path: string, view: MountedView): void;
324
+ detach(path: string): void;
271
325
  }
272
326
  declare class PulseSocketIOClient {
273
327
  #private;
@@ -280,11 +334,10 @@ declare class PulseSocketIOClient {
280
334
  isConnected(): boolean;
281
335
  connect(): Promise<void>;
282
336
  onConnectionChange(listener: ConnectionStatusListener): () => void;
283
- onServerError(listener: ServerErrorListener): () => void;
284
337
  sendMessage(payload: ClientMessage): void;
285
- mountView(path: string, view: MountedView): void;
286
- navigate(path: string, routeInfo: RouteInfo): void;
287
- unmount(path: string): void;
338
+ attach(path: string, view: MountedView): void;
339
+ updateRoute(path: string, routeInfo: RouteInfo): void;
340
+ detach(path: string): void;
288
341
  disconnect(): void;
289
342
  invokeCallback(path: string, callback: string, args: any[]): void;
290
343
  sendJsResult(id: string, result: any, error: string | null): void;
@@ -318,6 +371,7 @@ declare class ChannelBridge {
318
371
  private resolvePending;
319
372
  private close;
320
373
  }
374
+ declare function usePulseChannel(channelId: string): ChannelBridge;
321
375
  //#endregion
322
376
  //#region src/form.d.ts
323
377
  type PulseFormProps = ComponentPropsWithoutRef<"form"> & {
@@ -347,9 +401,20 @@ declare function submitForm({
347
401
  }: SubmitForm): Promise<void>;
348
402
  //#endregion
349
403
  //#region src/renderer.d.ts
350
- declare function RenderLazy(component: () => Promise<{
351
- default: ComponentType<any>;
352
- }>, fallback?: ReactNode): FC<PropsWithChildren<unknown>>;
404
+ declare class VDOMRenderer {
405
+ #private;
406
+ constructor(client: PulseSocketIOClient, path: string, registry?: ComponentRegistry);
407
+ getObject(key: string): unknown;
408
+ renderNode(node: VDOMNode, currentPath?: string): ReactNode;
409
+ init(view: PulsePrerenderView & {
410
+ vdom: VDOM;
411
+ }): ReactNode;
412
+ /**
413
+ * Evaluate a VDOMNode expression (for run_js support).
414
+ */
415
+ evaluateExpr(expr: VDOMNode): unknown;
416
+ applyUpdates(initialTree: ReactNode, updates: VDOMUpdate[]): ReactNode;
417
+ }
353
418
  //#endregion
354
419
  //#region src/serialize/serializer.d.ts
355
420
  type Primitive = number | string | boolean | null | undefined;
@@ -376,8 +441,5 @@ interface Transport {
376
441
  onConnectionChange(listener: ConnectionStatusListener$1): () => void;
377
442
  }
378
443
  //#endregion
379
- //#region src/usePulseChannel.d.ts
380
- declare function usePulseChannel(channelId: string): ChannelBridge;
381
- //#endregion
382
- export { type ChannelBridge, type ClientApiResultMessage, type ClientCallbackMessage, type ClientChannelMessage, type ClientChannelRequestMessage, type ClientChannelResponseMessage, type ClientMessage, type ClientMountMessage, type ClientNavigateMessage, type ClientUnmountMessage, type ComponentRegistry, type ConnectionStatusListener, type MessageListener, type MountedView, PulseChannelResetError, type PulseClient, type PulseConfig, PulseForm, type PulseFormProps, type PulsePrerender, PulseProvider, type PulseProviderProps, PulseView, RenderLazy, type RouteInfo, type ServerApiCallMessage, type ServerChannelMessage, type ServerChannelRequestMessage, type ServerChannelResponseMessage, type ServerErrorInfo, type ServerErrorListener, type ServerErrorMessage, type ServerInitMessage, type ServerMessage, type ServerNavigateToMessage, type ServerUpdateMessage, type Transport, type VDOM, type VDOMElement, type VDOMNode, type VDOMUpdate, deserialize, extractServerRouteInfo, serialize, submitForm, usePulseChannel, usePulseClient };
444
+ export { type ChannelBridge, type ClientApiResultMessage, type ClientAttachMessage, type ClientCallbackMessage, type ClientChannelMessage, type ClientChannelRequestMessage, type ClientChannelResponseMessage, type ClientDetachMessage, type ClientMessage, type ClientUpdateMessage, type ComponentRegistry, type ComponentRegistry as ComponentRegistry2, type ConnectionStatusListener, type MessageListener, type MountedView, PulseChannelResetError, type PulseClient, type PulseConfig, PulseForm, type PulseFormProps, type PulsePrerender, PulseProvider, type PulseProviderProps, PulseView, type RouteInfo, type ServerApiCallMessage, type ServerChannelMessage, type ServerChannelRequestMessage, type ServerChannelResponseMessage, type ServerError, type ServerErrorMessage, type ServerInitMessage, type ServerMessage, type ServerNavigateToMessage, type ServerUpdateMessage, type Transport, type VDOM, type VDOMElement, type VDOMExpr, type VDOMNode, type VDOMPropValue, VDOMRenderer, type VDOMUpdate, deserialize, extractServerRouteInfo, serialize, submitForm, usePulseChannel, usePulseClient };
383
445
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{Fragment as e,Suspense as t,cloneElement as n,createContext as r,createElement as i,forwardRef as a,isValidElement as o,lazy as s,useCallback as c,useContext as l,useEffect as u,useMemo as d,useRef as f,useState as p}from"react";import{jsx as m,jsxs as h}from"react/jsx-runtime";import{useLocation as g,useNavigate as _,useParams as ee}from"react-router";import{io as v}from"socket.io-client";var y=class extends Error{constructor(e){super(e),this.name=`PulseChannelResetError`}};function te(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID().replace(/-/g,``):Math.random().toString(16).slice(2)+Math.random().toString(16).slice(2)}function ne(e){if(e instanceof Error)return e.message;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function re(e){return typeof e.responseTo==`string`}function ie(e){return typeof e.event==`string`}var ae=class{handlers=new Map;pending=new Map;backlog=[];closed=!1;constructor(e,t){this.client=e,this.id=t}emit(e,t){this.ensureOpen(),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t})}request(e,t){this.ensureOpen();let n=te();return new Promise((r,i)=>{this.pending.set(n,{resolve:r,reject:i}),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t,requestId:n})})}on(e,t){this.ensureOpen();let n=this.handlers.get(e);return n||(n=new Set,this.handlers.set(e,n)),n.add(t),this.flushBacklog(e),()=>{let n=this.handlers.get(e);n&&(n.delete(t),n.size===0&&this.handlers.delete(e))}}handleServerMessage(e){return re(e)?(this.resolvePending(e),this.closed):this.closed?!0:ie(e)?e.event===`__close__`?(this.close(new y(`Channel closed by server`)),!0):(e.requestId?this.dispatchRequest(e):this.dispatchEvent(e),this.closed):this.closed}handleDisconnect(e){this.close(e)}dispose(e){this.close(e)}ensureOpen(){if(this.closed)throw new y(`Channel is closed`)}flushBacklog(e){if(this.backlog.length===0)return;let t=[];for(let n of this.backlog)n.event===e?this.dispatchEvent(n):t.push(n);this.backlog=t}dispatchEvent(e){let t=this.handlers.get(e.event);if(!t||t.size===0){this.backlog.push(e);return}for(let n of t)try{let t=n(e.payload);t&&typeof t.then==`function`&&t.catch(e=>{console.error(`Pulse channel handler error`,e)})}catch(e){console.error(`Pulse channel handler error`,e)}}async dispatchRequest(e){let t=this.handlers.get(e.event),n,r;if(t&&t.size>0)for(let i of t)try{let t=i(e.payload);if(n=await Promise.resolve(t),n!==void 0)break}catch(e){r=e;break}if(r){this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,error:ne(r)});return}this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,payload:n})}resolvePending(e){let t=e.responseTo?this.pending.get(e.responseTo):void 0;t&&(this.pending.delete(e.responseTo),e.error!==void 0&&e.error!==null?t.reject(new y(String(e.error))):t.resolve(e.payload))}close(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e);this.pending.clear(),this.handlers.clear(),this.backlog=[]}}};const oe=a(function({onSubmit:e,action:t,...n},r){return m(`form`,{...n,action:t,ref:r,onSubmit:c(n=>b({event:n,action:t,onSubmit:e}),[t,e])})});async function b({event:e,action:t,onSubmit:n,formData:r,force:i}){if(n?.(e),!i&&e.defaultPrevented)return;let a=e.currentTarget;e.preventDefault();let o=e.nativeEvent;r||=new FormData(a,o.submitter);let s=new URL(t,window.location.href);try{await fetch(s,{method:`POST`,credentials:`include`,body:r})}catch(e){if(process.env.NODE_ENV!==`production`)console.error(`[Pulse] Form submission failed`,e);else throw e}}function se({params:e,request:t}){let{"*":n=``,...r}=e,i=new URL(t.url);return{hash:i.hash,pathname:i.pathname,query:i.search,queryParams:Object.fromEntries(i.searchParams.entries()),pathParams:r,catchall:n.length>1?n.split(`/`):[]}}function x(){function e(e,t){return n=>{let r={};for(let t of e)r[t]=n[t];if(t)for(let e in t){let i=t[e];r[e]=i(n)}return r}}return e}const ce=e=>e.tagName.toLowerCase(),le=[`id`,`className`,`tagName`,`localName`,`clientHeight`,`clientLeft`,`clientTop`,`clientWidth`,`scrollHeight`,`scrollLeft`,`scrollTop`,`scrollWidth`,`slot`],ue=[`autofocus`,`tabIndex`,`nonce`],de=[`accessKey`,`accessKeyLabel`,`autocapitalize`,`dir`,`draggable`,`hidden`,`inert`,`lang`,`offsetHeight`,`offsetLeft`,`offsetTop`,`offsetWidth`,`popover`,`spellcheck`,`title`,`translate`,`writingSuggestions`,`contentEditable`,`enterKeyHint`,`isContentEditable`,`inputMode`],S=x()(le,{tagName:ce}),C=x()(ue),fe=x()(de);function w(e){return{...S(e),...C(e),...fe(e)}}function T(e,t){let n=x()(e,t);return e=>({...w(e),...n(e)})}const pe=T([`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`search`,`target`,`download`,`rel`,`hreflang`,`type`,`username`,`ping`,`referrerPolicy`,`text`]),me=T([`alt`,`coords`,`download`,`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`rel`,`search`,`shape`,`target`,`username`,`ping`,`referrerPolicy`]),E=T([`autoplay`,`controls`,`crossOrigin`,`currentSrc`,`currentTime`,`defaultMuted`,`defaultPlaybackRate`,`duration`,`ended`,`loop`,`muted`,`networkState`,`paused`,`playbackRate`,`preload`,`readyState`,`seeking`,`src`,`volume`,`preservesPitch`]),he=e=>E(e),ge=T([`disabled`,`name`,`type`,`value`,`formAction`,`formEnctype`,`formMethod`,`formNoValidate`,`formTarget`,`popoverTargetAction`]),_e=T([`value`]),ve=T([`height`,`src`,`type`,`width`,`align`,`name`]),ye=T([`disabled`,`name`,`type`,`validationMessage`,`willValidate`]),be=T([`acceptCharset`,`action`,`autocomplete`,`encoding`,`enctype`,`length`,`method`,`name`,`noValidate`,`target`,`rel`]),xe=T([`allow`,`allowFullscreen`,`height`,`name`,`referrerPolicy`,`src`,`srcdoc`,`width`,`align`,`frameBorder`,`longDesc`,`marginHeight`,`marginWidth`,`scrolling`,`sandbox`]),Se=T([`alt`,`crossOrigin`,`decoding`,`height`,`isMap`,`loading`,`naturalHeight`,`naturalWidth`,`referrerPolicy`,`sizes`,`src`,`srcset`,`useMap`,`width`,`align`,`border`,`complete`,`hspace`,`longDesc`,`lowsrc`,`name`,`vspace`,`x`,`y`,`fetchPriority`]),Ce=T(`accept.alt.autocomplete.checked.defaultChecked.defaultValue.dirName.disabled.height.indeterminate.max.maxLength.min.minLength.multiple.name.pattern.placeholder.readOnly.required.selectionDirection.selectionEnd.selectionStart.size.src.step.type.value.valueAsNumber.width.align.capture.formAction.formEnctype.formMethod.formNoValidate.formTarget.useMap.validationMessage.willValidate.popoverTargetAction`.split(`.`)),we=T([`htmlFor`]),Te=T([`value`,`type`]),Ee=T([`as`,`crossOrigin`,`disabled`,`fetchPriority`,`href`,`hreflang`,`imageSizes`,`imageSrcset`,`integrity`,`media`,`referrerPolicy`,`rel`,`type`,`charset`,`rev`,`target`,`sizes`]),De=T([`name`]),Oe=T([`high`,`low`,`max`,`min`,`optimum`,`value`]),D=T([`cite`,`dateTime`]),ke=T([`reversed`,`start`,`type`,`compact`]),Ae=T([`data`,`height`,`name`,`type`,`useMap`,`width`,`validationMessage`,`willValidate`,`align`,`archive`,`border`,`code`,`codeBase`,`codeType`,`declare`,`hspace`,`standby`,`vspace`]),je=T([`disabled`,`label`]),Me=T([`defaultSelected`,`disabled`,`index`,`label`,`selected`,`text`,`value`]),Ne=T([`defaultValue`,`name`,`type`,`value`,`htmlFor`,`validationMessage`,`willValidate`]),Pe=T([`max`,`position`,`value`]),O=T([`cite`]),Fe=e=>w(e),Ie=x()([`async`,`crossOrigin`,`defer`,`fetchPriority`,`integrity`,`noModule`,`referrerPolicy`,`src`,`text`,`type`,`charset`],{event:e=>e.event,htmlFor:e=>e.htmlFor}),Le=e=>({...w(e),...Ie(e)}),Re=T([`autocomplete`,`disabled`,`length`,`multiple`,`name`,`required`,`selectedIndex`,`size`,`type`,`value`,`validationMessage`,`willValidate`]),ze=T([`name`]),Be=T([`height`,`media`,`sizes`,`src`,`srcset`,`type`,`width`]),Ve=T([`align`]),k=T([`abbr`,`cellIndex`,`colSpan`,`headers`,`rowSpan`,`scope`,`align`,`axis`,`bgColor`,`ch`,`chOff`,`height`,`noWrap`,`vAlign`,`width`]),A=T([`span`,`align`,`ch`,`chOff`,`vAlign`,`width`]),He=T([`align`,`bgColor`,`border`,`cellPadding`,`cellSpacing`,`frame`,`rules`,`summary`,`width`]),Ue=T([`rowIndex`,`sectionRowIndex`,`align`,`bgColor`,`ch`,`chOff`,`vAlign`]),j=T([`align`,`ch`,`chOff`,`vAlign`]),We=e=>w(e),Ge=T([`autocomplete`,`cols`,`defaultValue`,`dirName`,`disabled`,`maxLength`,`minLength`,`name`,`placeholder`,`readOnly`,`required`,`rows`,`selectionDirection`,`selectionEnd`,`selectionStart`,`value`,`wrap`,`textLength`,`validationMessage`,`willValidate`]),Ke=T([`dateTime`]),qe=T([`default`,`kind`,`label`,`readyState`,`src`,`srclang`]),Je=x()([`height`,`poster`,`videoHeight`,`videoWidth`,`width`,`playsInline`]),Ye=e=>({...E(e),...Je(e)}),Xe=T([`clear`]),Ze=T([`href`,`target`]),Qe=T([`aLink`,`background`,`bgColor`,`link`,`text`,`vLink`]),$e=T([`compact`]),et=T([`open`]),tt=T([`open`,`returnValue`]),nt=T([`align`]),rt=e=>w(e),M=T([`align`]),it=T([`align`,`color`,`noShade`,`size`,`width`]),at=T([`version`]),ot=e=>w(e),st=T([`content`,`httpEquiv`,`name`,`scheme`]),ct=T([`align`]),lt=e=>w(e),ut=T([`width`]),dt=e=>w(e),ft=T([`media`,`type`,`disabled`]),pt=T([`text`]),mt=T([`compact`,`type`]);function N(e){return{...S(e),...C(e)}}function P(e,t){let n=x()(e,t);return e=>({...N(e),...n(e)})}const F={A:pe,AREA:me,AUDIO:he,BASE:Ze,BLOCKQUOTE:O,Q:O,BODY:Qe,BR:Xe,BUTTON:ge,CANVAS:w,CAPTION:Ve,CITE:Fe,COL:A,COLGROUP:A,DATA:_e,DETAILS:et,DIALOG:tt,DIV:nt,DL:$e,EMBED:ve,FIELDSET:ye,FORM:be,H1:M,H2:M,H3:M,H4:M,H5:M,H6:M,HEAD:rt,HR:it,HTML:at,IFRAME:xe,IMG:Se,INPUT:Ce,LABEL:we,LI:Te,LINK:Ee,MAP:De,MENU:ot,META:st,METER:Oe,INS:D,DEL:D,OBJECT:Ae,OL:ke,OPTGROUP:je,OPTION:Me,OUTPUT:Ne,P:ct,PICTURE:lt,PRE:ut,PROGRESS:Pe,SCRIPT:Le,SELECT:Re,SLOT:ze,SOURCE:Be,SPAN:dt,STYLE:ft,TABLE:He,TBODY:j,THEAD:j,TFOOT:j,TD:k,TH:k,TEMPLATE:We,TEXTAREA:Ge,TIME:Ke,TITLE:pt,TR:Ue,TRACK:qe,UL:mt,VIDEO:Ye,SVG:P([`x`,`y`,`width`,`height`,`currentScale`,`currentTranslate`]),CIRCLE:P([`cx`,`cy`,`r`]),ELLIPSE:P([`cx`,`cy`,`rx`,`ry`]),LINE:P([`x1`,`y1`,`x2`,`y2`]),PATH:P([`pathLength`]),RECT:P([`x`,`y`,`width`,`height`,`rx`,`ry`]),POLYGON:P([`points`]),POLYLINE:P([`points`]),TEXT:P([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),TSPAN:P([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),IMAGE:P([`x`,`y`,`width`,`height`,`href`,`preserveAspectRatio`,`crossOrigin`]),USE:P([`x`,`y`,`width`,`height`,`href`]),DEFS:P([]),G:P([]),LINEARGRADIENT:P([`x1`,`y1`,`x2`,`y2`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),RADIALGRADIENT:P([`cx`,`cy`,`r`,`fx`,`fy`,`fr`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),STOP:P([`offset`]),PATTERN:P([`x`,`y`,`width`,`height`,`patternUnits`,`patternContentUnits`,`patternTransform`,`preserveAspectRatio`,`href`]),CLIPPATH:P([`clipPathUnits`]),MASK:P([`x`,`y`,`width`,`height`,`maskUnits`,`maskContentUnits`])};function ht(e){let t=F[e.tagName.toUpperCase()];if(t)return t(e);throw Error(`Unexpected HTML element tag: ${e.tagName} (update .web/custom/serialize.ts)`)}function gt(e){let t=F[e.tagName.toUpperCase()];return t?t(e):N(e)}function I(e){return e instanceof HTMLElement?ht(e):e instanceof SVGElement?gt(e):S(e)}const _t=e=>I(e.target),L=e=>e.relatedTarget?I(e.relatedTarget):null;function R(e,t){return x()(e,{target:_t,...t||{}})}const z=[`target`,`bubbles`,`cancelable`,`defaultPrevented`,`eventPhase`,`isTrusted`,`timeStamp`,`type`],B=[...z,`detail`],V=[...B,`altKey`,`button`,`buttons`,`clientX`,`clientY`,`ctrlKey`,`metaKey`,`movementX`,`movementY`,`pageX`,`pageY`,`screenX`,`screenY`,`shiftKey`],vt=[...V,`pointerId`,`pressure`,`tangentialPressure`,`tiltX`,`tiltY`,`twist`,`width`,`height`,`pointerType`,`isPrimary`],yt=R(z),bt=R(B),xt=R(V,{relatedTarget:L}),St=R(z,{clipboardData:e=>U(e.clipboardData)}),Ct=R([...z,`data`]),wt=R(V,{relatedTarget:L,dataTransfer:e=>U(e.dataTransfer)}),Tt=R(vt,{relatedTarget:L}),Et=R(z,{relatedTarget:L}),Dt=R(z),Ot=R(z),kt=R(z),At=R([...B,`altKey`,`ctrlKey`,`code`,`key`,`locale`,`location`,`metaKey`,`repeat`,`shiftKey`]),jt=R([...B,`altKey`,`ctrlKey`,`metaKey`,`shiftKey`,`changedTouches`,`targetTouches`,`touches`],{changedTouches:e=>H(e.changedTouches),targetTouches:e=>H(e.targetTouches),touches:e=>H(e.touches)}),Mt=R([...V,`deltaMode`,`deltaX`,`deltaY`,`deltaZ`],{relatedTarget:L}),Nt=R([...z,`animationName`,`elapsedTime`,`pseudoElement`]),Pt=R([...z,`oldState`,`newState`]),Ft=R([...z,`elapsedTime`,`propertyName`,`pseudoElement`]);function H(e){return Array.from(e).map(e=>({target:I(e.target),identifier:e.identifier,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,pageX:e.pageX,pageY:e.pageY}))}function U(e){if(!e)return null;let t=[];if(e.items)for(let n=0;n<e.items.length;n++){let r=e.items[n];t.push({kind:r.kind,type:r.type})}return{drop_effect:e.dropEffect,effect_allowed:e.effectAllowed,items:t,types:Array.from(e.types||[])}}const W={};function G(e,t,n){for(let r of t)e[r]=n}G(W,[`pointerdown`,`pointermove`,`pointerup`,`pointercancel`,`gotpointercapture`,`lostpointercapture`,`pointerenter`,`pointerleave`,`pointerover`,`pointerout`],Tt),G(W,[`click`,`contextmenu`,`dblclick`,`mousedown`,`mouseenter`,`mouseleave`,`mousemove`,`mouseout`,`mouseover`,`mouseup`],xt),G(W,[`drag`,`dragend`,`dragenter`,`dragexit`,`dragleave`,`dragover`,`dragstart`,`drop`],wt),G(W,[`keydown`,`keypress`,`keyup`],At),G(W,[`focus`,`blur`],Et),G(W,[`change`,`input`],kt),G(W,[`invalid`],Ot),G(W,[`reset`,`submit`],Dt),G(W,[`copy`,`cut`,`paste`],St),G(W,[`compositionend`,`compositionstart`,`compositionupdate`],Ct),G(W,[`touchcancel`,`touchend`,`touchmove`,`touchstart`],jt),G(W,[`scroll`],bt),G(W,[`wheel`],Mt),G(W,[`animationstart`,`animationend`,`animationiteration`],Nt),G(W,[`transitionend`],Ft),G(W,[`toggle`],Pt);function It(e){if(e&&typeof e==`object`&&`nativeEvent`in e&&typeof e.isDefaultPrevented==`function`){let t=e;if(typeof t.type!=`string`)return e;let n=W[t.type.toLowerCase()];return n?n(t):yt(t)}return e}function K(e){let t=new Map,n=[],r=[],i=[],a=[],o=0;function s(e,c){if(e==null||typeof e==`string`||typeof e==`boolean`)return e;if(typeof e==`number`){if(Number.isNaN(e)){let e=c?` in '${c}'`:``;throw Error(`Cannot serialize NaN${e}. NaN and Infinity are not supported because they cannot be serialized to JSON.`)}if(!Number.isFinite(e)){let t=e>0?`Infinity`:`-Infinity`,n=c?` in '${c}'`:``;throw Error(`Cannot serialize ${t}${n}. NaN and Infinity are not supported because they cannot be serialized to JSON.`)}return e}let l=o++,u=t.get(e);if(u!==void 0)return n.push(l),u;if(t.set(e,l),e instanceof Date)return r.push(l),e.getTime();if(Array.isArray(e)){let t=e.length,n=Array(t);for(let r=0;r<t;r++)n[r]=s(e[r],c);return n}if(e instanceof Map){a.push(l);let t={};for(let[n,r]of e.entries())t[String(n)]=s(r,String(n));return t}if(e instanceof Set){i.push(l);let t=e.size,n=Array(t),r=0;for(let t of e)n[r]=s(t,c),r+=1;return n}if(typeof e==`object`){let t={},n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t[i]=s(e[i],i)}return t}throw Error(`Unsupported value in serialization: ${e}`)}let c=s(e);return[[n,r,i,a],c]}function q(e,t){let[[n,r,i,a],o]=e,s=new Set(n),c=new Set(r),l=new Set(i),u=new Set(a),d=[];function f(e){let n=d.length;if(s.has(n))return d.push(null),d[e];if(c.has(n)){let t=new Date(e);return d.push(t),t}if(e==null||typeof e==`number`||typeof e==`string`||typeof e==`boolean`)return t?.coerceNullsToUndefined?e??void 0:e;if(Array.isArray(e)){if(l.has(n)){let t=new Set;d.push(t);for(let n=0;n<e.length;n++)t.add(f(e[n]));return t}let t=e.length,r=Array(t);d.push(r);for(let n=0;n<t;n++)r[n]=f(e[n]);return r}if(typeof e==`object`){if(u.has(n)){let t=new Map;d.push(t);let n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t.set(i,f(e[i]))}return t}let t={};d.push(t);let r=Object.keys(e);for(let n=0;n<r.length;n++){let i=r[n];t[i]=f(e[i])}return t}throw Error(`Unsupported value in deserialization: ${e}`)}return f(o)}var Lt=class{#activeViews;#socket=null;#messageQueue;#connectionListeners=new Set;#serverErrors=new Map;#serverErrorListeners=new Set;#channels=new Map;#url;#frameworkNavigate;#directives;#connectionStatusConfig;#hasConnectedOnce=!1;#connectingTimeout=null;#errorTimeout=null;#currentStatus=`ok`;constructor(e,t,n,r){if(this.#url=e,this.#directives=t,this.#frameworkNavigate=n,this.#socket=null,this.#activeViews=new Map,this.#messageQueue=[],this.#connectionStatusConfig=r,typeof window<`u`&&typeof sessionStorage<`u`){let e=sessionStorage.getItem(`__PULSE_DIRECTIVES`);if(e)try{this.#directives=JSON.parse(e)}catch{}}}setDirectives(e){this.#directives=e}isConnected(){return this.#socket?.connected??!1}#clearTimeouts(){this.#connectingTimeout&&=(clearTimeout(this.#connectingTimeout),null),this.#errorTimeout&&=(clearTimeout(this.#errorTimeout),null)}#setStatus(e){this.#clearTimeouts(),this.#currentStatus=e,this.#notifyConnectionListeners(e)}#handleConnected(){this.#hasConnectedOnce=!0,this.#setStatus(`ok`)}#setInitialConnectionStatus(){this.#setStatus(`ok`),this.#connectingTimeout=setTimeout(()=>{this.#setStatus(`connecting`),this.#errorTimeout=setTimeout(()=>{this.#setStatus(`error`)},this.#connectionStatusConfig.initialErrorDelay)},this.#connectionStatusConfig.initialConnectingDelay)}#handleDisconnected(){this.#setStatus(`reconnecting`),this.#errorTimeout=setTimeout(()=>{this.#setStatus(`error`)},this.#connectionStatusConfig.reconnectErrorDelay)}async connect(){if(!this.#socket)return this.#hasConnectedOnce||this.#setInitialConnectionStatus(),new Promise((e,t)=>{let n=v(this.#url,{transports:[`websocket`,`webtransport`],auth:this.#directives.socketio?.auth,extraHeaders:this.#directives.socketio?.headers});this.#socket=n,n.on(`connect`,()=>{console.log(`[SocketIOTransport] Connected:`,this.#socket?.id);for(let[e,t]of this.#activeViews)n.emit(`message`,K({type:`mount`,path:e,routeInfo:t.routeInfo}));for(let e of this.#messageQueue)e.type===`mount`&&this.#activeViews.has(e.path)||e.type!==`navigate`&&n.emit(`message`,K(e));this.#messageQueue=[],this.#handleConnected(),e()}),n.on(`connect_error`,e=>{console.error(`[SocketIOTransport] Connection failed:`,e),this.#handleDisconnected(),t(e)}),n.on(`disconnect`,()=>{console.log(`[SocketIOTransport] Disconnected`),this.#handleTransportDisconnect(),this.#handleDisconnected()}),n.on(`message`,e=>this.#handleServerMessage(q(e,{coerceNullsToUndefined:!0})))})}onConnectionChange(e){return this.#connectionListeners.add(e),e(this.#currentStatus),()=>{this.#connectionListeners.delete(e)}}#notifyConnectionListeners(e){for(let t of this.#connectionListeners)t(e)}onServerError(e){this.#serverErrorListeners.add(e);for(let[t,n]of this.#serverErrors)e(t,n);return()=>{this.#serverErrorListeners.delete(e)}}#notifyServerError(e,t){for(let n of this.#serverErrorListeners)n(e,t)}sendMessage(e){this.isConnected()?this.#socket.emit(`message`,K(e)):this.#messageQueue.push(e)}mountView(e,t){if(this.#activeViews.has(e))throw Error(`Path ${e} is already mounted`);this.#activeViews.set(e,t),this.sendMessage({type:`mount`,path:e,routeInfo:t.routeInfo})}navigate(e,t){this.sendMessage({type:`navigate`,path:e,routeInfo:t})}unmount(e){this.sendMessage({type:`unmount`,path:e}),this.#activeViews.delete(e)}disconnect(){this.#clearTimeouts(),this.#socket?.disconnect(),this.#socket=null,this.#messageQueue=[],this.#connectionListeners.clear(),this.#activeViews.clear(),this.#serverErrors.clear(),this.#serverErrorListeners.clear();for(let{bridge:e}of this.#channels.values())e.dispose(new y(`Client disconnected`));this.#channels.clear(),this.#currentStatus=`ok`,this.#hasConnectedOnce=!1}#handleServerMessage(e){switch(e.type){case`vdom_init`:{let t=this.#activeViews.get(e.path);if(!t)return;t&&t.onInit(e),this.#serverErrors.has(e.path)&&(this.#serverErrors.delete(e.path),this.#notifyServerError(e.path,null));break}case`vdom_update`:{let t=this.#activeViews.get(e.path);if(!t)return;t.onUpdate(e.ops),this.#serverErrors.has(e.path)&&(this.#serverErrors.delete(e.path),this.#notifyServerError(e.path,null));break}case`server_error`:if(!this.#activeViews.has(e.path))return;this.#serverErrors.set(e.path,e.error),this.#notifyServerError(e.path,e.error);break;case`api_call`:this.#performApiCall(e);break;case`navigate_to`:{let t=!!e.replace,n=e.path||``;n.startsWith(`//`)&&(n=`${window.location.protocol}${n}`);let r=()=>t?window.location.replace(n):window.location.assign(n);if(e.hard){r();break}if(!/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(n)){this.#frameworkNavigate(n,{replace:t});break}if(/^https?:\/\//.test(n))try{let e=new URL(n);if(e.origin===window.location.origin){this.#frameworkNavigate(`${e.pathname}${e.search}${e.hash}`,{replace:t});break}}catch{}r();break}case`channel_message`:this.#routeChannelMessage(e);break;case`js_exec`:this.#handleJsExec(e);break;default:console.error(`Unexpected message:`,e)}}async#performApiCall(e){try{let t=await fetch(e.url,{method:e.method||`GET`,headers:{...e.headers||{},...e.body!=null&&!(`content-type`in(e.headers||{}))?{"content-type":`application/json`}:{}},body:e.body==null?void 0:typeof e.body==`string`?e.body:JSON.stringify(e.body),credentials:e.credentials||`include`}),n={};t.headers.forEach((e,t)=>{n[t]=e});let r=null;r=(t.headers.get(`content-type`)||``).includes(`application/json`)?await t.json().catch(()=>null):await t.text().catch(()=>null);let i={type:`api_result`,id:e.id,ok:t.ok,status:t.status,headers:n,body:r};this.sendMessage(i)}catch(t){let n={type:`api_result`,id:e.id,ok:!1,status:0,headers:{},body:{error:String(t)}};this.sendMessage(n)}}invokeCallback(e,t,n){this.sendMessage({type:`callback`,path:e,callback:t,args:n.map(It)})}#handleJsExec(e){let t=this.#activeViews.get(e.path);if(!t?.onJsExec){console.warn(`[Pulse] No onJsExec handler for path: ${e.path}`),this.#sendJsResult(e.id,void 0,`No JS executor registered`);return}t.onJsExec(e)}sendJsResult(e,t,n){this.#sendJsResult(e,t,n)}#sendJsResult(e,t,n){let r={type:`js_result`,id:e,result:t,error:n};this.sendMessage(r)}acquireChannel(e){let t=this.#ensureChannelEntry(e);return t.refCount+=1,t.bridge}releaseChannel(e){let t=this.#channels.get(e);t&&(t.refCount=Math.max(0,t.refCount-1),t.refCount===0&&(t.bridge.dispose(new y(`Channel released`)),this.sendMessage({type:`channel_message`,channel:e,event:`__close__`,payload:{reason:`refcount_zero`}}),this.#channels.delete(e)))}#ensureChannelEntry(e){let t=this.#channels.get(e);return t||(t={bridge:new ae(this,e),refCount:0},this.#channels.set(e,t)),t}#routeChannelMessage(e){let t=this.#ensureChannelEntry(e.channel);t.bridge.handleServerMessage(e)&&t.refCount===0&&this.#channels.delete(e.channel)}#handleTransportDisconnect(){for(let e of this.#channels.values())e.bridge.handleDisconnect(new y(`Connection lost`))}};const J=`$$fragment`;function Rt(e){return typeof e==`object`&&!!e}function zt(e){return typeof e==`object`&&!!e&&e.tag.startsWith(`$$`)&&e.tag!==J}const Y=`$js:`;var Bt=class{#callbacks;#callbackCache;#renderPropKeys;#jsexprPaths;#callbackList;#client;#path;#registry;constructor(e,t,n=[],r=[],i={},a=[]){this.#client=e,this.#path=t,this.#registry=i,this.#callbacks=new Set(n),this.#callbackCache=new Map,this.#renderPropKeys=new Set(r),this.#jsexprPaths=new Set(a),this.#callbackList=[...this.#callbacks].sort()}getObject(e){let t=this.#registry[e];if(t===void 0)throw Error(`[Pulse] Unknown registry key: ${e}`);return t}evaluateJsExpr(e){return Function(`get_object`,`return ${e}`)(e=>this.getObject(e))}hasCallbackPath(e){return this.#callbacks.has(e)}hasRenderPropPath(e){return this.#renderPropKeys.has(e)}hasAnyCallbackUnder(e){if(e===``)return this.#callbackList.length>0;let t=this.#lowerBound(this.#callbackList,e);return t<this.#callbackList.length&&this.#callbackList[t].startsWith(e)}applyCallbackDelta(e){if(e.remove)for(let t of e.remove)this.#callbacks.delete(t),this.#callbackCache.delete(t);if(e.add)for(let t of e.add)this.#callbacks.add(t);this.#callbackList=[...this.#callbacks].sort()}applyRenderPropsDelta(e){if(e.remove)for(let t of e.remove)this.#renderPropKeys.delete(t);if(e.add)for(let t of e.add)this.#renderPropKeys.add(t)}applyJsExprPathsDelta(e){if(e.remove)for(let t of e.remove)this.#jsexprPaths.delete(t);if(e.add)for(let t of e.add)this.#jsexprPaths.add(t)}getCallback(e,t){let n=this.#propPath(e,t),r=this.#callbackCache.get(n);return r||(r=(...e)=>this.#client.invokeCallback(this.#path,n,e),this.#callbackCache.set(n,r)),r}renderNode(t,n=``){if(t==null||typeof t==`boolean`||typeof t==`number`)return t;if(typeof t==`string`){if(t.startsWith(Y)){let e=t.slice(4);return this.evaluateJsExpr(e)}return t}if(Rt(t)){let{tag:r,props:a={},children:o=[]}=t,s={};for(let[e,t]of Object.entries(a))s[e]=this.transformValue(n,e,t);t.key&&(s.key=t.key);let c=[];for(let e=0;e<o.length;e+=1){let t=o[e],r=n?`${n}.${e}`:String(e);c.push(this.renderNode(t,r))}if(zt(t)){let e=t.tag.slice(2),n=this.#registry[e];if(!n)throw Error(`Could not find component ${e}. This is a Pulse internal error.`);return i(n,s,...c)}return i(r===J?e:r,s,...c)}return process.env.NODE_ENV!==`production`&&console.error(`Unknown VDOM node type:`,t),null}#propPath(e,t){return e?`${e}.${t}`:t}transformValue(e,t,n){let r=this.#propPath(e,t);if(this.#callbacks.has(r))return this.getCallback(e,t);if(this.#renderPropKeys.has(r))return this.renderNode(n,r);if(typeof n==`string`&&n.startsWith(Y)){let e=n.slice(4);return this.evaluateJsExpr(e)}return n}init(e){this.#callbacks=new Set(e.callbacks);for(let e of Array.from(this.#callbackCache.keys()))this.#callbacks.has(e)||this.#callbackCache.delete(e);return this.#callbackList=[...this.#callbacks].sort(),this.#renderPropKeys=new Set(e.render_props),this.#jsexprPaths=new Set(e.jsexpr_paths),this.renderNode(e.vdom)}#ensureChildrenArray(e){let t=e.props?.children;return t==null?[]:Array.isArray(t)?t.slice():[t]}applyUpdates(e,t){let r=e;for(let e of t){if(e.type===`update_callbacks`){this.applyCallbackDelta(e.data);continue}if(e.type===`update_render_props`){this.applyRenderPropsDelta(e.data);continue}if(e.type===`update_jsexpr_paths`){this.applyJsExprPathsDelta(e.data);continue}let t=e.path.split(`.`).filter(e=>e.length>0),a=(r,o,s)=>{if(o<t.length){this.#assertIsElement(r,t,o);let e=r,i=t[o],c=+i,l=s?`${s}.${i}`:i;if(Number.isNaN(c)){let t=e.props??{},r=t[i];return n(e,{...t,[i]:a(r,o+1,l)})}else{let t=this.#ensureChildrenArray(e),r=t[c];return t[c]=a(r,o+1,l),n(e,void 0,...t)}}switch(e.type){case`replace`:return this.renderNode(e.data,e.path);case`update_props`:{this.#assertIsElement(r,t,o);let a=r,c={...a.props??{}},l=e.data;if(l.remove&&l.remove.length>0)for(let e of l.remove)e in c&&delete c[e];if(l.set)for(let[e,t]of Object.entries(l.set))c[e]=this.transformValue(s,e,t);return(l.remove?.length??0)>0?(c.key=a.key,c.ref=a.ref,i(a.type,c,...this.#ensureChildrenArray(a))):n(a,c)}case`reconciliation`:{this.#assertIsElement(r,t,o);let i=r,a=this.#ensureChildrenArray(i),c=[],[l,u]=e.new,[d,f]=e.reuse,p=-1,m=-1,h=-1,g=-1;l.length>0&&(p=l[0],h=0),d.length>0&&(m=d[0],g=0);for(let t=0;t<e.N;++t)if(t===p){let e=u[h],n=s?`${s}.${t}`:String(t);c.push(this.renderNode(e,n)),p=h<l.length-1?l[++h]:-1}else if(t===m){let e=a[f[g]],n=s?`${s}.${t}`:String(t);this.hasAnyCallbackUnder(n)&&(e=this.#rebindCallbacksInSubtree(e,n)),c.push(e),m=g<d.length-1?d[++g]:-1}else c.push(a[t]);return n(i,null,...c)}default:throw Error(`[Pulse renderer] Unknown update type: ${e?.type}`)}};r=a(r,0,``)}return r}#assertIsElement(e,t,n){if(process.env.NODE_ENV!==`production`&&!o(e))throw console.error(`Invalid node:`,e),Error(`Invalid node at path ${t.slice(0,n).join(`.`)}`);return!0}#rebindCallbacksInSubtree(e,t){if(!o(e))return e;let r=e,i=r.props??{},a={...i};for(let e of Object.keys(i)){let n=t?`${t}.${e}`:e;this.hasCallbackPath(n)&&(a[e]=this.getCallback(t,e)),this.hasRenderPropPath(n)&&this.hasAnyCallbackUnder(n)&&(a[e]=this.#rebindCallbacksInSubtree(i[e],n))}return n(r,a,...this.#ensureChildrenArray(r).map((e,n)=>{let r=t?`${t}.${n}`:String(n);return this.hasAnyCallbackUnder(r)?this.#rebindCallbacksInSubtree(e,r):e}))}#lowerBound(e,t){let n=0,r=e.length;for(;n<r;){let i=n+r>>>1;e[i]<t?n=i+1:r=i}return n}};function Vt(e,n){let r=s(e);return({children:e,...i})=>m(t,{fallback:n,children:m(r,{...i,children:e})})}const X=r(null),Z=r(null),Q=()=>{let e=l(X);if(!e)throw Error(`usePulseClient must be used within a PulseProvider`);return e},Ht=e=>{let t=l(Z);if(!t)throw Error(`usePulsePrerender must be used within a PulseProvider`);let n=t.views[e];if(!n)throw Error(`No prerender found for '${e}'`);return n},$=typeof window<`u`;function Ut({children:e,config:t,prerender:n}){let[r,i]=p(`ok`),a=_(),{directives:o}=n,s=d(()=>new Lt(t.serverAddress,o,a,t.connectionStatus),[t.serverAddress,a,t.connectionStatus]);u(()=>s.setDirectives(o),[s,o]),u(()=>{if(!$)return;let e=s.onConnectionChange(e=>{i(e)});return s.connect(),()=>{e(),s.disconnect()}},[s]);let c=(()=>{switch(r){case`connecting`:return`Connecting...`;case`reconnecting`:return`Reconnecting...`;case`error`:return`Failed to connect to the server.`;default:return null}})();return m(X.Provider,{value:s,children:h(Z.Provider,{value:n,children:[c&&m(`div`,{style:{position:`fixed`,bottom:`20px`,right:`20px`,backgroundColor:r===`error`?`red`:`#666`,color:`white`,padding:`10px`,borderRadius:`5px`,zIndex:1e3},children:c}),e]})})}function Wt({path:e,registry:t}){let n=Q(),r=Ht(e),i=d(()=>new Bt(n,e,r.callbacks,r.render_props,t,r.jsexpr_paths),[n,e,t]),[a,o]=p(()=>i.init(r)),[s,c]=p(null),l=g(),h=ee(),_=d(()=>{let{"*":e=``,...t}=h,n=new URLSearchParams(l.search);return{hash:l.hash,pathname:l.pathname,query:l.search,queryParams:Object.fromEntries(n.entries()),pathParams:t,catchall:e.length>0?e.split(`/`):[]}},[l.hash,l.pathname,l.search,JSON.stringify(h)]);u(()=>{if($){n.mountView(e,{routeInfo:_,onInit:e=>{o(i.init(e))},onUpdate:e=>{o(t=>t==null?t:i.applyUpdates(t,e))},onJsExec:e=>{let t,r=null;try{t=i.evaluateJsExpr(e.code)}catch(e){r=e instanceof Error?e.message:String(e)}n.sendJsResult(e.id,t,r)}});let t=n.onServerError((t,n)=>{t===e&&c(n)});return()=>{t(),n.unmount(e)}}},[n,i,e]),u(()=>{$&&n.navigate(e,_)},[n,e,_]);let v=f(!1);return u(()=>(v.current?o(i.init(r)):v.current=!0,()=>{v.current=!1}),[r,i]),s?m(Gt,{error:s}):a}function Gt({error:e}){return h(`div`,{style:{padding:16,border:`1px solid #e00`,background:`#fff5f5`,color:`#900`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`,whiteSpace:`pre-wrap`},children:[h(`div`,{style:{fontWeight:700,marginBottom:8},children:[`Server Error during `,e.phase]}),e.message&&m(`div`,{children:e.message}),e.stack&&h(`details`,{open:!0,style:{marginTop:8},children:[m(`summary`,{children:`Stack trace`}),m(`pre`,{style:{margin:0},children:e.stack})]})]})}function Kt(e){let t=Q(),n=d(()=>{if(!e)throw Error(`usePulseChannel requires a non-empty channelId`);return t.acquireChannel(e)},[t,e]);return u(()=>()=>{t.releaseChannel(e)},[t,e]),n}export{y as PulseChannelResetError,oe as PulseForm,Ut as PulseProvider,Wt as PulseView,Vt as RenderLazy,q as deserialize,se as extractServerRouteInfo,K as serialize,b as submitForm,Kt as usePulseChannel,Q as usePulseClient};
1
+ import{Fragment as e,cloneElement as t,createContext as n,createElement as r,forwardRef as i,isValidElement as a,useCallback as o,useContext as s,useEffect as c,useMemo as l,useRef as u,useState as d}from"react";import{useLocation as f,useNavigate as p,useParams as m}from"react-router";import{io as h}from"socket.io-client";import{jsx as g,jsxs as _}from"react/jsx-runtime";function v(){function e(e,t){return n=>{let r={};for(let t of e)r[t]=n[t];if(t)for(let e in t){let i=t[e];r[e]=i(n)}return r}}return e}const y=e=>e.tagName.toLowerCase(),ee=[`id`,`className`,`tagName`,`localName`,`clientHeight`,`clientLeft`,`clientTop`,`clientWidth`,`scrollHeight`,`scrollLeft`,`scrollTop`,`scrollWidth`,`slot`],te=[`autofocus`,`tabIndex`,`nonce`],ne=[`accessKey`,`accessKeyLabel`,`autocapitalize`,`dir`,`draggable`,`hidden`,`inert`,`lang`,`offsetHeight`,`offsetLeft`,`offsetTop`,`offsetWidth`,`popover`,`spellcheck`,`title`,`translate`,`writingSuggestions`,`contentEditable`,`enterKeyHint`,`isContentEditable`,`inputMode`],b=v()(ee,{tagName:y}),x=v()(te),re=v()(ne);function S(e){return{...b(e),...x(e),...re(e)}}function C(e,t){let n=v()(e,t);return e=>({...S(e),...n(e)})}const ie=C([`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`search`,`target`,`download`,`rel`,`hreflang`,`type`,`username`,`ping`,`referrerPolicy`,`text`]),ae=C([`alt`,`coords`,`download`,`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`rel`,`search`,`shape`,`target`,`username`,`ping`,`referrerPolicy`]),w=C([`autoplay`,`controls`,`crossOrigin`,`currentSrc`,`currentTime`,`defaultMuted`,`defaultPlaybackRate`,`duration`,`ended`,`loop`,`muted`,`networkState`,`paused`,`playbackRate`,`preload`,`readyState`,`seeking`,`src`,`volume`,`preservesPitch`]),oe=e=>w(e),se=C([`disabled`,`name`,`type`,`value`,`formAction`,`formEnctype`,`formMethod`,`formNoValidate`,`formTarget`,`popoverTargetAction`]),ce=C([`value`]),le=C([`height`,`src`,`type`,`width`,`align`,`name`]),ue=C([`disabled`,`name`,`type`,`validationMessage`,`willValidate`]),de=C([`acceptCharset`,`action`,`autocomplete`,`encoding`,`enctype`,`length`,`method`,`name`,`noValidate`,`target`,`rel`]),fe=C([`allow`,`allowFullscreen`,`height`,`name`,`referrerPolicy`,`src`,`srcdoc`,`width`,`align`,`frameBorder`,`longDesc`,`marginHeight`,`marginWidth`,`scrolling`,`sandbox`]),pe=C([`alt`,`crossOrigin`,`decoding`,`height`,`isMap`,`loading`,`naturalHeight`,`naturalWidth`,`referrerPolicy`,`sizes`,`src`,`srcset`,`useMap`,`width`,`align`,`border`,`complete`,`hspace`,`longDesc`,`lowsrc`,`name`,`vspace`,`x`,`y`,`fetchPriority`]),me=C(`accept.alt.autocomplete.checked.defaultChecked.defaultValue.dirName.disabled.height.indeterminate.max.maxLength.min.minLength.multiple.name.pattern.placeholder.readOnly.required.selectionDirection.selectionEnd.selectionStart.size.src.step.type.value.valueAsNumber.width.align.capture.formAction.formEnctype.formMethod.formNoValidate.formTarget.useMap.validationMessage.willValidate.popoverTargetAction`.split(`.`),{valueAsNumber:e=>{let t=e.valueAsNumber;return Number.isFinite(t)?t:null}}),he=C([`htmlFor`]),ge=C([`value`,`type`]),_e=C([`as`,`crossOrigin`,`disabled`,`fetchPriority`,`href`,`hreflang`,`imageSizes`,`imageSrcset`,`integrity`,`media`,`referrerPolicy`,`rel`,`type`,`charset`,`rev`,`target`,`sizes`]),ve=C([`name`]),ye=C([`high`,`low`,`max`,`min`,`optimum`,`value`]),T=C([`cite`,`dateTime`]),be=C([`reversed`,`start`,`type`,`compact`]),xe=C([`data`,`height`,`name`,`type`,`useMap`,`width`,`validationMessage`,`willValidate`,`align`,`archive`,`border`,`code`,`codeBase`,`codeType`,`declare`,`hspace`,`standby`,`vspace`]),Se=C([`disabled`,`label`]),Ce=C([`defaultSelected`,`disabled`,`index`,`label`,`selected`,`text`,`value`]),we=C([`defaultValue`,`name`,`type`,`value`,`htmlFor`,`validationMessage`,`willValidate`]),Te=C([`max`,`position`,`value`]),E=C([`cite`]),Ee=e=>S(e),De=v()([`async`,`crossOrigin`,`defer`,`fetchPriority`,`integrity`,`noModule`,`referrerPolicy`,`src`,`text`,`type`,`charset`],{event:e=>e.event,htmlFor:e=>e.htmlFor}),Oe=e=>({...S(e),...De(e)}),ke=C([`autocomplete`,`disabled`,`length`,`multiple`,`name`,`required`,`selectedIndex`,`size`,`type`,`value`,`validationMessage`,`willValidate`]),Ae=C([`name`]),je=C([`height`,`media`,`sizes`,`src`,`srcset`,`type`,`width`]),Me=C([`align`]),D=C([`abbr`,`cellIndex`,`colSpan`,`headers`,`rowSpan`,`scope`,`align`,`axis`,`bgColor`,`ch`,`chOff`,`height`,`noWrap`,`vAlign`,`width`]),O=C([`span`,`align`,`ch`,`chOff`,`vAlign`,`width`]),Ne=C([`align`,`bgColor`,`border`,`cellPadding`,`cellSpacing`,`frame`,`rules`,`summary`,`width`]),Pe=C([`rowIndex`,`sectionRowIndex`,`align`,`bgColor`,`ch`,`chOff`,`vAlign`]),k=C([`align`,`ch`,`chOff`,`vAlign`]),Fe=e=>S(e),Ie=C([`autocomplete`,`cols`,`defaultValue`,`dirName`,`disabled`,`maxLength`,`minLength`,`name`,`placeholder`,`readOnly`,`required`,`rows`,`selectionDirection`,`selectionEnd`,`selectionStart`,`value`,`wrap`,`textLength`,`validationMessage`,`willValidate`]),Le=C([`dateTime`]),Re=C([`default`,`kind`,`label`,`readyState`,`src`,`srclang`]),ze=v()([`height`,`poster`,`videoHeight`,`videoWidth`,`width`,`playsInline`]),Be=e=>({...w(e),...ze(e)}),Ve=C([`clear`]),He=C([`href`,`target`]),Ue=C([`aLink`,`background`,`bgColor`,`link`,`text`,`vLink`]),We=C([`compact`]),Ge=C([`open`]),Ke=C([`open`,`returnValue`]),qe=C([`align`]),Je=e=>S(e),A=C([`align`]),Ye=C([`align`,`color`,`noShade`,`size`,`width`]),Xe=C([`version`]),Ze=e=>S(e),Qe=C([`content`,`httpEquiv`,`name`,`scheme`]),$e=C([`align`]),et=e=>S(e),tt=C([`width`]),nt=e=>S(e),rt=C([`media`,`type`,`disabled`]),it=C([`text`]),at=C([`compact`,`type`]);function j(e){return{...b(e),...x(e)}}function M(e,t){let n=v()(e,t);return e=>({...j(e),...n(e)})}const N={A:ie,AREA:ae,AUDIO:oe,BASE:He,BLOCKQUOTE:E,Q:E,BODY:Ue,BR:Ve,BUTTON:se,CANVAS:S,CAPTION:Me,CITE:Ee,COL:O,COLGROUP:O,DATA:ce,DETAILS:Ge,DIALOG:Ke,DIV:qe,DL:We,EMBED:le,FIELDSET:ue,FORM:de,H1:A,H2:A,H3:A,H4:A,H5:A,H6:A,HEAD:Je,HR:Ye,HTML:Xe,IFRAME:fe,IMG:pe,INPUT:me,LABEL:he,LI:ge,LINK:_e,MAP:ve,MENU:Ze,META:Qe,METER:ye,INS:T,DEL:T,OBJECT:xe,OL:be,OPTGROUP:Se,OPTION:Ce,OUTPUT:we,P:$e,PICTURE:et,PRE:tt,PROGRESS:Te,SCRIPT:Oe,SELECT:ke,SLOT:Ae,SOURCE:je,SPAN:nt,STYLE:rt,TABLE:Ne,TBODY:k,THEAD:k,TFOOT:k,TD:D,TH:D,TEMPLATE:Fe,TEXTAREA:Ie,TIME:Le,TITLE:it,TR:Pe,TRACK:Re,UL:at,VIDEO:Be,SVG:M([`x`,`y`,`width`,`height`,`currentScale`,`currentTranslate`]),CIRCLE:M([`cx`,`cy`,`r`]),ELLIPSE:M([`cx`,`cy`,`rx`,`ry`]),LINE:M([`x1`,`y1`,`x2`,`y2`]),PATH:M([`pathLength`]),RECT:M([`x`,`y`,`width`,`height`,`rx`,`ry`]),POLYGON:M([`points`]),POLYLINE:M([`points`]),TEXT:M([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),TSPAN:M([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),IMAGE:M([`x`,`y`,`width`,`height`,`href`,`preserveAspectRatio`,`crossOrigin`]),USE:M([`x`,`y`,`width`,`height`,`href`]),DEFS:M([]),G:M([]),LINEARGRADIENT:M([`x1`,`y1`,`x2`,`y2`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),RADIALGRADIENT:M([`cx`,`cy`,`r`,`fx`,`fy`,`fr`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),STOP:M([`offset`]),PATTERN:M([`x`,`y`,`width`,`height`,`patternUnits`,`patternContentUnits`,`patternTransform`,`preserveAspectRatio`,`href`]),CLIPPATH:M([`clipPathUnits`]),MASK:M([`x`,`y`,`width`,`height`,`maskUnits`,`maskContentUnits`])};function ot(e){let t=N[e.tagName.toUpperCase()];if(t)return t(e);throw Error(`Unexpected HTML element tag: ${e.tagName} (update .web/custom/serialize.ts)`)}function st(e){let t=N[e.tagName.toUpperCase()];return t?t(e):j(e)}function P(e){return e instanceof HTMLElement?ot(e):e instanceof SVGElement?st(e):b(e)}const ct=e=>P(e.target),F=e=>e.relatedTarget?P(e.relatedTarget):null;function I(e,t){return v()(e,{target:ct,...t||{}})}const L=[`target`,`bubbles`,`cancelable`,`defaultPrevented`,`eventPhase`,`isTrusted`,`timeStamp`,`type`],R=[...L,`detail`],z=[...R,`altKey`,`button`,`buttons`,`clientX`,`clientY`,`ctrlKey`,`metaKey`,`movementX`,`movementY`,`pageX`,`pageY`,`screenX`,`screenY`,`shiftKey`],lt=[...z,`pointerId`,`pressure`,`tangentialPressure`,`tiltX`,`tiltY`,`twist`,`width`,`height`,`pointerType`,`isPrimary`],ut=I(L),dt=I(R),ft=I(z,{relatedTarget:F}),pt=I(L,{clipboardData:e=>V(e.clipboardData)}),mt=I([...L,`data`]),ht=I(z,{relatedTarget:F,dataTransfer:e=>V(e.dataTransfer)}),gt=I(lt,{relatedTarget:F}),_t=I(L,{relatedTarget:F}),vt=I(L),yt=I(L),bt=I(L),xt=I([...R,`altKey`,`ctrlKey`,`code`,`key`,`locale`,`location`,`metaKey`,`repeat`,`shiftKey`]),St=I([...R,`altKey`,`ctrlKey`,`metaKey`,`shiftKey`,`changedTouches`,`targetTouches`,`touches`],{changedTouches:e=>B(e.changedTouches),targetTouches:e=>B(e.targetTouches),touches:e=>B(e.touches)}),Ct=I([...z,`deltaMode`,`deltaX`,`deltaY`,`deltaZ`],{relatedTarget:F}),wt=I([...L,`animationName`,`elapsedTime`,`pseudoElement`]),Tt=I([...L,`oldState`,`newState`]),Et=I([...L,`elapsedTime`,`propertyName`,`pseudoElement`]);function B(e){return Array.from(e).map(e=>({target:P(e.target),identifier:e.identifier,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,pageX:e.pageX,pageY:e.pageY}))}function V(e){if(!e)return null;let t=[];if(e.items)for(let n=0;n<e.items.length;n++){let r=e.items[n];t.push({kind:r.kind,type:r.type})}return{drop_effect:e.dropEffect,effect_allowed:e.effectAllowed,items:t,types:Array.from(e.types||[])}}const H={};function U(e,t,n){for(let r of t)e[r]=n}U(H,[`pointerdown`,`pointermove`,`pointerup`,`pointercancel`,`gotpointercapture`,`lostpointercapture`,`pointerenter`,`pointerleave`,`pointerover`,`pointerout`],gt),U(H,[`click`,`contextmenu`,`dblclick`,`mousedown`,`mouseenter`,`mouseleave`,`mousemove`,`mouseout`,`mouseover`,`mouseup`],ft),U(H,[`drag`,`dragend`,`dragenter`,`dragexit`,`dragleave`,`dragover`,`dragstart`,`drop`],ht),U(H,[`keydown`,`keypress`,`keyup`],xt),U(H,[`focus`,`blur`],_t),U(H,[`change`,`input`],bt),U(H,[`invalid`],yt),U(H,[`reset`,`submit`],vt),U(H,[`copy`,`cut`,`paste`],pt),U(H,[`compositionend`,`compositionstart`,`compositionupdate`],mt),U(H,[`touchcancel`,`touchend`,`touchmove`,`touchstart`],St),U(H,[`scroll`],dt),U(H,[`wheel`],Ct),U(H,[`animationstart`,`animationend`,`animationiteration`],wt),U(H,[`transitionend`],Et),U(H,[`toggle`],Tt);function Dt(e){if(e&&typeof e==`object`&&`nativeEvent`in e&&typeof e.isDefaultPrevented==`function`){let t=e;if(typeof t.type!=`string`)return e;let n=H[t.type.toLowerCase()];return n?n(t):ut(t)}return e}function W(e){let t=new Map,n=[],r=[],i=[],a=[],o=0;function s(e,c){if(e==null||typeof e==`string`||typeof e==`boolean`)return e;if(typeof e==`number`){if(Number.isNaN(e))return null;if(!Number.isFinite(e)){let t=e>0?`Infinity`:`-Infinity`,n=c?` in '${c}'`:``;throw Error(`Cannot serialize ${t}${n}. NaN and Infinity are not supported because they cannot be serialized to JSON.`)}return e}let l=o++,u=t.get(e);if(u!==void 0)return n.push(l),u;if(t.set(e,l),e instanceof Date)return r.push(l),e.getTime();if(Array.isArray(e)){let t=e.length,n=Array(t);for(let r=0;r<t;r++)n[r]=s(e[r],c);return n}if(e instanceof Map){a.push(l);let t={};for(let[n,r]of e.entries())t[String(n)]=s(r,String(n));return t}if(e instanceof Set){i.push(l);let t=e.size,n=Array(t),r=0;for(let t of e)n[r]=s(t,c),r+=1;return n}if(typeof e==`object`){let t={},n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t[i]=s(e[i],i)}return t}throw Error(`Unsupported value in serialization: ${e}`)}let c=s(e);return[[n,r,i,a],c]}function G(e,t){let[[n,r,i,a],o]=e,s=new Set(n),c=new Set(r),l=new Set(i),u=new Set(a),d=[];function f(e){let n=d.length;if(s.has(n))return d.push(null),d[e];if(c.has(n)){let t=new Date(e);return d.push(t),t}if(e==null||typeof e==`number`||typeof e==`string`||typeof e==`boolean`)return t?.coerceNullsToUndefined?e??void 0:e;if(Array.isArray(e)){if(l.has(n)){let t=new Set;d.push(t);for(let n=0;n<e.length;n++)t.add(f(e[n]));return t}let t=e.length,r=Array(t);d.push(r);for(let n=0;n<t;n++)r[n]=f(e[n]);return r}if(typeof e==`object`){if(u.has(n)){let t=new Map;d.push(t);let n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t.set(i,f(e[i]))}return t}let t={};d.push(t);let r=Object.keys(e);for(let n=0;n<r.length;n++){let i=r[n];t[i]=f(e[i])}return t}throw Error(`Unsupported value in deserialization: ${e}`)}return f(o)}var Ot=class{#e;#t=null;#n;#r=new Set;#i=new Map;#a;#o;#s;#c;#l=!1;#u=null;#d=null;#f=`ok`;constructor(e,t,n,r){this.#a=e,this.#s=t,this.#o=n,this.#t=null,this.#e=new Map,this.#n=[],this.#c=r}setDirectives(e){this.#s=e}isConnected(){return this.#t?.connected??!1}#p(){this.#u&&=(clearTimeout(this.#u),null),this.#d&&=(clearTimeout(this.#d),null)}#m(e){this.#p(),this.#f=e,this.#v(e)}#h(){this.#l=!0,this.#m(`ok`)}#g(){this.#m(`ok`),this.#u=setTimeout(()=>{this.#m(`connecting`),this.#d=setTimeout(()=>{this.#m(`error`)},this.#c.initialErrorDelay)},this.#c.initialConnectingDelay)}#_(){this.#m(`reconnecting`),this.#d=setTimeout(()=>{this.#m(`error`)},this.#c.reconnectErrorDelay)}async connect(){if(!this.#t)return this.#l||this.#g(),new Promise((e,t)=>{let n=h(this.#a,{transports:[`websocket`,`webtransport`],auth:this.#s.socketio?.auth,extraHeaders:this.#s.socketio?.headers});this.#t=n,n.on(`connect`,()=>{console.log(`[SocketIOTransport] Connected:`,this.#t?.id);for(let[e,t]of this.#e)n.emit(`message`,W({type:`attach`,path:e,routeInfo:t.routeInfo}));for(let e of this.#n)e.type===`attach`&&this.#e.has(e.path)||e.type!==`update`&&n.emit(`message`,W(e));this.#n=[],this.#h(),e()}),n.on(`connect_error`,e=>{console.error(`[SocketIOTransport] Connection failed:`,e),this.#_(),t(e)}),n.on(`disconnect`,()=>{console.log(`[SocketIOTransport] Disconnected`),this.#T(),this.#_()}),n.on(`message`,e=>this.#y(G(e,{coerceNullsToUndefined:!0})))})}onConnectionChange(e){return this.#r.add(e),e(this.#f),()=>{this.#r.delete(e)}}#v(e){for(let t of this.#r)t(e)}sendMessage(e){this.isConnected()?this.#t.emit(`message`,W(e)):this.#n.push(e)}attach(e,t){if(this.#e.has(e))throw Error(`Path ${e} is already attached`);this.#e.set(e,t),this.sendMessage({type:`attach`,path:e,routeInfo:t.routeInfo})}updateRoute(e,t){let n=this.#e.get(e);n&&(n.routeInfo=t,this.sendMessage({type:`update`,path:e,routeInfo:t}))}detach(e){this.sendMessage({type:`detach`,path:e}),this.#e.delete(e)}disconnect(){this.#p(),this.#t?.disconnect(),this.#t=null,this.#n=[],this.#r.clear(),this.#e.clear();for(let{bridge:e}of this.#i.values())e.dispose(new $(`Client disconnected`));this.#i.clear(),this.#f=`ok`,this.#l=!1}#y(e){switch(e.type){case`vdom_init`:{let t=this.#e.get(e.path);if(!t)return;t.onInit(e);break}case`vdom_update`:{let t=this.#e.get(e.path);if(!t)return;t.onUpdate(e.ops);break}case`server_error`:{let t=this.#e.get(e.path);if(!t)return;t.onServerError(e.error);break}case`api_call`:this.#b(e);break;case`navigate_to`:{let t=!!e.replace,n=e.path||``;n.startsWith(`//`)&&(n=`${window.location.protocol}${n}`);let r=()=>t?window.location.replace(n):window.location.assign(n);if(e.hard){r();break}if(!/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(n)){this.#o(n,{replace:t});break}if(/^https?:\/\//.test(n))try{let e=new URL(n);if(e.origin===window.location.origin){this.#o(`${e.pathname}${e.search}${e.hash}`,{replace:t});break}}catch{}r();break}case`channel_message`:this.#w(e);break;case`js_exec`:this.#x(e);break;default:console.error(`Unexpected message:`,e)}}async#b(e){try{let t=await fetch(e.url,{method:e.method||`GET`,headers:{...e.headers||{},...e.body!=null&&!(`content-type`in(e.headers||{}))?{"content-type":`application/json`}:{}},body:e.body==null?void 0:typeof e.body==`string`?e.body:JSON.stringify(e.body),credentials:e.credentials||`include`}),n={};t.headers.forEach((e,t)=>{n[t]=e});let r=null;r=(t.headers.get(`content-type`)||``).includes(`application/json`)?await t.json().catch(()=>null):await t.text().catch(()=>null);let i={type:`api_result`,id:e.id,ok:t.ok,status:t.status,headers:n,body:r};this.sendMessage(i)}catch(t){let n={type:`api_result`,id:e.id,ok:!1,status:0,headers:{},body:{error:String(t)}};this.sendMessage(n)}}invokeCallback(e,t,n){this.sendMessage({type:`callback`,path:e,callback:t,args:n.map(Dt)})}#x(e){let t=this.#e.get(e.path);if(!t){this.#S(e.id,void 0,null);return}t.onJsExec(e)}sendJsResult(e,t,n){this.#S(e,t,n)}#S(e,t,n){let r={type:`js_result`,id:e,result:t,error:n};this.sendMessage(r)}acquireChannel(e){let t=this.#C(e);return t.refCount+=1,t.bridge}releaseChannel(e){let t=this.#i.get(e);t&&(t.refCount=Math.max(0,t.refCount-1),t.refCount===0&&(t.bridge.dispose(new $(`Channel released`)),this.sendMessage({type:`channel_message`,channel:e,event:`__close__`,payload:{reason:`refcount_zero`}}),this.#i.delete(e)))}#C(e){let t=this.#i.get(e);return t||(t={bridge:new zt(this,e),refCount:0},this.#i.set(e,t)),t}#w(e){let t=this.#C(e.channel);t.bridge.handleServerMessage(e)&&t.refCount===0&&this.#i.delete(e.channel)}#T(){for(let e of this.#i.values())e.bridge.handleDisconnect(new $(`Connection lost`))}};function K(e){return typeof e==`object`&&!!e&&`tag`in e}function q(e){return typeof e==`object`&&!!e&&`t`in e}function kt(e){return K(e)&&e.tag.startsWith(`$$`)&&e.tag!==``}function At(e){return e===`$cb`}var J=class{#e;#t;#n;#r;#i;constructor(e,t,n={}){this.#e=e,this.#t=t,this.#n=n,this.#r=new Map,this.#i=new WeakMap}getObject(e){let t=this.#n[e];if(t===void 0)throw Error(`[Pulse] Unknown registry key: ${e}`);return t}#a(e){let t=globalThis[e];if(t===void 0)throw Error(`[Pulse] Unknown identifier in expr: ${e}`);return t}#o(e,t){if(typeof e!=`object`||!e)return e;if(`tag`in e)return this.renderNode(e,``);switch(e.t){case`ref`:return this.getObject(e.key);case`id`:return Object.hasOwn(t,e.name)?t[e.name]:this.#a(e.name);case`lit`:return e.value;case`undef`:return;case`array`:{let n=[];for(let r of e.items)n.push(this.#o(r,t));return n}case`object`:{let n={};for(let[r,i]of Object.entries(e.props))n[r]=this.#o(i,t);return n}case`member`:return this.#o(e.obj,t)?.[e.prop];case`sub`:{let n=this.#o(e.obj,t),r=this.#o(e.key,t);return n?.[r]}case`call`:{let n=this.#o(e.callee,t),r=e.args.map(e=>this.#o(e,t));if(typeof n!=`function`)throw Error(`[Pulse] call callee is not a function`);return n(...r)}case`unary`:{let n=this.#o(e.arg,t);switch(e.op){case`!`:return!n;case`+`:return+n;case`-`:return-n;case`typeof`:return typeof n;case`void`:return;default:throw Error(`[Pulse] Unsupported unary op: ${e.op}`)}}case`binary`:{let n=this.#o(e.left,t),r=this.#o(e.right,t);switch(e.op){case`+`:return n+r;case`-`:return n-r;case`*`:return n*r;case`/`:return n/r;case`%`:return n%r;case`&&`:return n&&r;case`||`:return n||r;case`??`:return n??r;case`**`:return n**r;case`in`:return n in r;case`instanceof`:return n instanceof r;case`===`:return n===r;case`!==`:return n!==r;case`<`:return n<r;case`<=`:return n<=r;case`>`:return n>r;case`>=`:return n>=r;default:throw Error(`[Pulse] Unsupported binary op: ${e.op}`)}}case`ternary`:return this.#o(e.cond,t)?this.#o(e.then,t):this.#o(e.else_,t);case`template`:{let n=``;for(let r of e.parts)typeof r==`string`?n+=r:n+=String(this.#o(r,t));return n}case`arrow`:{let n=e.params;return(...r)=>{let i={...t};for(let e=0;e<n.length;e+=1)i[n[e]]=r[e];return this.#o(e.body,i)}}case`new`:return new(this.#o(e.ctor,t))(...e.args.map(e=>this.#o(e,t)));default:throw Error(`[Pulse] Unknown expr node: ${e.t}`)}}#s(e,t){return e?`${e}.${t}`:t}#c(e,t){let n=this.#s(e,t),r=this.#r.get(n);return r||(r=(...e)=>this.#e.invokeCallback(this.#t,n,e),this.#r.set(n,r)),r}#l(e,t,n){return At(n)?this.#c(e,t):q(n)?this.#o(n,{}):typeof n==`object`&&n&&`tag`in n?this.renderNode(n,this.#s(e,t)):n}#u(e,t){return this.#i.set(e,t),e}renderNode(t,n=``){if(t==null||typeof t==`boolean`||typeof t==`number`||typeof t==`string`)return t;if(q(t))return this.#o(t,{});if(K(t)){let{tag:i,props:a={},children:o=[],eval:s}=t,c,l={},u;if(s){u=new Set(s);for(let[e,t]of Object.entries(a)){if(!u.has(e)){l[e]=t;continue}t===`$cb`&&(c||=new Set,c.add(e)),l[e]=this.#l(n,e,t)}}else for(let[e,t]of Object.entries(a))l[e]=t;t.key&&(l.key=t.key);let d=[];for(let e=0;e<o.length;e+=1){let t=o[e],r=n?`${n}.${e}`:String(e);d.push(this.renderNode(t,r))}if(kt(t)){let e=i.slice(2),t=this.#n[e];if(!t)throw Error(`[Pulse] Missing component for mount point: ${e}`);return this.#u(r(t,l,...d),{eval:u,cbKeys:c})}return this.#u(r(i===``?e:i,l,...d),{eval:u,cbKeys:c})}return process.env.NODE_ENV!==`production`&&console.error(`Unknown VDOM node:`,t),null}init(e){return this.renderNode(e.vdom)}evaluateExpr(e){return this.#o(e,{})}#d(e){let t=e.props?.children;return t==null?[]:Array.isArray(t)?t.slice():[t]}#f(e,t){let n=this.#i.get(e);return n&&this.#i.set(t,n),t}#p(e,n){if(!a(e))return e;let r=e,i=r.props??{},o={...i},s=this.#i.get(r)?.cbKeys;if(s&&s.size>0)for(let e of s)o[e]=this.#c(n,e);for(let e of Object.keys(i)){let t=i[e];a(t)&&(o[e]=this.#p(t,this.#s(n,e)))}let c=this.#d(r).map((e,t)=>{let r=n?`${n}.${t}`:String(t);return this.#p(e,r)});return this.#f(r,t(r,o,...c))}applyUpdates(e,n){let i=e;for(let e of n){let n=e.path.split(`.`).filter(e=>e.length>0),a=(i,o,s)=>{if(o<n.length){this.#m(i,n,o);let e=i,r=n[o],c=+r,l=s?`${s}.${r}`:r;if(Number.isNaN(c)){let n=e.props??{},i=n[r],s={...n,[r]:a(i,o+1,l)};return this.#f(e,t(e,s))}else{let n=this.#d(e),r=n[c];return n[c]=a(r,o+1,l),this.#f(e,t(e,void 0,...n))}}switch(e.type){case`replace`:return this.renderNode(e.data,e.path);case`update_props`:{this.#m(i,n,o);let a=i,c={...a.props??{}},l=this.#i.get(a),u=l?.eval,d=l?.cbKeys,f=e.data.eval,p=f===void 0?u:f.length===0?void 0:new Set(f),m=f!==void 0&&f.length===0,h;if(p){let e=new Set;if(d)for(let t of d)p.has(t)&&e.add(t);h=e}if(m&&d)for(let e of d)delete c[e];if(e.data.remove&&e.data.remove.length>0)for(let t of e.data.remove)delete c[t],h?.delete(t);if(e.data.set)for(let[t,n]of Object.entries(e.data.set)){let e=p?.has(t)===!0;c[t]=e?this.#l(s,t,n):n,h&&(e&&n===`$cb`?h.add(t):h.delete(t))}return h&&h.size===0&&(h=void 0),(e.data.remove?.length??0)>0?(c.key=a.key,c.ref=a.ref,this.#u(r(a.type,c,...this.#d(a)),{eval:p,cbKeys:h})):this.#u(t(a,c),{eval:p,cbKeys:h})}case`reconciliation`:{this.#m(i,n,o);let r=i,a=this.#d(r),c=[],[l,u]=e.new,[d,f]=e.reuse,p=-1,m=-1,h=-1,g=-1;l.length>0&&(p=l[0],h=0),d.length>0&&(m=d[0],g=0);for(let t=0;t<e.N;t+=1)if(t===p){let e=u[h],n=s?`${s}.${t}`:String(t);c.push(this.renderNode(e,n)),p=h<l.length-1?l[++h]:-1}else if(t===m){let e=a[f[g]],n=s?`${s}.${t}`:String(t);e=this.#p(e,n),c.push(e),m=g<d.length-1?d[++g]:-1}else c.push(a[t]);return this.#f(r,t(r,null,...c))}default:throw Error(`[Pulse renderer] Unknown update type: ${e?.type}`)}};i=a(i,0,``)}return i}#m(e,t,n){if(process.env.NODE_ENV!==`production`&&!a(e))throw console.error(`Invalid node:`,e),Error(`Invalid node at path ${t.slice(0,n).join(`.`)}`);return!0}};const Y=n(null),X=n(null),Z=()=>{let e=s(Y);if(!e)throw Error(`usePulseClient must be used within a PulseProvider`);return e},jt=e=>{let t=s(X);if(!t)throw Error(`usePulsePrerender must be used within a PulseProvider`);let n=t.views[e];if(!n)throw Error(`No prerender found for '${e}'`);return n},Q=typeof window<`u`;function Mt({children:e,config:t,prerender:n}){let[r,i]=d(`ok`),a=p(),{directives:o}=n,s=l(()=>new Ot(t.serverAddress,o,a,t.connectionStatus),[t.serverAddress,a,t.connectionStatus]);c(()=>s.setDirectives(o),[s,o]),c(()=>{if(!Q)return;let e=s.onConnectionChange(e=>{i(e)});return s.connect(),()=>{e(),s.disconnect()}},[s]);let u=(()=>{switch(r){case`connecting`:return`Connecting...`;case`reconnecting`:return`Reconnecting...`;case`error`:return`Failed to connect to the server.`;default:return null}})();return g(Y.Provider,{value:s,children:_(X.Provider,{value:n,children:[u&&g(`div`,{style:{position:`fixed`,bottom:`20px`,right:`20px`,backgroundColor:r===`error`?`red`:`#666`,color:`white`,padding:`10px`,borderRadius:`5px`,zIndex:1e3},children:u}),e]})})}function Nt({path:e,registry:t}){let n=Z(),r=jt(e),i=l(()=>new J(n,e,t),[n,e,t]),[a,o]=d(()=>i.init(r)),[s,p]=d(null),h=f(),_=m(),v=l(()=>{let{"*":e=``,...t}=_,n=new URLSearchParams(h.search);return{hash:h.hash,pathname:h.pathname,query:h.search,queryParams:Object.fromEntries(n.entries()),pathParams:t,catchall:e.length>0?e.split(`/`):[]}},[h.hash,h.pathname,h.search,JSON.stringify(_)]);c(()=>{if(Q)return n.attach(e,{routeInfo:v,onInit:e=>{o(i.init(e)),p(null)},onUpdate:e=>{o(t=>t==null?t:i.applyUpdates(t,e)),p(null)},onJsExec:e=>{let t,r=null;try{t=i.evaluateExpr(e.expr)}catch(e){r=e instanceof Error?e.message:String(e)}n.sendJsResult(e.id,t,r)},onServerError:p}),()=>{n.detach(e)}},[n,i,e]),c(()=>{Q&&n.updateRoute(e,v)},[n,e,v]);let y=u(!1);return c(()=>(y.current?o(i.init(r)):y.current=!0,()=>{y.current=!1}),[r,i]),s?g(Pt,{error:s}):a}function Pt({error:e}){return _(`div`,{style:{padding:16,border:`1px solid #e00`,background:`#fff5f5`,color:`#900`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`,whiteSpace:`pre-wrap`},children:[_(`div`,{style:{fontWeight:700,marginBottom:8},children:[`Server Error during `,e.phase]}),e.message&&g(`div`,{children:e.message}),e.stack&&_(`details`,{open:!0,style:{marginTop:8},children:[g(`summary`,{children:`Stack trace`}),g(`pre`,{style:{margin:0},children:e.stack})]})]})}var $=class extends Error{constructor(e){super(e),this.name=`PulseChannelResetError`}};function Ft(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID().replace(/-/g,``):Math.random().toString(16).slice(2)+Math.random().toString(16).slice(2)}function It(e){if(e instanceof Error)return e.message;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function Lt(e){return typeof e.responseTo==`string`}function Rt(e){return typeof e.event==`string`}var zt=class{handlers=new Map;pending=new Map;backlog=[];closed=!1;constructor(e,t){this.client=e,this.id=t}emit(e,t){this.ensureOpen(),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t})}request(e,t){this.ensureOpen();let n=Ft();return new Promise((r,i)=>{this.pending.set(n,{resolve:r,reject:i}),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t,requestId:n})})}on(e,t){this.ensureOpen();let n=this.handlers.get(e);return n||(n=new Set,this.handlers.set(e,n)),n.add(t),this.flushBacklog(e),()=>{let n=this.handlers.get(e);n&&(n.delete(t),n.size===0&&this.handlers.delete(e))}}handleServerMessage(e){return Lt(e)?(this.resolvePending(e),this.closed):this.closed?!0:Rt(e)?e.event===`__close__`?(this.close(new $(`Channel closed by server`)),!0):(e.requestId?this.dispatchRequest(e):this.dispatchEvent(e),this.closed):this.closed}handleDisconnect(e){this.close(e)}dispose(e){this.close(e)}ensureOpen(){if(this.closed)throw new $(`Channel is closed`)}flushBacklog(e){if(this.backlog.length===0)return;let t=[];for(let n of this.backlog)n.event===e?this.dispatchEvent(n):t.push(n);this.backlog=t}dispatchEvent(e){let t=this.handlers.get(e.event);if(!t||t.size===0){this.backlog.push(e);return}for(let n of t)try{let t=n(e.payload);t&&typeof t.then==`function`&&t.catch(e=>{console.error(`Pulse channel handler error`,e)})}catch(e){console.error(`Pulse channel handler error`,e)}}async dispatchRequest(e){let t=this.handlers.get(e.event),n,r;if(t&&t.size>0)for(let i of t)try{let t=i(e.payload);if(n=await Promise.resolve(t),n!==void 0)break}catch(e){r=e;break}if(r){this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,error:It(r)});return}this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,payload:n})}resolvePending(e){let t=e.responseTo?this.pending.get(e.responseTo):void 0;t&&(this.pending.delete(e.responseTo),e.error!==void 0&&e.error!==null?t.reject(new $(String(e.error))):t.resolve(e.payload))}close(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e);this.pending.clear(),this.handlers.clear(),this.backlog=[]}}};function Bt(e){let t=Z(),n=l(()=>{if(!e)throw Error(`usePulseChannel requires a non-empty channelId`);return t.acquireChannel(e)},[t,e]);return c(()=>()=>{t.releaseChannel(e)},[t,e]),n}const Vt=i(function({onSubmit:e,action:t,...n},r){return g(`form`,{...n,action:t,ref:r,onSubmit:o(n=>Ht({event:n,action:t,onSubmit:e}),[t,e])})});async function Ht({event:e,action:t,onSubmit:n,formData:r,force:i}){if(n?.(e),!i&&e.defaultPrevented)return;let a=e.currentTarget;e.preventDefault();let o=e.nativeEvent;r||=new FormData(a,o.submitter);let s=new URL(t,window.location.href);try{await fetch(s,{method:`POST`,credentials:`include`,body:r})}catch(e){if(process.env.NODE_ENV!==`production`)console.error(`[Pulse] Form submission failed`,e);else throw e}}function Ut({params:e,request:t}){let{"*":n=``,...r}=e,i=new URL(t.url);return{hash:i.hash,pathname:i.pathname,query:i.search,queryParams:Object.fromEntries(i.searchParams.entries()),pathParams:r,catchall:n.length>1?n.split(`/`):[]}}export{$ as PulseChannelResetError,Vt as PulseForm,Mt as PulseProvider,Nt as PulseView,J as VDOMRenderer,G as deserialize,Ut as extractServerRouteInfo,W as serialize,Ht as submitForm,Bt as usePulseChannel,Z as usePulseClient};
2
2
  //# sourceMappingURL=index.js.map