litewire 1.0.3 → 1.0.5

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.
Files changed (2) hide show
  1. package/README.MD +121 -9
  2. package/package.json +1 -1
package/README.MD CHANGED
@@ -1,17 +1,18 @@
1
- # Litewire 1.0.3
1
+ # Litewire 1.0.5
2
2
 
3
3
  Litewire is a small browser-side HTML-over-the-wire library. It binds HTTP
4
4
  requests, reactive state, and event expressions to HTML attributes, swaps
5
5
  server-rendered HTML into the page, and can load ES module components on
6
6
  demand.
7
7
 
8
- Version 1.0.3 adds reactive `lw:class` bindings, iterable lists with
8
+ Version 1.0.5 adds reactive `lw:class` bindings, iterable lists with
9
9
  `template[lw:for]`, and event-triggered component mounting. It also improves
10
10
  radio model initialization and browser-history markup restoration.
11
11
 
12
12
  ## Contents
13
13
 
14
14
  - [Install and start](#install-and-start)
15
+ - [End-to-end example](#end-to-end-example)
15
16
  - [Configuration](#configuration)
16
17
  - [AJAX requests](#ajax-requests)
17
18
  - [Reactive state and bindings](#reactive-state-and-bindings)
@@ -21,6 +22,7 @@ radio model initialization and browser-history markup restoration.
21
22
  - [Browser history](#browser-history)
22
23
  - [Lifecycle events](#lifecycle-events)
23
24
  - [CSRF](#csrf)
25
+ - [Troubleshooting](#troubleshooting)
24
26
  - [Security considerations](#security-considerations)
25
27
  - [API reference](#api-reference)
26
28
 
@@ -40,10 +42,10 @@ continues scanning elements added later.
40
42
 
41
43
  ### Use the npm package
42
44
 
43
- Install version 1.0.3 from your configured npm registry:
45
+ Install version 1.0.5 from your configured npm registry:
44
46
 
45
47
  ```sh
46
- npm install litewire@1.0.3
48
+ npm install litewire@1.0.5
47
49
  ```
48
50
 
49
51
  Import the package from your application's JavaScript entry point:
@@ -72,6 +74,45 @@ and observers.
72
74
  Litewire sends a GET request when the button is clicked and replaces the
73
75
  contents of `#result` with the response HTML.
74
76
 
77
+ ## End-to-end example
78
+
79
+ This example uses an HTML form to submit a search query and swaps the
80
+ server-rendered result into a separate element:
81
+
82
+ ```html
83
+ <form
84
+ lw-get="/search"
85
+ lw-target="#search-results"
86
+ lw-indicator="#search-status"
87
+ >
88
+ <label>
89
+ Search
90
+ <input name="q" type="search" required>
91
+ </label>
92
+ <button type="submit">Search</button>
93
+ <span id="search-status" aria-live="polite">Ready</span>
94
+ </form>
95
+
96
+ <section id="search-results" aria-live="polite">
97
+ Enter a query to see results.
98
+ </section>
99
+ ```
100
+
101
+ The browser sends a request like `GET /search?q=...`. The endpoint should
102
+ return an HTML fragment, for example:
103
+
104
+ ```html
105
+ <h2>Results for “tea”</h2>
106
+ <ul>
107
+ <li>Green tea</li>
108
+ <li>Black tea</li>
109
+ </ul>
110
+ ```
111
+
112
+ Litewire replaces the contents of `#search-results` with that fragment. The
113
+ new content is scanned for Litewire attributes and any `lw-component` modules
114
+ are loaded. No JSON decoding or client-side template rendering is performed.
115
+
75
116
  ## Configuration
76
117
 
77
118
  Litewire resolves its base URL in this order:
@@ -166,6 +207,33 @@ the element is scanned:
166
207
  <div id="account-summary"></div>
167
208
  ```
168
209
 
210
+ ### Request and form behavior
211
+
212
+ - A form listens for `submit` by default. Other elements listen for `click`.
213
+ Set `lw-trigger` to a DOM event name to use another event; `load` runs the
214
+ request immediately when the element is discovered.
215
+ - A GET request serializes all successful controls in the nearest containing
216
+ form as URL query parameters. If there is no containing form, a control with
217
+ a `name` and `value` contributes that one parameter.
218
+ - POST, PUT, and DELETE requests send the nearest containing form as
219
+ `FormData`. If there is no form, Litewire sends no request body.
220
+ - Litewire checks `response.ok`; a non-success status is treated as a request
221
+ failure. Successful response bodies are read as text and inserted as HTML.
222
+ Set the response `Content-Type` appropriately on the server, even though
223
+ Litewire does not parse it.
224
+ - `lw-target` is resolved with `document.querySelector`. If omitted, the
225
+ triggering element is the target. Ensure the selector matches the intended
226
+ element when the response is applied.
227
+ - A trigger and each loading indicator receive the configured loading class
228
+ while the request is in flight. By default, indicators are descendants with
229
+ the `litewire-indicator` class; `lw-indicator` can select indicators
230
+ elsewhere in the document.
231
+ - Request failures are logged to the console and emit `litewire:error` from
232
+ the trigger. The loading class is removed on both success and failure.
233
+
234
+ `lw-trigger="load"` is useful for initial content, but avoid putting it on
235
+ large numbers of elements if they would all issue requests at once.
236
+
169
237
  ## Reactive state and bindings
170
238
 
171
239
  Litewire provides a small reactive layer using `lw:state`, `lw:model`,
@@ -259,11 +327,36 @@ written with the instance methods `litewire.getModel(name)` and
259
327
  `litewire.setModel(name, value)`. Global model changes dispatch a
260
328
  `litewire:model` event on `document`, with `{ name, value }` in `event.detail`.
261
329
 
330
+ For example, a control outside a local state root can populate a global model,
331
+ and a matching text binding can display it:
332
+
333
+ ```html
334
+ <input name="status" lw:model="status" aria-label="Status">
335
+ <p>Current status: <span lw:text="status"></span></p>
336
+
337
+ <script type="module">
338
+ import "litewire";
339
+
340
+ window.addEventListener("DOMContentLoaded", () => {
341
+ window.litewire.setModel("status", "Ready");
342
+ });
343
+ </script>
344
+ ```
345
+
346
+ When setting global models from application code, set them on the initialized
347
+ `window.litewire` instance. `setModel()` updates a `lw:text` binding whose
348
+ expression is exactly that model name, reevaluates global `lw:class` and
349
+ `lw:for` bindings, and dispatches `litewire:model`.
350
+
262
351
  A model name beginning with `#` or `.` is treated as a CSS selector instead of
263
352
  a state key. Litewire copies the control's value to matching elements (to
264
353
  `value` for form controls, otherwise to `textContent`) and dispatches
265
354
  `litewire:model` on each target with `{ value }` in `event.detail`.
266
355
 
356
+ For example, `lw:model="#live-preview"` copies an input value to the
357
+ `textContent` of the element with that ID. Selector-based models update the
358
+ matching targets; they are not reactive state properties.
359
+
267
360
  ### Event expressions
268
361
 
269
362
  Supported event attributes are:
@@ -316,9 +409,9 @@ level so it can observe events outside the element.
316
409
 
317
410
  An element with `lw-component` dynamically imports a JavaScript module. The
318
411
  path is joined to Litewire's base URL. Litewire selects the module's default
319
- export first, then a named `imageUploader` export, then the first export. If
320
- the selected export is a function, it is called with the host element and its
321
- `data-*` attributes converted to an object:
412
+ export first, then its first export. If the selected export is a function, it
413
+ is called with the host element and its `data-*` attributes converted to an
414
+ object:
322
415
 
323
416
  ```html
324
417
  <div
@@ -438,6 +531,19 @@ When this meta tag is present, Litewire adds its token as the
438
531
  The server must still validate the token and enforce its own authorization and
439
532
  request protections.
440
533
 
534
+ ## Troubleshooting
535
+
536
+ | Symptom | Things to check |
537
+ |---|---|
538
+ | The global `window.litewire` is missing | Load Litewire in a browser as a module and check the console for module loading errors. Auto-initialization occurs after the document is ready. |
539
+ | A request does not run | Confirm the element has one of `lw-get`, `lw-post`, `lw-put`, or `lw-delete`. Check its default or configured `lw-trigger` event and whether another handler prevents the event from reaching it. |
540
+ | The server receives no form values | Make sure the trigger is inside the form, or is the form itself. Non-GET requests without a containing form have no body. For GET, a standalone control needs both `name` and `value`. |
541
+ | The request succeeds but the page does not change | Return an HTML fragment, verify `lw-target` matches an element, and check that the selected `lw-swap` behavior is suitable. |
542
+ | A request reports an error | Inspect the browser console and the `litewire:error` event. Litewire treats HTTP statuses outside the 2xx range as failures. |
543
+ | A state binding stays unchanged | Confirm the binding is under the intended `lw:state` root. Replace a top-level state property; nested mutations are not observed. |
544
+ | A component does not mount | Check the module URL, its default or first export, and that the export is a function. For deferred components, verify the triggering event and optional `lw-target` selector. |
545
+ | A directive in newly inserted HTML does not run | Ensure the HTML is inserted through a Litewire swap or added to the observed document body. The observer watches additions under `document.body`. |
546
+
441
547
  ## Security considerations
442
548
 
443
549
  Litewire inserts response bodies as HTML. Only return trusted or appropriately
@@ -453,11 +559,11 @@ untrusted user input.
453
559
  |---|---|
454
560
  | `lw-get`, `lw-post`, `lw-put`, `lw-delete` | Request path and HTTP method |
455
561
  | `lw-trigger` | Request event (defaults to `click` or form `submit`; `load` runs on scan); for components, event to defer mounting |
456
- | `lw-target` | CSS selector for the response target |
562
+ | `lw-target` | CSS selector for the response target; for a triggered component, selects the element passed to the component |
457
563
  | `lw-swap` | `innerHTML`, `outerHTML`, `prepend`, or `append` |
458
564
  | `lw-indicator` | CSS selector for loading indicators |
459
565
  | `lw-push-url` | `true`, `false`, or a custom history URL |
460
- | `lw-component` | Path to a dynamically imported ES module |
566
+ | `lw-component` | Path to a dynamically imported ES module; its default export or first export is mounted |
461
567
  | `lw:state` | JavaScript object expression that initializes local reactive state |
462
568
  | `lw:model`, `.live`, `.change`, `.blur` | Bind a form control to a state or global model |
463
569
  | `lw:text` | Render an expression as text |
@@ -467,5 +573,11 @@ untrusted user input.
467
573
  | `lw:click`, `lw:input`, `lw:change`, `lw:submit`, `lw:keydown`, `lw:keyup`, `lw:focus`, `lw:blur` | Evaluate an expression in response to an event; supports the modifiers documented above |
468
574
  | `litewire.getModel(name)` | Read a global model |
469
575
  | `litewire.setModel(name, value)` | Set a global model and update matching bindings |
576
+ | `new Litewire({ baseUrl, loadingClass })` | Construct and initialize an instance with optional configuration |
577
+
578
+ The browser module exports the `Litewire` class as its default export and
579
+ auto-creates `window.litewire` if that global is not already set. When creating
580
+ a custom instance, set `window.litewire` to a placeholder before importing the
581
+ module if needed to prevent auto-initialization, then assign the instance.
470
582
 
471
583
  **Buy my kids schoolbooks:** [https://paypal.me/justumg](https://paypal.me/justumg)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litewire",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "A lightweight HTML-driven request engine with reactive state and dynamic ES module components.",
5
5
  "main": "./litewire.js",
6
6
  "module": "./litewire.js",