xhtmlx 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/xhtmlx.d.ts ADDED
@@ -0,0 +1,351 @@
1
+ /**
2
+ * TypeScript definitions for xhtmlx
3
+ *
4
+ * Declarative HTML attributes for REST API driven UIs.
5
+ * Like htmx, but the server returns JSON and xhtmlx renders UI client-side
6
+ * using templates.
7
+ */
8
+
9
+ export = xhtmlx;
10
+ export as namespace xhtmlx;
11
+
12
+ declare const xhtmlx: xhtmlx.Xhtmlx;
13
+
14
+ declare namespace xhtmlx {
15
+
16
+ // -------------------------------------------------------------------------
17
+ // Configuration
18
+ // -------------------------------------------------------------------------
19
+
20
+ interface XhtmlxConfig {
21
+ /** Enable debug logging to the console. */
22
+ debug: boolean;
23
+ /** Default swap mode for rendered content (e.g. "innerHTML"). */
24
+ defaultSwapMode: string;
25
+ /** CSS class added to indicator elements while a request is in-flight. */
26
+ indicatorClass: string;
27
+ /** CSS class added to elements that have a request in-flight. */
28
+ requestClass: string;
29
+ /** CSS class added to elements that received an error response. */
30
+ errorClass: string;
31
+ /** Arrays above this size use requestAnimationFrame batching in xh-each. */
32
+ batchThreshold: number;
33
+ /** Global fallback error template URL. */
34
+ defaultErrorTemplate: string | null;
35
+ /** Global fallback error target CSS selector. */
36
+ defaultErrorTarget: string | null;
37
+ /** Prefix prepended to all xh-template URLs (for UI versioning). */
38
+ templatePrefix: string;
39
+ /** Prefix prepended to all REST verb URLs. */
40
+ apiPrefix: string;
41
+ /** Current UI version identifier (any string). */
42
+ uiVersion: string | null;
43
+ }
44
+
45
+ // -------------------------------------------------------------------------
46
+ // DataContext
47
+ // -------------------------------------------------------------------------
48
+
49
+ class DataContext {
50
+ /** The JSON payload for this context level. */
51
+ data: any;
52
+ /** Enclosing parent context, or null at root. */
53
+ parent: DataContext | null;
54
+ /** Current iteration index for xh-each, or null. */
55
+ index: number | null;
56
+
57
+ /**
58
+ * @param data The JSON payload for this level.
59
+ * @param parent Enclosing context (null at root).
60
+ * @param index Current iteration index for xh-each.
61
+ */
62
+ constructor(data?: any, parent?: DataContext | null, index?: number | null);
63
+
64
+ /**
65
+ * Resolve a dotted path against this context.
66
+ *
67
+ * Special variables:
68
+ * $index - iteration index
69
+ * $parent - jump to parent context, continue resolving remainder
70
+ * $root - jump to root context, continue resolving remainder
71
+ *
72
+ * Supports transform pipes: "price | currency"
73
+ *
74
+ * If the key is not found locally, walks up the parent chain.
75
+ *
76
+ * @param path e.g. "user.name", "$parent.title", "$index"
77
+ * @returns resolved value or undefined
78
+ */
79
+ resolve(path: string): any;
80
+ }
81
+
82
+ // -------------------------------------------------------------------------
83
+ // MutableDataContext
84
+ // -------------------------------------------------------------------------
85
+
86
+ class MutableDataContext extends DataContext {
87
+ /**
88
+ * @param data The JSON payload for this level.
89
+ * @param parent Enclosing context (null at root).
90
+ * @param index Current iteration index for xh-each.
91
+ */
92
+ constructor(data?: any, parent?: DataContext | null, index?: number | null);
93
+
94
+ /**
95
+ * Set a value at the given dotted path, creating intermediate objects as
96
+ * needed. Notifies all subscribers for the given path.
97
+ *
98
+ * @param path e.g. "user.name"
99
+ * @param value The new value.
100
+ */
101
+ set(path: string, value: any): void;
102
+
103
+ /**
104
+ * Subscribe to changes on a given path.
105
+ *
106
+ * @param path The dotted path to watch.
107
+ * @param callback Called when the value at path changes.
108
+ */
109
+ subscribe(path: string, callback: () => void): void;
110
+ }
111
+
112
+ // -------------------------------------------------------------------------
113
+ // SwitchVersionOptions
114
+ // -------------------------------------------------------------------------
115
+
116
+ interface SwitchVersionOptions {
117
+ /** Template prefix. Defaults to "/ui/{version}". */
118
+ templatePrefix?: string;
119
+ /** API prefix. Defaults to "" (unchanged). */
120
+ apiPrefix?: string;
121
+ /** Re-render all active widgets. Defaults to true. */
122
+ reload?: boolean;
123
+ }
124
+
125
+ // -------------------------------------------------------------------------
126
+ // Custom event detail types
127
+ // -------------------------------------------------------------------------
128
+
129
+ interface XhBeforeRequestDetail {
130
+ url: string;
131
+ method: string;
132
+ headers: Record<string, string>;
133
+ }
134
+
135
+ interface XhAfterRequestDetail {
136
+ url: string;
137
+ status: number;
138
+ }
139
+
140
+ interface XhBeforeSwapDetail {
141
+ target: Element;
142
+ fragment: DocumentFragment;
143
+ swapMode: string;
144
+ isError?: boolean;
145
+ }
146
+
147
+ interface XhAfterSwapDetail {
148
+ target: Element;
149
+ isError?: boolean;
150
+ }
151
+
152
+ interface XhResponseErrorDetail {
153
+ status: number;
154
+ statusText: string;
155
+ body: any;
156
+ }
157
+
158
+ interface XhRetryDetail {
159
+ attempt: number;
160
+ maxRetries: number;
161
+ status?: number;
162
+ error?: string;
163
+ }
164
+
165
+ interface XhVersionChangedDetail {
166
+ version: string;
167
+ templatePrefix: string;
168
+ apiPrefix: string;
169
+ }
170
+
171
+ interface XhWsOpenDetail {
172
+ url: string;
173
+ }
174
+
175
+ interface XhWsCloseDetail {
176
+ code: number;
177
+ reason: string;
178
+ }
179
+
180
+ interface XhWsErrorDetail {
181
+ url: string;
182
+ }
183
+
184
+ // -------------------------------------------------------------------------
185
+ // Main xhtmlx API
186
+ // -------------------------------------------------------------------------
187
+
188
+ interface Xhtmlx {
189
+ /** Library configuration. */
190
+ config: XhtmlxConfig;
191
+
192
+ /**
193
+ * Manually process a DOM node and its descendants.
194
+ * @param root Element to process (defaults to document.body).
195
+ * @param ctx Optional data context.
196
+ */
197
+ process(root?: Element, ctx?: DataContext): void;
198
+
199
+ /**
200
+ * Create a DataContext for programmatic use.
201
+ * @param data The data payload.
202
+ * @param parent Parent context.
203
+ * @param index Iteration index.
204
+ */
205
+ createContext(data: any, parent?: DataContext, index?: number): DataContext;
206
+
207
+ /** Clear the template cache. */
208
+ clearTemplateCache(): void;
209
+
210
+ /** Clear the response cache. */
211
+ clearResponseCache(): void;
212
+
213
+ /**
214
+ * Interpolate a string using a data context.
215
+ * Replaces all {{field}} tokens.
216
+ *
217
+ * @param str Source string with {{field}} tokens.
218
+ * @param ctx Data context for resolution.
219
+ * @param uriEncode If true, URI-encode each substituted value.
220
+ */
221
+ interpolate(str: string, ctx: DataContext, uriEncode?: boolean): string;
222
+
223
+ /**
224
+ * Register a custom directive processed during binding application.
225
+ *
226
+ * @param name Directive name (the xh-* attribute name without the "xh-" prefix).
227
+ * @param handler Called for each element with the directive.
228
+ */
229
+ directive(
230
+ name: string,
231
+ handler: (el: Element, value: string, ctx: DataContext) => void
232
+ ): void;
233
+
234
+ /**
235
+ * Register a global hook.
236
+ * Return false from the handler to cancel the event (where applicable).
237
+ *
238
+ * @param event Hook event name (e.g. "beforeRequest").
239
+ * @param handler Hook handler. Return false to cancel.
240
+ */
241
+ hook(event: string, handler: (detail: any) => boolean | void): void;
242
+
243
+ /**
244
+ * Register a named transform for pipe syntax in bindings.
245
+ * Usage in templates: {{price | currency}}
246
+ *
247
+ * @param name Transform name.
248
+ * @param fn Transform function.
249
+ */
250
+ transform(name: string, fn: (value: any) => any): void;
251
+
252
+ /**
253
+ * Switch UI version. Sets template and API prefixes, clears all caches.
254
+ * Version can be any string: "v2", "abc123", "20260315", a git SHA, etc.
255
+ *
256
+ * @param version Version identifier.
257
+ * @param opts Options for prefix overrides and reload control.
258
+ */
259
+ switchVersion(version: string, opts?: SwitchVersionOptions): void;
260
+
261
+ /**
262
+ * Re-render all active widgets, or only those using a specific template.
263
+ * Re-fetches data from API and re-renders with (possibly new) templates.
264
+ *
265
+ * @param templateUrl If provided, only reload widgets using this template.
266
+ */
267
+ reload(templateUrl?: string): void;
268
+
269
+ /** Library version string. */
270
+ version: string;
271
+
272
+ /** Internals exposed for testing (not part of the public API). */
273
+ _internals: {
274
+ DataContext: typeof DataContext;
275
+ MutableDataContext: typeof MutableDataContext;
276
+ interpolate: (str: string, ctx: DataContext, uriEnc: boolean) => string;
277
+ parseTrigger: Function;
278
+ parseTimeValue: Function;
279
+ renderTemplate: Function;
280
+ applyBindings: (el: Element, ctx: DataContext) => boolean;
281
+ processEach: Function;
282
+ processBindingsInTree: Function;
283
+ processElement: Function;
284
+ attachOnHandler: Function;
285
+ executeRequest: Function;
286
+ resolveErrorTemplate: Function;
287
+ findErrorBoundary: Function;
288
+ getRestVerb: (el: Element) => { verb: string; url: string } | null;
289
+ performSwap: Function;
290
+ buildRequestBody: Function;
291
+ fetchTemplate: (url: string) => Promise<string>;
292
+ resolveTemplate: Function;
293
+ getSwapTarget: Function;
294
+ defaultTrigger: Function;
295
+ resolveDot: (obj: any, parts: string[]) => any;
296
+ templateCache: Map<string, Promise<string>>;
297
+ responseCache: Map<string, { data: string; timestamp: number }>;
298
+ elementStates: WeakMap<Element, any>;
299
+ generationMap: WeakMap<Element, number>;
300
+ fetchWithRetry: Function;
301
+ applySettleClasses: Function;
302
+ setupWebSocket: Function;
303
+ setupWsSend: Function;
304
+ boostElement: Function;
305
+ boostLink: Function;
306
+ boostForm: Function;
307
+ customDirectives: Array<{ name: string; handler: Function }>;
308
+ globalHooks: Record<string, Function[]>;
309
+ transforms: Record<string, (value: any) => any>;
310
+ runHooks: (event: string, detail: any) => boolean;
311
+ registerDirective: (
312
+ name: string,
313
+ handler: (el: Element, value: string, ctx: DataContext) => void
314
+ ) => void;
315
+ registerHook: (
316
+ event: string,
317
+ handler: (detail: any) => boolean | void
318
+ ) => void;
319
+ registerTransform: (name: string, fn: (value: any) => any) => void;
320
+ config: XhtmlxConfig;
321
+ };
322
+ }
323
+ }
324
+
325
+ // ---------------------------------------------------------------------------
326
+ // Global declarations (browser -- window.xhtmlx and custom events)
327
+ // ---------------------------------------------------------------------------
328
+
329
+ declare global {
330
+ interface Window {
331
+ xhtmlx: xhtmlx.Xhtmlx;
332
+ }
333
+
334
+ /**
335
+ * Custom event map for xhtmlx events.
336
+ * Use with addEventListener on DOM elements:
337
+ * el.addEventListener("xh:beforeRequest", (e) => { ... })
338
+ */
339
+ interface HTMLElementEventMap {
340
+ "xh:beforeRequest": CustomEvent<xhtmlx.XhBeforeRequestDetail>;
341
+ "xh:afterRequest": CustomEvent<xhtmlx.XhAfterRequestDetail>;
342
+ "xh:beforeSwap": CustomEvent<xhtmlx.XhBeforeSwapDetail>;
343
+ "xh:afterSwap": CustomEvent<xhtmlx.XhAfterSwapDetail>;
344
+ "xh:responseError": CustomEvent<xhtmlx.XhResponseErrorDetail>;
345
+ "xh:retry": CustomEvent<xhtmlx.XhRetryDetail>;
346
+ "xh:versionChanged": CustomEvent<xhtmlx.XhVersionChangedDetail>;
347
+ "xh:wsOpen": CustomEvent<xhtmlx.XhWsOpenDetail>;
348
+ "xh:wsClose": CustomEvent<xhtmlx.XhWsCloseDetail>;
349
+ "xh:wsError": CustomEvent<xhtmlx.XhWsErrorDetail>;
350
+ }
351
+ }