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/LICENSE +21 -0
- package/README.md +384 -0
- package/package.json +62 -0
- package/xhtmlx.d.ts +351 -0
- package/xhtmlx.js +2825 -0
- package/xhtmlx.min.js +2 -0
- package/xhtmlx.min.js.map +1 -0
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
|
+
}
|