pejay-ui 1.2.2 → 1.3.1

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 (61) hide show
  1. package/README.md +17 -2
  2. package/package.json +2 -2
  3. package/registry.json +33 -1
  4. package/templates/notes/create-pejay.md +222 -0
  5. package/templates/notes/notes-v1.md +516 -0
  6. package/templates/notes/notes-v2.md +764 -0
  7. package/templates/notes/notes-v3.md +574 -0
  8. package/templates/notes/notes-v4.md +811 -0
  9. package/templates/notes/notes-v5.md +579 -0
  10. package/templates/notes/notes-vf+1.md +311 -0
  11. package/templates/notes/notes-vfinal.md +852 -0
  12. package/templates/scaffolds/axios/api/index.ts +40 -0
  13. package/templates/scaffolds/axios/api/one.api.ts +94 -0
  14. package/templates/scaffolds/axios/endpoints.ts +9 -0
  15. package/templates/scaffolds/axios/index.ts +26 -0
  16. package/templates/scaffolds/axios/interceptors.ts +103 -0
  17. package/templates/scaffolds/axios/request.ts +32 -0
  18. package/templates/scaffolds/react-router/hook/useRouterSearch.ts +8 -0
  19. package/templates/scaffolds/react-router/router/guards/private.route.tsx +1 -0
  20. package/templates/scaffolds/react-router/router/index.ts +26 -0
  21. package/templates/scaffolds/react-router/router/layouts/error.layout.tsx +1 -1
  22. package/templates/scaffolds/redux-store/middlewares.ts +0 -0
  23. package/templates/scaffolds/redux-store/reducers.ts +30 -0
  24. package/templates/scaffolds/redux-store/selector/one.selector.ts +43 -0
  25. package/templates/scaffolds/redux-store/selector/two.selector.ts +11 -0
  26. package/templates/scaffolds/redux-store/slices/one.slice.ts +202 -0
  27. package/templates/scaffolds/redux-store/slices/two.slice.ts +21 -0
  28. package/templates/scaffolds/redux-store/store.ts +38 -0
  29. package/templates/scaffolds/rtk-query/baseApi.ts +24 -0
  30. package/templates/scaffolds/rtk-query/baseQuery.ts +12 -0
  31. package/templates/scaffolds/rtk-query/endpoints/api.one.ts +82 -0
  32. package/templates/scaffolds/rtk-query/endpoints/index.ts +1 -0
  33. package/templates/scaffolds/rtk-query/middlewares.ts +11 -0
  34. package/templates/scaffolds/rtk-query/queryTags.ts +13 -0
  35. package/templates/scaffolds/tanstack-query/api-base.ts +68 -68
  36. package/templates/scaffolds/tanstack-query/api-queries.ts +0 -19
  37. package/templates/scaffolds/tanstack-query/client.ts +8 -0
  38. package/templates/scaffolds/tanstack-query/module/index.ts +12 -12
  39. package/templates/scaffolds/tanstack-query/module/keys.ts +17 -17
  40. package/templates/scaffolds/tanstack-query/module/mappers.ts +15 -15
  41. package/templates/scaffolds/tanstack-query/module/mutations.ts +59 -55
  42. package/templates/scaffolds/tanstack-query/module/queries.ts +145 -156
  43. package/templates/scaffolds/tanstack-query/module/services.ts +74 -66
  44. package/templates/scaffolds/tanstack-router/layout/404.layout.tsx +3 -0
  45. package/templates/scaffolds/tanstack-router/layout/app.layout.tsx +10 -0
  46. package/templates/scaffolds/tanstack-router/layout/auth.layout.tsx +10 -0
  47. package/templates/scaffolds/tanstack-router/layout/error.layout.tsx +3 -0
  48. package/templates/scaffolds/tanstack-router/page/auth/login.tsx +3 -0
  49. package/templates/scaffolds/tanstack-router/page/one/index.tsx +3 -0
  50. package/templates/scaffolds/tanstack-router/page/one/one-id.tsx +128 -0
  51. package/templates/scaffolds/tanstack-router/router.ts +90 -0
  52. package/templates/scaffolds/tanstack-router/routes/_404.tsx +0 -0
  53. package/templates/scaffolds/tanstack-router/routes/__root.tsx +9 -0
  54. package/templates/scaffolds/tanstack-router/routes/_app.tsx +6 -0
  55. package/templates/scaffolds/tanstack-router/routes/_auth.tsx +6 -0
  56. package/templates/scaffolds/tanstack-router/routes/_error.tsx +0 -0
  57. package/templates/scaffolds/tanstack-router/routes/auth/login.tsx +6 -0
  58. package/templates/scaffolds/tanstack-router/routes/one/$id.tsx +191 -0
  59. package/templates/scaffolds/tanstack-router/routes/one/index.tsx +6 -0
  60. package/templates/scripts/setup.bat +284 -0
  61. package/templates/scripts/setup.ps1 +318 -0
@@ -0,0 +1,811 @@
1
+ # TanStack Router - Advanced Features & Overlooked APIs
2
+
3
+ This document covers TanStack Router features that are often missed during the initial learning phase but become extremely valuable in medium-to-large applications.
4
+
5
+ ---
6
+
7
+ # 1. beforeLoad()
8
+
9
+ One of the most important TanStack Router features.
10
+
11
+ Runs before:
12
+
13
+ ```txt
14
+ Component Render
15
+ Loader Execution
16
+ Route Entry
17
+ ```
18
+
19
+ Example:
20
+
21
+ ```tsx
22
+ export const Route = createFileRoute("/_app")({
23
+ beforeLoad: ({ context }) => {
24
+ if (!context.auth.isAuthenticated) {
25
+ throw redirect({
26
+ to: "/login",
27
+ });
28
+ }
29
+ },
30
+ });
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Common Uses
36
+
37
+ ```txt
38
+ Authentication
39
+ Authorization
40
+ Feature Flags
41
+ Role Checks
42
+ Tenant Validation
43
+ Subscription Checks
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Benefits
49
+
50
+ ```txt
51
+ ✓ Prevents unnecessary API calls
52
+ ✓ Prevents component mounting
53
+ ✓ Centralized access control
54
+ ✓ Better than component-level guards
55
+ ```
56
+
57
+ ---
58
+
59
+ # 2. createRootRouteWithContext()
60
+
61
+ Provides globally typed router context.
62
+
63
+ Example:
64
+
65
+ ```tsx
66
+ interface RouterContext {
67
+ auth: AuthStore;
68
+ queryClient: QueryClient;
69
+ }
70
+ ```
71
+
72
+ Root Route:
73
+
74
+ ```tsx
75
+ export const Route =
76
+ createRootRouteWithContext<
77
+ RouterContext
78
+ >()({
79
+ component: RootLayout,
80
+ });
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Why Use It?
86
+
87
+ Provides type-safe access to:
88
+
89
+ ```txt
90
+ Authentication
91
+ Query Client
92
+ API Services
93
+ Application Services
94
+ ```
95
+
96
+ throughout your routing tree.
97
+
98
+ ---
99
+
100
+ # 3. Route.useRouteContext()
101
+
102
+ Read router context inside a route.
103
+
104
+ Example:
105
+
106
+ ```tsx
107
+ const context =
108
+ Route.useRouteContext();
109
+ ```
110
+
111
+ Access:
112
+
113
+ ```tsx
114
+ context.auth
115
+ context.queryClient
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Use Cases
121
+
122
+ ```txt
123
+ Current User
124
+ Permissions
125
+ Query Client Access
126
+ Application Services
127
+ ```
128
+
129
+ ---
130
+
131
+ # 4. Route.useParams()
132
+
133
+ Read route parameters.
134
+
135
+ Route:
136
+
137
+ ```txt
138
+ /users/$id
139
+ ```
140
+
141
+ URL:
142
+
143
+ ```txt
144
+ /users/123
145
+ ```
146
+
147
+ Usage:
148
+
149
+ ```tsx
150
+ const { id } =
151
+ Route.useParams();
152
+ ```
153
+
154
+ Result:
155
+
156
+ ```tsx
157
+ id === "123"
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Common Usage
163
+
164
+ ```txt
165
+ Detail Pages
166
+ Edit Pages
167
+ Nested Resources
168
+ ```
169
+
170
+ Examples:
171
+
172
+ ```txt
173
+ /patient/123
174
+ /invoice/456
175
+ /user/789
176
+ ```
177
+
178
+ ---
179
+
180
+ # 5. Route.useSearch()
181
+
182
+ Read validated search parameters.
183
+
184
+ URL:
185
+
186
+ ```txt
187
+ /users?search=john&type=active
188
+ ```
189
+
190
+ Validation:
191
+
192
+ ```tsx
193
+ validateSearch: (search) => ({
194
+ search:
195
+ typeof search.search === "string"
196
+ ? search.search
197
+ : "",
198
+
199
+ type:
200
+ typeof search.type === "string"
201
+ ? search.type
202
+ : "",
203
+ })
204
+ ```
205
+
206
+ Usage:
207
+
208
+ ```tsx
209
+ const search =
210
+ Route.useSearch();
211
+ ```
212
+
213
+ Result:
214
+
215
+ ```tsx
216
+ {
217
+ search: "john",
218
+ type: "active",
219
+ }
220
+ ```
221
+
222
+ ---
223
+
224
+ ## Why It's Powerful
225
+
226
+ After validation:
227
+
228
+ ```tsx
229
+ search.search
230
+ search.type
231
+ ```
232
+
233
+ are fully typed.
234
+
235
+ No:
236
+
237
+ ```tsx
238
+ searchParams.get()
239
+ Number()
240
+ Boolean()
241
+ ```
242
+
243
+ scattered across components.
244
+
245
+ ---
246
+
247
+ # 6. Route.useLoaderData()
248
+
249
+ Reads the value returned by a route loader.
250
+
251
+ Route:
252
+
253
+ ```tsx
254
+ loader: async () => {
255
+ return {
256
+ title: "Users",
257
+ };
258
+ }
259
+ ```
260
+
261
+ Usage:
262
+
263
+ ```tsx
264
+ const data =
265
+ Route.useLoaderData();
266
+ ```
267
+
268
+ Result:
269
+
270
+ ```tsx
271
+ data.title
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Best For
277
+
278
+ ```txt
279
+ Page Metadata
280
+ Simple Route Data
281
+ Configuration Data
282
+ Non-Query Information
283
+ ```
284
+
285
+ ---
286
+
287
+ ## Usually Not Needed When Using TanStack Query
288
+
289
+ Preferred pattern:
290
+
291
+ ```txt
292
+ Loader
293
+
294
+ ensureQueryData()
295
+
296
+ Component
297
+
298
+ useSuspenseQuery()
299
+ ```
300
+
301
+ This leverages:
302
+
303
+ ```txt
304
+ Caching
305
+ Invalidation
306
+ Refetching
307
+ Mutations
308
+ ```
309
+
310
+ ---
311
+
312
+ # 7. useRouter()
313
+
314
+ Access the router instance.
315
+
316
+ Example:
317
+
318
+ ```tsx
319
+ const router =
320
+ useRouter();
321
+ ```
322
+
323
+ ---
324
+
325
+ ## Common Uses
326
+
327
+ ### Navigation
328
+
329
+ ```tsx
330
+ router.navigate({
331
+ to: "/users",
332
+ });
333
+ ```
334
+
335
+ ### Reload Route Data
336
+
337
+ ```tsx
338
+ await router.invalidate();
339
+ ```
340
+
341
+ ### Access Router State
342
+
343
+ ```tsx
344
+ router.state
345
+ ```
346
+
347
+ ---
348
+
349
+ # 8. router.invalidate()
350
+
351
+ Forces active route loaders to rerun.
352
+
353
+ Example:
354
+
355
+ ```tsx
356
+ await router.invalidate();
357
+ ```
358
+
359
+ ---
360
+
361
+ ## Useful After
362
+
363
+ ```txt
364
+ Login
365
+ Logout
366
+ Location Change
367
+ Role Change
368
+ Permission Updates
369
+ ```
370
+
371
+ Think:
372
+
373
+ ```txt
374
+ QueryClient.invalidateQueries()
375
+
376
+ but for route loaders.
377
+ ```
378
+
379
+ ---
380
+
381
+ # 9. useRouterState()
382
+
383
+ Subscribe to router state updates.
384
+
385
+ Example:
386
+
387
+ ```tsx
388
+ const state =
389
+ useRouterState();
390
+ ```
391
+
392
+ ---
393
+
394
+ ## Global Loading Indicator
395
+
396
+ ```tsx
397
+ const isPending =
398
+ useRouterState({
399
+ select: (state) =>
400
+ state.status === "pending",
401
+ });
402
+ ```
403
+
404
+ Usage:
405
+
406
+ ```tsx
407
+ {
408
+ isPending &&
409
+ <TopLoader />
410
+ }
411
+ ```
412
+
413
+ ---
414
+
415
+ ## Great For
416
+
417
+ ```txt
418
+ Progress Bars
419
+ Global Skeletons
420
+ Route Loading Indicators
421
+ Analytics Tracking
422
+ ```
423
+
424
+ ---
425
+
426
+ # 10. loaderDeps()
427
+
428
+ Specify values that should trigger loader re-execution.
429
+
430
+ Example:
431
+
432
+ ```tsx
433
+ loaderDeps: ({ search }) => ({
434
+ search: search.search,
435
+ page: search.page,
436
+ })
437
+ ```
438
+
439
+ ---
440
+
441
+ ## Why Use It?
442
+
443
+ Without it:
444
+
445
+ ```txt
446
+ Search Changes
447
+
448
+ Loader Might Not Rerun
449
+ ```
450
+
451
+ With it:
452
+
453
+ ```txt
454
+ Search Changes
455
+
456
+ Loader Reruns
457
+ ```
458
+
459
+ ---
460
+
461
+ ## Best For
462
+
463
+ ```txt
464
+ Tables
465
+ Filters
466
+ Pagination
467
+ Search Screens
468
+ ```
469
+
470
+ ---
471
+
472
+ # 11. Route.useNavigate()
473
+
474
+ Route-scoped navigation helper.
475
+
476
+ Example:
477
+
478
+ ```tsx
479
+ const navigate =
480
+ Route.useNavigate();
481
+ ```
482
+
483
+ Usage:
484
+
485
+ ```tsx
486
+ navigate({
487
+ search: {
488
+ page: 2,
489
+ },
490
+ });
491
+ ```
492
+
493
+ ---
494
+
495
+ ## Best For
496
+
497
+ ```txt
498
+ Updating Search Params
499
+ Relative Navigation
500
+ Pagination
501
+ Filtering
502
+ ```
503
+
504
+ ---
505
+
506
+ # 12. useMatchRoute()
507
+
508
+ Determine if a route matches.
509
+
510
+ Example:
511
+
512
+ ```tsx
513
+ const matchRoute =
514
+ useMatchRoute();
515
+ ```
516
+
517
+ Usage:
518
+
519
+ ```tsx
520
+ const isUsersPage =
521
+ matchRoute({
522
+ to: "/users",
523
+ });
524
+ ```
525
+
526
+ ---
527
+
528
+ ## Great For
529
+
530
+ ```txt
531
+ Sidebar Active States
532
+ Menu Highlighting
533
+ Conditional UI
534
+ ```
535
+
536
+ ---
537
+
538
+ # 13. Route Preloading
539
+
540
+ Manual route prefetching.
541
+
542
+ Example:
543
+
544
+ ```tsx
545
+ router.preloadRoute({
546
+ to: "/reports",
547
+ });
548
+ ```
549
+
550
+ or
551
+
552
+ ```tsx
553
+ <Link
554
+ to="/reports"
555
+ preload="intent"
556
+ />
557
+ ```
558
+
559
+ ---
560
+
561
+ ## Benefit
562
+
563
+ ```txt
564
+ Hover Link
565
+
566
+ Route Downloads
567
+
568
+ Instant Navigation
569
+ ```
570
+
571
+ ---
572
+
573
+ # 14. pendingComponent
574
+
575
+ Route-level loading UI.
576
+
577
+ Example:
578
+
579
+ ```tsx
580
+ export const Route =
581
+ createFileRoute("/users")({
582
+ pendingComponent:
583
+ UsersSkeleton,
584
+ });
585
+ ```
586
+
587
+ Shown while:
588
+
589
+ ```txt
590
+ Loader Running
591
+ Route Loading
592
+ Navigation Pending
593
+ ```
594
+
595
+ ---
596
+
597
+ # 15. pendingMs
598
+
599
+ Delay pendingComponent appearance.
600
+
601
+ Example:
602
+
603
+ ```tsx
604
+ pendingMs: 300
605
+ ```
606
+
607
+ Behavior:
608
+
609
+ ```txt
610
+ <300ms
611
+
612
+ No Skeleton
613
+
614
+ >300ms
615
+
616
+ Show Skeleton
617
+ ```
618
+
619
+ ---
620
+
621
+ ## Prevents
622
+
623
+ ```txt
624
+ Loading Flicker
625
+ ```
626
+
627
+ for very fast requests.
628
+
629
+ ---
630
+
631
+ # 16. pendingMinMs
632
+
633
+ Minimum display duration for pendingComponent.
634
+
635
+ Example:
636
+
637
+ ```tsx
638
+ pendingMinMs: 500
639
+ ```
640
+
641
+ Behavior:
642
+
643
+ ```txt
644
+ Skeleton Appears
645
+
646
+ Remains Visible For 500ms
647
+
648
+ Content Displays
649
+ ```
650
+
651
+ ---
652
+
653
+ ## Prevents
654
+
655
+ ```txt
656
+ Flashy Loading States
657
+ ```
658
+
659
+ ---
660
+
661
+ # 17. notFoundComponent
662
+
663
+ Route-specific 404 handling.
664
+
665
+ Example:
666
+
667
+ ```tsx
668
+ export const Route =
669
+ createFileRoute("/users")({
670
+ notFoundComponent:
671
+ UserNotFound,
672
+ });
673
+ ```
674
+
675
+ ---
676
+
677
+ ## Great For
678
+
679
+ ```txt
680
+ Patient Not Found
681
+ Invoice Not Found
682
+ User Not Found
683
+ Record Not Found
684
+ ```
685
+
686
+ ---
687
+
688
+ # 18. Search Param Validation
689
+
690
+ One of TanStack Router's strongest features.
691
+
692
+ Example:
693
+
694
+ ```tsx
695
+ validateSearch: (search) => ({
696
+ page:
697
+ Number(search.page ?? 1),
698
+
699
+ search:
700
+ typeof search.search === "string"
701
+ ? search.search
702
+ : "",
703
+ })
704
+ ```
705
+
706
+ ---
707
+
708
+ ## Benefit
709
+
710
+ After validation:
711
+
712
+ ```tsx
713
+ const search =
714
+ Route.useSearch();
715
+ ```
716
+
717
+ Result:
718
+
719
+ ```tsx
720
+ search.page
721
+ search.search
722
+ ```
723
+
724
+ are already typed.
725
+
726
+ ---
727
+
728
+ # Recommended Learning Order
729
+
730
+ ## Level 1 - Daily Usage
731
+
732
+ ```tsx
733
+ <Link />
734
+ <Outlet />
735
+
736
+ Route.useParams()
737
+
738
+ Route.useSearch()
739
+
740
+ useNavigate()
741
+
742
+ redirect()
743
+ ```
744
+
745
+ ---
746
+
747
+ ## Level 2 - Most Useful Features
748
+
749
+ ```tsx
750
+ beforeLoad()
751
+
752
+ loader()
753
+
754
+ pendingComponent
755
+
756
+ ensureQueryData()
757
+
758
+ useSuspenseQuery()
759
+ ```
760
+
761
+ ---
762
+
763
+ ## Level 3 - Intermediate
764
+
765
+ ```tsx
766
+ createRootRouteWithContext()
767
+
768
+ Route.useRouteContext()
769
+
770
+ useRouter()
771
+
772
+ useRouterState()
773
+
774
+ router.invalidate()
775
+ ```
776
+
777
+ ---
778
+
779
+ ## Level 4 - Advanced
780
+
781
+ ```tsx
782
+ loaderDeps()
783
+
784
+ useMatchRoute()
785
+
786
+ Route Preloading
787
+
788
+ pendingMs
789
+
790
+ pendingMinMs
791
+
792
+ notFoundComponent
793
+ ```
794
+
795
+ ---
796
+
797
+ # Features That Usually Win Over React Router Users
798
+
799
+ ```txt
800
+ 1. Route.useSearch() + validateSearch()
801
+
802
+ 2. beforeLoad()
803
+
804
+ 3. createRootRouteWithContext()
805
+
806
+ 4. Route.useParams()
807
+
808
+ 5. Automatic Route Type Safety
809
+ ```
810
+
811
+ These are typically the features that make larger TanStack Router applications feel significantly cleaner and easier to maintain than equivalent React Router implementations.