@rpcbase/client 0.283.0 → 0.285.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 (57) hide show
  1. package/dist/RootProvider/index.d.ts +7 -0
  2. package/dist/RootProvider/index.d.ts.map +1 -0
  3. package/dist/RootProvider/index.js +8 -0
  4. package/dist/apiClient/getServerApiClient.d.ts +10 -0
  5. package/dist/apiClient/getServerApiClient.d.ts.map +1 -0
  6. package/dist/apiClient/getServerApiClient.js +97 -0
  7. package/dist/apiClient/index.d.ts +16 -0
  8. package/dist/apiClient/index.d.ts.map +1 -0
  9. package/dist/apiClient/index.js +50 -0
  10. package/dist/cleanupURL.d.ts +2 -0
  11. package/dist/cleanupURL.d.ts.map +1 -0
  12. package/dist/cleanupURL.js +37 -0
  13. package/dist/getFeatureFlag.d.ts +2 -0
  14. package/dist/getFeatureFlag.d.ts.map +1 -0
  15. package/dist/getFeatureFlag.js +43 -0
  16. package/dist/hooks/index.d.ts +3 -0
  17. package/dist/hooks/index.d.ts.map +1 -0
  18. package/dist/hooks/index.js +2 -0
  19. package/dist/hooks/useMediaQuery.d.ts +2 -0
  20. package/dist/hooks/useMediaQuery.d.ts.map +1 -0
  21. package/dist/hooks/useMediaQuery.js +24 -0
  22. package/dist/hooks/useThrottledMeasure.d.ts +11 -0
  23. package/dist/hooks/useThrottledMeasure.d.ts.map +1 -0
  24. package/dist/hooks/useThrottledMeasure.js +32 -0
  25. package/dist/hooks.d.ts +2 -0
  26. package/dist/hooks.d.ts.map +1 -0
  27. package/dist/hooks.js +1 -0
  28. package/dist/index.d.ts +6 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +5 -0
  31. package/dist/initWithRoutes.d.ts +8 -0
  32. package/dist/initWithRoutes.d.ts.map +1 -0
  33. package/dist/initWithRoutes.js +80 -0
  34. package/dist/instrument.d.ts +2 -0
  35. package/dist/instrument.d.ts.map +1 -0
  36. package/dist/instrument.js +29 -0
  37. package/dist/types.d.ts +8 -0
  38. package/dist/types.d.ts.map +1 -0
  39. package/dist/types.js +1 -0
  40. package/dist/utils/useApplyScroll.d.ts +2 -0
  41. package/dist/utils/useApplyScroll.d.ts.map +1 -0
  42. package/dist/utils/useApplyScroll.js +138 -0
  43. package/package.json +27 -7
  44. package/hooks.ts +0 -1
  45. package/instrument.ts +0 -32
  46. package/src/RootProvider/index.tsx +0 -15
  47. package/src/apiClient/getServerApiClient.ts +0 -133
  48. package/src/apiClient/index.ts +0 -86
  49. package/src/cleanupURL.ts +0 -46
  50. package/src/getFeatureFlag.ts +0 -58
  51. package/src/hooks/index.ts +0 -2
  52. package/src/hooks/useMediaQuery.ts +0 -31
  53. package/src/hooks/useThrottledMeasure.ts +0 -49
  54. package/src/index.ts +0 -5
  55. package/src/initWithRoutes.tsx +0 -115
  56. package/src/types.ts +0 -8
  57. package/src/utils/useApplyScroll.ts +0 -169
@@ -1,115 +0,0 @@
1
- import { StrictMode } from "react"
2
- import posthog from "posthog-js"
3
- import {createBrowserRouter, createRoutesFromElements, RouterProvider} from "@rpcbase/router"
4
- import { hydrateRoot } from "react-dom/client"
5
-
6
- import { initApiClient } from "./apiClient"
7
- import {cleanupURL} from "./cleanupURL"
8
-
9
-
10
- const isProduction = import.meta.env.MODE === "production"
11
-
12
- type ReactErrorInfo = { componentStack?: string }
13
-
14
-
15
- /* eslint-disable @typescript-eslint/no-explicit-any */
16
- const showErrorOverlay = (err: { title: string, message: string, reason: string, plugin: string }) => {
17
- const ErrorOverlay = customElements.get("vite-error-overlay")
18
- // don't open outside vite environment
19
- if (!ErrorOverlay) {return}
20
- console.log(err)
21
- const overlay = new ErrorOverlay(err)
22
- document.body.appendChild(overlay)
23
- }
24
-
25
-
26
- const handleServerErrors = () => {
27
- if ((window as any).__staticRouterHydrationData?.errors) {
28
-
29
- const {errors} = (window as any).__staticRouterHydrationData
30
-
31
- Object.values(errors).forEach((error: any) => {
32
- showErrorOverlay({
33
- plugin: "ssr-router",
34
- ...error.reason
35
- })
36
- })
37
- }
38
- }
39
-
40
-
41
- // TODO: what type is this
42
- export const initWithRoutes = async (routesElement, opts) => {
43
-
44
- await initApiClient()
45
-
46
- cleanupURL()
47
-
48
- handleServerErrors()
49
-
50
-
51
- const routes = createRoutesFromElements(routesElement)
52
- const router = createBrowserRouter(routes)
53
-
54
-
55
- const toError = (error: unknown): Error =>
56
- error instanceof Error ? error : new Error(String(error))
57
-
58
- const mentionsHydration = (value: unknown, depth = 0): boolean => {
59
- if (depth > 5) {
60
- return false
61
- }
62
- if (typeof value === "string") {
63
- return value.toLowerCase().includes("hydrat")
64
- }
65
- if (value instanceof Error) {
66
- const digest = (value as { digest?: unknown }).digest
67
- const cause = (value as { cause?: unknown }).cause
68
- return (
69
- mentionsHydration(value.message, depth + 1) ||
70
- mentionsHydration(digest, depth + 1) ||
71
- mentionsHydration(cause, depth + 1)
72
- )
73
- }
74
- return false
75
- }
76
-
77
- const phReactHandler =
78
- (react_context: "uncaught" | "caught" | "recoverable") =>
79
- (error: unknown, errorInfo?: ReactErrorInfo) => {
80
- const err = toError(error)
81
- // send as exception (counts toward error tracking)
82
- posthog.captureException(err, {
83
- react_context,
84
- component_stack: errorInfo?.componentStack
85
- })
86
- if (react_context === "uncaught") {
87
- console.warn("Uncaught error", err, errorInfo?.componentStack)
88
- }
89
- }
90
-
91
- const hydrationOptions: Parameters<typeof hydrateRoot>[2] | undefined = isProduction ? {
92
- onUncaughtError: phReactHandler("uncaught"),
93
- onCaughtError: phReactHandler("caught"),
94
- onRecoverableError: phReactHandler("recoverable")
95
- } : (opts?.devThrowsOnHydrationErrors ? {
96
- onRecoverableError(error, errorInfo) {
97
- const err = toError(error)
98
- if (mentionsHydration(err) || mentionsHydration(errorInfo?.componentStack)) {
99
- throw err
100
- }
101
- // For non-hydration recoverable errors in dev, keep a visible signal.
102
- console.error(err, errorInfo?.componentStack)
103
- }
104
- } : undefined)
105
-
106
-
107
- hydrateRoot(
108
- document.getElementById("root") as HTMLElement,
109
- <StrictMode>
110
- <RouterProvider router={router} />
111
- </StrictMode>,
112
- hydrationOptions
113
- )
114
-
115
- }
package/src/types.ts DELETED
@@ -1,8 +0,0 @@
1
- import { Ctx } from "@rpcbase/api"
2
- import { Params } from "@rpcbase/router"
3
-
4
-
5
- export type LoaderArgs = {params: Params, ctx: Ctx}
6
-
7
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
- export type Loader = ({params, ctx}: LoaderArgs) => Promise<any>
@@ -1,169 +0,0 @@
1
- import { useCallback, useEffect, useRef } from "react"
2
- import { useLocation } from "@rpcbase/router"
3
-
4
-
5
- function throttle(callback: (...args: any[]) => void, limit: number) {
6
- let wait = false
7
- return (...args: any[]) => {
8
- if (!wait) {
9
- callback(...args)
10
- wait = true
11
- setTimeout(() => {
12
- wait = false
13
- }, limit)
14
- }
15
- }
16
- }
17
-
18
- export function useApplyScroll() {
19
- const location = useLocation()
20
- const previousPathRef = useRef(location.pathname)
21
- const isScrollingProgrammatically = useRef(false)
22
- const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null)
23
- const lastAppliedHashRef = useRef("")
24
-
25
- useEffect(() => {
26
- if (typeof window !== "undefined") {
27
- lastAppliedHashRef.current = window.location.hash || ""
28
- }
29
- }, [])
30
-
31
- useEffect(() => {
32
- lastAppliedHashRef.current = location.hash || ""
33
- }, [location.hash])
34
-
35
- const replaceHashSilently = useCallback((hash: string) => {
36
- if (typeof window === "undefined") {
37
- return
38
- }
39
- if (lastAppliedHashRef.current === hash) {
40
- return
41
- }
42
- const base = `${window.location.pathname}${window.location.search}`
43
- window.history.replaceState(window.history.state, "", `${base}${hash}`)
44
- lastAppliedHashRef.current = hash
45
- }, [])
46
-
47
- const markProgrammaticScroll = useCallback(() => {
48
- isScrollingProgrammatically.current = true
49
- if (scrollTimeoutRef.current) {
50
- clearTimeout(scrollTimeoutRef.current)
51
- }
52
- scrollTimeoutRef.current = setTimeout(() => {
53
- isScrollingProgrammatically.current = false
54
- }, 1000)
55
- }, [])
56
-
57
- useEffect(() => {
58
- const pathChanged = previousPathRef.current !== location.pathname
59
-
60
- if (pathChanged) {
61
- previousPathRef.current = location.pathname
62
-
63
- if (!location.hash) {
64
- window.scrollTo({ top: 0, left: 0, behavior: "auto" })
65
- return
66
- }
67
-
68
- setTimeout(() => {
69
- const id = location.hash.substring(1)
70
- const element = document.getElementById(id)
71
- if (element) {
72
- markProgrammaticScroll()
73
- element.scrollIntoView({ behavior: "smooth" })
74
- }
75
- }, 100)
76
-
77
- return
78
- }
79
-
80
- if (!location.hash) {
81
- return
82
- }
83
-
84
- const id = location.hash.substring(1)
85
- const element = document.getElementById(id)
86
- if (element) {
87
- markProgrammaticScroll()
88
- element.scrollIntoView({ behavior: "smooth" })
89
- }
90
- }, [location.hash, location.pathname, markProgrammaticScroll])
91
-
92
- useEffect(() => {
93
- if (typeof window === "undefined") {
94
- return
95
- }
96
-
97
- const handleScroll = throttle(() => {
98
- if (isScrollingProgrammatically.current) {
99
- return
100
- }
101
-
102
- const sections = Array.from(document.querySelectorAll("section[id]"))
103
-
104
- if (sections.length === 0) {
105
- replaceHashSilently("")
106
- return
107
- }
108
-
109
- const scrollPosition = window.scrollY
110
- const viewportHeight = window.innerHeight
111
- const checkPoint = scrollPosition + viewportHeight / 3
112
-
113
- let activeSectionId: string | null = null
114
- for (const section of sections) {
115
- if (
116
- section.offsetTop <= checkPoint &&
117
- section.offsetTop + section.offsetHeight > checkPoint
118
- ) {
119
- activeSectionId = section.id
120
- break
121
- }
122
- }
123
-
124
- const newHash = activeSectionId ? `#${activeSectionId}` : ""
125
- replaceHashSilently(newHash)
126
- }, 150)
127
-
128
- document.addEventListener("scroll", handleScroll)
129
- return () => {
130
- document.removeEventListener("scroll", handleScroll)
131
- if (scrollTimeoutRef.current) {
132
- clearTimeout(scrollTimeoutRef.current)
133
- scrollTimeoutRef.current = null
134
- }
135
- }
136
- }, [replaceHashSilently])
137
-
138
- useEffect(() => {
139
- const handleClick = (event: MouseEvent) => {
140
- const target = event.target as HTMLElement | null
141
- const link = target?.closest("a")
142
- const currentHash =
143
- typeof window !== "undefined"
144
- ? window.location.hash
145
- : location.hash || ""
146
-
147
- if (
148
- !link ||
149
- !link.hash ||
150
- link.pathname !== location.pathname ||
151
- link.hash !== currentHash
152
- ) {
153
- return
154
- }
155
-
156
- const id = link.hash.substring(1)
157
- const element = document.getElementById(id)
158
- if (element) {
159
- event.preventDefault()
160
- event.stopPropagation()
161
- markProgrammaticScroll()
162
- element.scrollIntoView({ behavior: "smooth" })
163
- }
164
- }
165
-
166
- document.addEventListener("click", handleClick, true)
167
- return () => document.removeEventListener("click", handleClick, true)
168
- }, [location.hash, location.pathname, markProgrammaticScroll])
169
- }