phoenix_live_view 1.2.0-rc.2 → 1.2.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.
Files changed (27) hide show
  1. package/README.md +5 -5
  2. package/assets/js/phoenix_live_view/README.md +3 -0
  3. package/assets/js/phoenix_live_view/{aria.js → aria.ts} +18 -10
  4. package/assets/js/phoenix_live_view/{browser.js → browser.ts} +12 -8
  5. package/assets/js/phoenix_live_view/{dom.js → dom.ts} +107 -34
  6. package/assets/js/phoenix_live_view/{dom_patch.js → dom_patch.ts} +187 -124
  7. package/assets/js/phoenix_live_view/{dom_post_morph_restorer.js → dom_post_morph_restorer.ts} +17 -2
  8. package/assets/js/phoenix_live_view/{element_ref.js → element_ref.ts} +17 -11
  9. package/assets/js/phoenix_live_view/entry_uploader.js +4 -4
  10. package/assets/js/phoenix_live_view/{hooks.js → hooks.ts} +108 -91
  11. package/assets/js/phoenix_live_view/index.ts +14 -301
  12. package/assets/js/phoenix_live_view/js.js +2 -1
  13. package/assets/js/phoenix_live_view/js_commands.ts +12 -9
  14. package/assets/js/phoenix_live_view/{live_socket.js → live_socket.ts} +582 -114
  15. package/assets/js/phoenix_live_view/live_uploader.js +1 -1
  16. package/assets/js/phoenix_live_view/rendered.js +3 -0
  17. package/assets/js/phoenix_live_view/{utils.js → utils.ts} +35 -6
  18. package/assets/js/phoenix_live_view/{view.js → view.ts} +221 -110
  19. package/assets/js/phoenix_live_view/view_hook.ts +92 -32
  20. package/package.json +5 -2
  21. package/priv/static/phoenix_live_view.cjs.js +577 -314
  22. package/priv/static/phoenix_live_view.cjs.js.map +4 -4
  23. package/priv/static/phoenix_live_view.esm.js +577 -314
  24. package/priv/static/phoenix_live_view.esm.js.map +4 -4
  25. package/priv/static/phoenix_live_view.js +584 -314
  26. package/priv/static/phoenix_live_view.min.js +7 -7
  27. /package/assets/js/phoenix_live_view/{constants.js → constants.ts} +0 -0
@@ -12,6 +12,11 @@ export type CallbackRef = { event: string; callback: (payload: any) => any };
12
12
 
13
13
  export type PhxTarget = string | number | HTMLElement;
14
14
 
15
+ /**
16
+ * Defines the lifecycle callbacks and custom methods for a LiveView hook.
17
+ *
18
+ * @category JavaScript Hooks
19
+ */
15
20
  export interface HookInterface<E extends HTMLElement = HTMLElement> {
16
21
  /**
17
22
  * The DOM element that the hook is attached to.
@@ -41,14 +46,14 @@ export interface HookInterface<E extends HTMLElement = HTMLElement> {
41
46
  /**
42
47
  * The updated callback.
43
48
  *
44
- * Called when the element has been updated in the DOM by the server
49
+ * Called when the element has been updated in the DOM by the server.
45
50
  */
46
51
  updated?: () => void;
47
52
 
48
53
  /**
49
54
  * The destroyed callback.
50
55
  *
51
- * Called when the element has been removed from the page, either by a parent update, or by the parent being removed entirely
56
+ * Called when the element has been removed from the page, either by a parent update, or by the parent being removed entirely.
52
57
  */
53
58
  destroyed?: () => void;
54
59
 
@@ -73,49 +78,85 @@ export interface HookInterface<E extends HTMLElement = HTMLElement> {
73
78
  js(): HookJSCommands;
74
79
 
75
80
  /**
76
- * Pushes an event to the server.
81
+ * Pushes an event to the server and invokes a callback with the server's reply.
82
+ *
83
+ * **Note:** this version silently ignores push errors.
84
+ * Use the {@link pushEvent | promise-returning version} to handle errors.
77
85
  *
78
86
  * @param event - The event name.
79
- * @param [payload] - The payload to send to the server. Defaults to an empty object.
80
- * @param [onReply] - A callback to handle the server's reply.
87
+ * @param payload - The payload to send to the server. Must be a serializable
88
+ * value (typically JSON-serializable, depends on the Socket configuration).
89
+ * Defaults to an empty object.
90
+ * @param onReply - A callback to handle the server's reply.
91
+ */
92
+ pushEvent(event: string, payload: unknown, onReply: OnReply): void;
93
+ /**
94
+ * Pushes an event to the server and returns a Promise that resolves with the server's reply.
95
+ *
96
+ * The promise will be rejected in case of errors
97
+ * such as a disconnected state, timeout, or the server rejecting the event.
81
98
  *
82
- * When onReply is not provided, the method returns a Promise that
83
- * When onReply is provided, the method returns void.
99
+ * @param event - The event name.
100
+ * @param [payload] - The payload to send to the server. Must be a serializable
101
+ * value (typically JSON-serializable, depends on the Socket configuration).
102
+ * Defaults to an empty object.
103
+ * @returns A promise that fulfills or rejects with the server's reply.
84
104
  */
85
- pushEvent(event: string, payload: any, onReply: OnReply): void;
86
- pushEvent(event: string, payload?: any): Promise<any>;
105
+ pushEvent(event: string, payload?: unknown): Promise<any>;
87
106
 
88
107
  /**
89
- * Pushed a targeted event to the server.
108
+ * Pushes a targeted event to the server and invokes a callback with the server's reply.
90
109
  *
91
110
  * It sends the event to the LiveComponent or LiveView the `selectorOrTarget` is defined in,
92
111
  * where its value can be either a query selector, an actual DOM element, or a CID (component id)
93
112
  * returned by the `@myself` assign.
94
113
  *
95
- * If the query selector returns more than one element it will send the event to all of them,
96
- * even if all the elements are in the same LiveComponent or LiveView. Because of this,
97
- * if no callback is passed, a promise is returned that matches the return value of
98
- * [`Promise.allSettled()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled#return_value).
99
- * Individual fulfilled values are of the format `{ reply, ref }`, where `reply` is the server's reply.
114
+ * If the selector matches multiple elements, the event is sent to all of them,
115
+ * even if they belong to the same LiveComponent or LiveView.
116
+ *
117
+ * **Note:** this version silently ignores push errors.
118
+ * Use the {@link pushEventTo | promise-returning version} to handle errors.
100
119
  *
101
120
  * @param selectorOrTarget - The selector, element, or CID to target.
102
121
  * @param event - The event name.
103
- * @param [payload] - The payload to send to the server. Defaults to an empty object.
104
- * @param [onReply] - A callback to handle the server's reply.
105
- *
106
- * When onReply is not provided, the method returns a Promise.
107
- * When onReply is provided, the method returns void.
122
+ * @param payload - The payload to send to the server. Must be a serializable
123
+ * value (typically JSON-serializable, depends on the Socket configuration).
124
+ * Defaults to an empty object.
125
+ * @param onReply - A callback to handle the server's reply.
108
126
  */
109
127
  pushEventTo(
110
128
  selectorOrTarget: PhxTarget,
111
129
  event: string,
112
- payload: object,
130
+ payload: unknown,
113
131
  onReply: OnReply,
114
132
  ): void;
133
+ /**
134
+ * Pushes a targeted event to the server and returns a Promise that resolves with the server's reply.
135
+ *
136
+ * It sends the event to the LiveComponent or LiveView the `selectorOrTarget` is defined in,
137
+ * where its value can be either a query selector, an actual DOM element, or a CID (component id)
138
+ * returned by the `@myself` assign.
139
+ *
140
+ * If the selector matches multiple elements, the event is sent to all of them,
141
+ * even if they belong to the same LiveComponent or LiveView.
142
+ * Because of this, it returns a single promise that matches the return value of
143
+ * [`Promise.allSettled()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled#return_value).
144
+ * Individual fulfilled values are of the format `{ reply, ref }`, where `reply` is the server's reply.
145
+ *
146
+ * The individual promises will be rejected in case of errors
147
+ * such as a disconnected state, timeout, or the server rejecting the event.
148
+ *
149
+ * @param selectorOrTarget - The selector, element, or CID to target.
150
+ * @param event - The event name.
151
+ * @param [payload] - The payload to send to the server. Must be a serializable
152
+ * value (typically JSON-serializable, depends on the Socket configuration).
153
+ * Defaults to an empty object.
154
+ * @returns A promise that resolves when the event has been handled by all targets.
155
+ */
115
156
  pushEventTo(
116
157
  selectorOrTarget: PhxTarget,
117
158
  event: string,
118
- payload?: object,
159
+ payload?: unknown,
119
160
  ): Promise<PromiseSettledResult<{ reply: any; ref: number }>[]>;
120
161
 
121
162
  /**
@@ -133,7 +174,7 @@ export interface HookInterface<E extends HTMLElement = HTMLElement> {
133
174
  /**
134
175
  * Removes a callback registered with `handleEvent`.
135
176
  *
136
- * @param callbackRef - The reference to the callback to remove.
177
+ * @param ref - The reference to the callback to remove.
137
178
  */
138
179
  removeHandleEvent(ref: CallbackRef): void;
139
180
 
@@ -160,6 +201,11 @@ export interface HookInterface<E extends HTMLElement = HTMLElement> {
160
201
 
161
202
  // based on https://github.com/DefinitelyTyped/DefinitelyTyped/blob/fac1aa75acdddbf4f1a95e98ee2297b54ce4b4c9/types/phoenix_live_view/hooks.d.ts#L26
162
203
  // licensed under MIT
204
+ /**
205
+ * Defines the lifecycle callbacks and custom methods for a LiveView hook.
206
+ *
207
+ * @category JavaScript Hooks
208
+ */
163
209
  export interface Hook<T = object, E extends HTMLElement = HTMLElement> {
164
210
  /**
165
211
  * The mounted callback.
@@ -179,14 +225,14 @@ export interface Hook<T = object, E extends HTMLElement = HTMLElement> {
179
225
  /**
180
226
  * The updated callback.
181
227
  *
182
- * Called when the element has been updated in the DOM by the server
228
+ * Called when the element has been updated in the DOM by the server.
183
229
  */
184
230
  updated?: (this: T & HookInterface<E>) => void;
185
231
 
186
232
  /**
187
233
  * The destroyed callback.
188
234
  *
189
- * Called when the element has been removed from the page, either by a parent update, or by the parent being removed entirely
235
+ * Called when the element has been removed from the page, either by a parent update, or by the parent being removed entirely.
190
236
  */
191
237
  destroyed?: (this: T & HookInterface<E>) => void;
192
238
 
@@ -236,6 +282,8 @@ export interface Hook<T = object, E extends HTMLElement = HTMLElement> {
236
282
  * The `this` context within the hook methods (mounted, updated, custom methods, etc.)
237
283
  * will refer to the hook instance, providing access to `this.el`, `this.liveSocket`,
238
284
  * `this.pushEvent()`, etc., as well as any properties or methods defined on the subclass.
285
+ *
286
+ * @category JavaScript Hooks
239
287
  */
240
288
  export class ViewHook<E extends HTMLElement = HTMLElement>
241
289
  implements HookInterface<E>
@@ -251,16 +299,20 @@ export class ViewHook<E extends HTMLElement = HTMLElement>
251
299
  return this.__liveSocket();
252
300
  }
253
301
 
302
+ /** @internal */
254
303
  static makeID() {
255
304
  return viewHookID++;
256
305
  }
306
+ /** @internal */
257
307
  static elementID(el: HTMLElement) {
258
308
  return DOM.private(el, HOOK_ID);
259
309
  }
310
+ /** @internal */
260
311
  static deadHook(el: HTMLElement) {
261
312
  return DOM.private(el, DEAD_HOOK) === true;
262
313
  }
263
314
 
315
+ /** @internal */
264
316
  constructor(view: View | null, el: E, callbacks?: Hook) {
265
317
  this.el = el;
266
318
  this.__attachView(view);
@@ -401,11 +453,11 @@ export class ViewHook<E extends HTMLElement = HTMLElement>
401
453
  };
402
454
  }
403
455
 
404
- pushEvent(event: string, payload: any, onReply: OnReply): void;
405
- pushEvent(event: string, payload?: any): Promise<any>;
456
+ pushEvent(event: string, payload: unknown, onReply: OnReply): void;
457
+ pushEvent(event: string, payload?: unknown): Promise<any>;
406
458
  pushEvent(
407
459
  event: string,
408
- payload?: any,
460
+ payload?: unknown,
409
461
  onReply?: OnReply,
410
462
  ): Promise<any> | void {
411
463
  const promise = this.__view().pushHookEvent(
@@ -427,18 +479,18 @@ export class ViewHook<E extends HTMLElement = HTMLElement>
427
479
  pushEventTo(
428
480
  selectorOrTarget: PhxTarget,
429
481
  event: string,
430
- payload: object,
482
+ payload: unknown,
431
483
  onReply: OnReply,
432
484
  ): void;
433
485
  pushEventTo(
434
486
  selectorOrTarget: PhxTarget,
435
487
  event: string,
436
- payload?: object,
488
+ payload?: unknown,
437
489
  ): Promise<PromiseSettledResult<{ reply: any; ref: number }>[]>;
438
490
  pushEventTo(
439
491
  selectorOrTarget: PhxTarget,
440
492
  event: string,
441
- payload?: object,
493
+ payload?: unknown,
442
494
  onReply?: OnReply,
443
495
  ): Promise<PromiseSettledResult<{ reply: any; ref: number }>[]> | void {
444
496
  if (onReply === undefined) {
@@ -450,7 +502,12 @@ export class ViewHook<E extends HTMLElement = HTMLElement>
450
502
  },
451
503
  );
452
504
  const promises = targetPair.map(({ view, targetCtx }) => {
453
- return view.pushHookEvent(this.el, targetCtx, event, payload || {});
505
+ return view.pushHookEvent(
506
+ this.el,
507
+ targetCtx,
508
+ event,
509
+ payload || {},
510
+ ) as Promise<{ reply: any; ref: number }>;
454
511
  });
455
512
  return Promise.allSettled(promises);
456
513
  }
@@ -509,6 +566,9 @@ export class ViewHook<E extends HTMLElement = HTMLElement>
509
566
  }
510
567
  }
511
568
 
569
+ /**
570
+ * @category JavaScript Hooks
571
+ */
512
572
  export type HooksOptions = Record<string, typeof ViewHook | Hook<any, any>>;
513
573
 
514
574
  export default ViewHook;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phoenix_live_view",
3
- "version": "1.2.0-rc.2",
3
+ "version": "1.2.0",
4
4
  "description": "The Phoenix LiveView JavaScript client.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -52,6 +52,8 @@
52
52
  "phoenix": "1.7.21",
53
53
  "prettier": "3.5.3",
54
54
  "ts-jest": "^29.4.0",
55
+ "typedoc": "^0.28.19",
56
+ "typedoc-plugin-missing-exports": "^4.1.3",
55
57
  "typescript": "^5.8.3",
56
58
  "typescript-eslint": "^8.34.0"
57
59
  },
@@ -70,6 +72,7 @@
70
72
  "typecheck:tests": "tsc -p assets/test/tsconfig.json",
71
73
  "cover:merge": "node test/e2e/merge-coverage.js",
72
74
  "cover": "npm run test && npm run cover:merge",
73
- "cover:report": "npx monocart show-report cover/merged-js/index.html"
75
+ "cover:report": "npx monocart show-report cover/merged-js/index.html",
76
+ "docs": "typedoc assets/js/phoenix_live_view/index.ts --readme assets/js/phoenix_live_view/README.md --html doc/js"
74
77
  }
75
78
  }