@orieljs/live 0.1.0-alpha.4 → 0.1.0-alpha.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.
- package/README.md +45 -1
- package/dist/index.d.ts +66 -10
- package/dist/index.js +249 -50
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -33,7 +33,51 @@ Route.get('/counter', Counter)
|
|
|
33
33
|
|
|
34
34
|
Embed a component in any view with `<Live component={Counter} />`. In the browser, components are driven by `@orieljs/live-client`.
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
## Pagination
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { Component, Pagination, WithPagination } from '@orieljs/framework'
|
|
40
|
+
import { Post } from '../Models/Post'
|
|
41
|
+
|
|
42
|
+
export default class Posts extends WithPagination(Component) {
|
|
43
|
+
search = ''
|
|
44
|
+
|
|
45
|
+
updatedSearch() {
|
|
46
|
+
this.resetPage()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async render() {
|
|
50
|
+
const posts = await Post.whereLike('title', `%${this.search}%`).latest().paginate(10)
|
|
51
|
+
return (
|
|
52
|
+
<div>
|
|
53
|
+
<input o:model-live="search" aria-label="Search" />
|
|
54
|
+
{posts.items().map((post) => <p>{post.title}</p>)}
|
|
55
|
+
<Pagination paginator={posts} class="flex gap-2" />
|
|
56
|
+
</div>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`paginate()` in the component (in `render()`, in `mount()`, in actions and the update hooks, or in a `@Computed`
|
|
63
|
+
getter any of them reads) shows the component's `page`, and its links are built on the page's URL. The actions
|
|
64
|
+
`nextPage`, `previousPage`, `gotoPage(n)`, `setPage(n)` and `resetPage` move it; `<Pagination>` renders them as
|
|
65
|
+
buttons with the kits' `btn` classes. The page starts at 1 and isn't kept in the address bar.
|
|
66
|
+
|
|
67
|
+
## Middleware on updates
|
|
68
|
+
|
|
69
|
+
Each update re-runs the `auth`, `verified`, `guest` and `can` middleware of the route that rendered the page
|
|
70
|
+
(Livewire's persistent middleware), with that route's parameters bound again, so `can:update,post` sees the post. A
|
|
71
|
+
signed-out tab gets a 401 and a user who lost the ability a 403, before the component's actions run. On a page behind
|
|
72
|
+
one of these middleware, a model deleted since the page rendered gets a 404 too; a page with none binds nothing on
|
|
73
|
+
updates. The list is `live.persistent_middleware` in `config/live.ts`.
|
|
74
|
+
|
|
75
|
+
## Flash data in updates
|
|
76
|
+
|
|
77
|
+
A status an action flashes (`session().flash('status', 'Saved.')`) shows in that update's response only, unless the
|
|
78
|
+
action redirects or navigates: then it is there on the next page. Component state is unaffected.
|
|
79
|
+
|
|
80
|
+
## Known limitations
|
|
37
81
|
|
|
38
82
|
- `o:navigate` does not run scripts in the new page.
|
|
39
83
|
- A DOM event whose name contains `-` can't be written as `o:<event>` in TSX, because modifiers are `-` segments (for example `o:model-live`).
|
package/dist/index.d.ts
CHANGED
|
@@ -189,9 +189,11 @@ declare class LiveComponentManager implements LiveManager {
|
|
|
189
189
|
update(request: LiveUpdateRequest): Promise<LiveUpdateResponse>;
|
|
190
190
|
updateComponent(snapshotJson: string, updates: Record<string, unknown>, calls: Call[]): Promise<ComponentResult>;
|
|
191
191
|
/**
|
|
192
|
-
* The route action of POST /oriel/live/update. Each component's update runs behind the
|
|
193
|
-
* that rendered its page (Livewire's
|
|
194
|
-
*
|
|
192
|
+
* The route action of POST /oriel/live/update. Each component's update runs behind the persistent middleware of the
|
|
193
|
+
* route that rendered its page (Livewire's): `auth`, `verified`, `guest` and `can`, with the page route's parameters
|
|
194
|
+
* bound again. A signed-out tab gets a 401, a revoked ability a 403 and a deleted model a 404, before the component
|
|
195
|
+
* hydrates. When a middleware answers instead (a redirect), that is the response. A key first flashed during the
|
|
196
|
+
* update shows in this response only, unless the update redirects.
|
|
195
197
|
*/
|
|
196
198
|
handle(request: HttpRequest): Promise<LiveUpdateResponse | Response>;
|
|
197
199
|
/** A full-page component (Route.get('/counter', Counter)): mounted with the route parameters, inside the layout. */
|
|
@@ -206,8 +208,14 @@ declare class LiveComponentManager implements LiveManager {
|
|
|
206
208
|
private applyUpdate;
|
|
207
209
|
/** Runs one call from the browser: a magic action, an event, or a public method. Returns its return value. */
|
|
208
210
|
private call;
|
|
209
|
-
/**
|
|
211
|
+
/**
|
|
212
|
+
* Renders the component (rendering/rendered hooks, nested children tracked) and checks for a single root. A
|
|
213
|
+
* WithPagination component's page and page URL are what paginate() reads while it renders, as in its mount() and in
|
|
214
|
+
* its update's hooks and actions.
|
|
215
|
+
*/
|
|
210
216
|
private render;
|
|
217
|
+
/** The absolute URL of the page a memo path belongs to, on the current request's origin ('/' + path without one). */
|
|
218
|
+
private pageUrl;
|
|
211
219
|
/** Dispatches, redirects: the effects every response carries. */
|
|
212
220
|
private effects;
|
|
213
221
|
/** dehydrate() hook, then the state as snapshot data, the error bag, and the checksum over both. */
|
|
@@ -217,8 +225,9 @@ declare class LiveComponentManager implements LiveManager {
|
|
|
217
225
|
/** The URI the client runtime posts updates to. */
|
|
218
226
|
declare const UPDATE_URI = "/oriel/live/update";
|
|
219
227
|
/**
|
|
220
|
-
* Binds the LiveManager
|
|
221
|
-
* group: sessions and CSRF apply), the make:live
|
|
228
|
+
* Binds the LiveManager and the PaginationState that WithPagination components answer, merges the `live` config,
|
|
229
|
+
* registers POST /oriel/live/update (named `live.update`, in the `web` group: sessions and CSRF apply), the make:live
|
|
230
|
+
* command, and the components under app/Live.
|
|
222
231
|
*/
|
|
223
232
|
declare class LiveServiceProvider extends ServiceProvider {
|
|
224
233
|
register(): void;
|
|
@@ -277,10 +286,57 @@ interface PersistentMiddleware {
|
|
|
277
286
|
readonly parameters: readonly string[];
|
|
278
287
|
}
|
|
279
288
|
/**
|
|
280
|
-
* Livewire's persistent middleware: the
|
|
281
|
-
*
|
|
282
|
-
* A path no route matches has none.
|
|
289
|
+
* Livewire's persistent middleware: the middleware among `persistent` (aliases) that the page route (the component's
|
|
290
|
+
* memo path and method) ran, in the order an update runs them. A path no route matches has none.
|
|
283
291
|
*/
|
|
284
292
|
declare function persistentMiddleware(router: Router, persistent: readonly string[], method: string, path: string): PersistentMiddleware[];
|
|
285
293
|
|
|
286
|
-
|
|
294
|
+
type ComponentConstructor = abstract new (...args: any[]) => Component;
|
|
295
|
+
/** What WithPagination() adds to a component: its page and the actions that move it. */
|
|
296
|
+
interface Paginated {
|
|
297
|
+
/** The current page. The browser may set it; Live reads it as a page number. */
|
|
298
|
+
page: number;
|
|
299
|
+
nextPage(): Promise<void>;
|
|
300
|
+
previousPage(): Promise<void>;
|
|
301
|
+
gotoPage(page: number | string): Promise<void>;
|
|
302
|
+
resetPage(): Promise<void>;
|
|
303
|
+
setPage(page: number | string): Promise<void>;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Livewire's WithPagination: `class Posts extends WithPagination(Component)`. The public `page` (1 to start; there
|
|
307
|
+
* is no address-bar sync) is what `paginate()` shows in the component (in `render()`, `mount()`, `hydrate()`, the
|
|
308
|
+
* update hooks and actions, or in a `@Computed` getter any of them reads), and its page links are built on the
|
|
309
|
+
* page's URL. The actions move it: `o:click="nextPage"`, `previousPage`, `gotoPage(3)`, `setPage(3)`,
|
|
310
|
+
* `resetPage` (call it from `updatedSearch()` so a new search starts on page 1). `updatingPage(page)` and
|
|
311
|
+
* `updatedPage(page)` run around every change. One paginator per component: other page names read the request.
|
|
312
|
+
*/
|
|
313
|
+
declare function WithPagination<TBase extends ComponentConstructor>(Base: TBase): TBase & (abstract new (...args: any[]) => Paginated);
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* What <Pagination> reads from a paginator. Structural, since Live can't import Database: paginate()'s
|
|
317
|
+
* LengthAwarePaginator (with lastPage(), so page buttons) and simplePaginate()'s Paginator (Previous and Next only).
|
|
318
|
+
*/
|
|
319
|
+
interface PaginationSource {
|
|
320
|
+
currentPage(): number;
|
|
321
|
+
lastPage?(): number;
|
|
322
|
+
hasMorePages(): boolean;
|
|
323
|
+
onFirstPage(): boolean;
|
|
324
|
+
/** Page buttons on each side of the current one (the paginator's onEachSide(), 3 by default). */
|
|
325
|
+
readonly onEachSideCount?: number;
|
|
326
|
+
/** Not cursorPaginate(): its pages are cursors, which a component's page number can't follow. */
|
|
327
|
+
readonly nextCursor?: never;
|
|
328
|
+
}
|
|
329
|
+
interface PaginationProps {
|
|
330
|
+
paginator: PaginationSource;
|
|
331
|
+
/** Classes for the <nav>, such as its layout ("flex gap-2"); in your file, so Tailwind generates them. */
|
|
332
|
+
class?: string;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Livewire's pagination links for a WithPagination component: `<Pagination paginator={posts} />` in render(). A
|
|
336
|
+
* <nav aria-label="Pagination"> with « Previous, the page buttons and Next » as Live actions (previousPage,
|
|
337
|
+
* gotoPage(n), nextPage), the current page marked aria-current="page", the ends disabled, the kits' theme classes
|
|
338
|
+
* (btn, btn-secondary). Nothing when everything fits on one page. The address bar is left alone.
|
|
339
|
+
*/
|
|
340
|
+
declare function Pagination({ paginator, class: className }: PaginationProps): Htmlable;
|
|
341
|
+
|
|
342
|
+
export { Component, type ComponentResult, Computed, CorruptComponentPayloadError, ErrorBag, InvalidLiveRequestError, Live, LiveComponentManager, LiveComponentNotFoundError, LiveError, type LiveProps, LiveServiceProvider, Locked, MethodNotCallableError, On, PERSISTENT_MIDDLEWARE, type Paginated, Pagination, type PaginationProps, type PaginationSource, PendingEvent, type PersistentMiddleware, PropertyNotUpdatableError, TestRequestScope, Testable, UPDATE_URI, WithPagination, componentName, live, persistentMiddleware };
|