@rpcbase/client 0.285.0 → 0.287.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 (39) hide show
  1. package/dist/RootProvider/index.d.ts +1 -1
  2. package/dist/RootProvider/index.d.ts.map +1 -1
  3. package/dist/apiClient/getServerApiClient.d.ts +1 -1
  4. package/dist/apiClient/getServerApiClient.d.ts.map +1 -1
  5. package/dist/apiClient/index.d.ts +1 -1
  6. package/dist/apiClient/index.d.ts.map +1 -1
  7. package/dist/cleanupURL.d.ts.map +1 -1
  8. package/dist/getFeatureFlag.d.ts.map +1 -1
  9. package/dist/hooks/index.d.ts +2 -2
  10. package/dist/hooks/index.d.ts.map +1 -1
  11. package/dist/hooks/useMediaQuery.d.ts.map +1 -1
  12. package/dist/hooks/useThrottledMeasure.d.ts +1 -1
  13. package/dist/hooks/useThrottledMeasure.d.ts.map +1 -1
  14. package/dist/index.d.ts +6 -5
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +5860 -5
  17. package/dist/initWithRoutes.d.ts +1 -1
  18. package/dist/initWithRoutes.d.ts.map +1 -1
  19. package/dist/types.d.ts +2 -2
  20. package/dist/types.d.ts.map +1 -1
  21. package/dist/utils/useApplyScroll.d.ts.map +1 -1
  22. package/package.json +12 -12
  23. package/dist/RootProvider/index.js +0 -8
  24. package/dist/apiClient/getServerApiClient.js +0 -97
  25. package/dist/apiClient/index.js +0 -50
  26. package/dist/cleanupURL.js +0 -37
  27. package/dist/getFeatureFlag.js +0 -43
  28. package/dist/hooks/index.js +0 -2
  29. package/dist/hooks/useMediaQuery.js +0 -24
  30. package/dist/hooks/useThrottledMeasure.js +0 -32
  31. package/dist/hooks.d.ts +0 -2
  32. package/dist/hooks.d.ts.map +0 -1
  33. package/dist/hooks.js +0 -1
  34. package/dist/initWithRoutes.js +0 -80
  35. package/dist/instrument.d.ts +0 -2
  36. package/dist/instrument.d.ts.map +0 -1
  37. package/dist/instrument.js +0 -29
  38. package/dist/types.js +0 -1
  39. package/dist/utils/useApplyScroll.js +0 -138
@@ -1,4 +1,4 @@
1
- import { createRoutesFromElements } from "@rpcbase/router";
1
+ import { createRoutesFromElements } from '../../router/src';
2
2
  type InitWithRoutesOptions = {
3
3
  devThrowsOnHydrationErrors?: boolean;
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"initWithRoutes.d.ts","sourceRoot":"","sources":["../../../../pkg/client/src/initWithRoutes.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsB,wBAAwB,EAAiB,MAAM,iBAAiB,CAAA;AAqC7F,KAAK,qBAAqB,GAAG;IAC3B,0BAA0B,CAAC,EAAE,OAAO,CAAA;CACrC,CAAA;AAED,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAA;AAEnE,eAAO,MAAM,cAAc,GACzB,eAAe,aAAa,EAC5B,OAAO,qBAAqB,kBA0E7B,CAAA"}
1
+ {"version":3,"file":"initWithRoutes.d.ts","sourceRoot":"","sources":["../src/initWithRoutes.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsB,wBAAwB,EAAiB,MAAM,iBAAiB,CAAA;AAqC7F,KAAK,qBAAqB,GAAG;IAC3B,0BAA0B,CAAC,EAAE,OAAO,CAAA;CACrC,CAAA;AAED,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAA;AAEnE,eAAO,MAAM,cAAc,GACzB,eAAe,aAAa,EAC5B,OAAO,qBAAqB,kBA0E7B,CAAA"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Ctx } from "@rpcbase/api";
2
- import { Params } from "@rpcbase/router";
1
+ import { Ctx } from '../../api/src';
2
+ import { Params } from '../../router/src';
3
3
  export type LoaderArgs = {
4
4
  params: Params;
5
5
  ctx: Ctx;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../pkg/client/src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAGxC,MAAM,MAAM,UAAU,GAAG;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,GAAG,CAAA;CAAC,CAAA;AAGnD,MAAM,MAAM,MAAM,GAAG,CAAC,EAAC,MAAM,EAAE,GAAG,EAAC,EAAE,UAAU,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAGxC,MAAM,MAAM,UAAU,GAAG;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,GAAG,CAAA;CAAC,CAAA;AAGnD,MAAM,MAAM,MAAM,GAAG,CAAC,EAAC,MAAM,EAAE,GAAG,EAAC,EAAE,UAAU,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useApplyScroll.d.ts","sourceRoot":"","sources":["../../../../../pkg/client/src/utils/useApplyScroll.ts"],"names":[],"mappings":"AAiBA,wBAAgB,cAAc,SAuJ7B"}
1
+ {"version":3,"file":"useApplyScroll.d.ts","sourceRoot":"","sources":["../../src/utils/useApplyScroll.ts"],"names":[],"mappings":"AAiBA,wBAAgB,cAAc,SAuJ7B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpcbase/client",
3
- "version": "0.285.0",
3
+ "version": "0.287.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -13,14 +13,15 @@
13
13
  },
14
14
  "wireit": {
15
15
  "build": {
16
- "command": "node ../../scripts/build-package.js client",
16
+ "command": "../../node_modules/.bin/vite build",
17
17
  "files": [
18
18
  "src/**/*",
19
- "hooks.ts",
20
19
  "instrument.ts",
21
20
  "../../tsconfig.json",
22
- "../../tsconfig.base.json",
23
- "../../scripts/build-package.js"
21
+ "../../scripts/tsconfig.pkg.json",
22
+ "./tsconfig.json",
23
+ "./vite.config.js",
24
+ "../../scripts/vite.config-pkg.js"
24
25
  ],
25
26
  "output": [
26
27
  "dist/"
@@ -33,7 +34,6 @@
33
34
  ],
34
35
  "files": [
35
36
  "package.json",
36
- "hooks.ts",
37
37
  "instrument.ts",
38
38
  "src/**/*"
39
39
  ],
@@ -45,12 +45,12 @@
45
45
  }
46
46
  }
47
47
  },
48
- "peerDependencies": {},
49
- "dependencies": {
50
- "axios": "1.13.2",
51
- "fast-equals": "5.2.2",
52
- "lodash": "4.17.21",
48
+ "peerDependencies": {
49
+ "axios": "^1.13",
53
50
  "react-use": "17.6.0"
54
51
  },
55
- "devDependencies": {}
52
+ "devDependencies": {
53
+ "fast-equals": "5.2.2",
54
+ "lodash": "4.17.21"
55
+ }
56
56
  }
@@ -1,8 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import posthog from "posthog-js";
3
- import { PostHogProvider } from "posthog-js/react";
4
- import { useApplyScroll } from "../utils/useApplyScroll";
5
- export const RootProvider = ({ children }) => {
6
- useApplyScroll();
7
- return (_jsx(PostHogProvider, { client: posthog, children: children }));
8
- };
@@ -1,97 +0,0 @@
1
- export const getServerApiClient = async (app) => {
2
- const callRoute = async (app, method, path, req, res) => {
3
- return new Promise((resolve, reject) => {
4
- let isEnded = false;
5
- const mockReq = {
6
- ...req,
7
- method: method.toUpperCase(),
8
- url: path
9
- };
10
- const mockRes = {
11
- ...res,
12
- json: (data) => {
13
- if (!isEnded) {
14
- isEnded = true;
15
- resolve(data);
16
- }
17
- },
18
- status: (statusCode) => {
19
- console.log("Status:", statusCode);
20
- return mockRes;
21
- },
22
- };
23
- const routerStack = app.router.stack;
24
- const firstApiMiddlewareIndex = routerStack.findIndex((layer) => layer.name === "__FIRST_API_MIDDLEWARE__");
25
- if (!(firstApiMiddlewareIndex > -1)) {
26
- throw new Error("middleware: __FIRST_API_MIDDLEWARE__ was not found in stack");
27
- }
28
- const apiStack = routerStack.slice(firstApiMiddlewareIndex + 1);
29
- const processLayer = async (index) => {
30
- if (index >= apiStack.length || isEnded)
31
- return;
32
- const layer = apiStack[index];
33
- const isNonMatchingLayer = !layer.match(path);
34
- if (isNonMatchingLayer) {
35
- // console.log("not machthing route:", path, "to layer:", index, layer.name, layer, "reason: ", {isNonMatchingLayer})
36
- await processLayer(index + 1);
37
- return;
38
- }
39
- const runHandler = async (handler) => new Promise((resolveMiddleware, rejectMiddleware) => {
40
- handler(mockReq, mockRes, (err) => {
41
- if (err) {
42
- console.error("Middleware error:", err);
43
- if (!isEnded) {
44
- isEnded = true;
45
- rejectMiddleware(err);
46
- }
47
- return;
48
- }
49
- resolveMiddleware();
50
- });
51
- });
52
- if (layer.route) {
53
- if (!layer.route.methods[method.toLowerCase()]) {
54
- // console.log("not machthing route:", path, "to route layer:", index, layer.name, layer, "reason: method not matching")
55
- await processLayer(index + 1);
56
- return;
57
- }
58
- if (layer.route.stack.length !== 1) {
59
- throw new Error(`expected only one handler per route for route: ${layer.route.path}`);
60
- }
61
- await runHandler(layer.route.stack[0].handle);
62
- }
63
- else {
64
- await runHandler(layer.handle);
65
- }
66
- if (!isEnded) {
67
- await processLayer(index + 1);
68
- }
69
- };
70
- // AWAIT ??
71
- processLayer(0);
72
- // Set a timeout to prevent hanging
73
- setTimeout(() => {
74
- if (!isEnded) {
75
- reject("Route handler timed out");
76
- }
77
- }, 30000);
78
- });
79
- };
80
- const createMethod = (method) => {
81
- return async (path, payload, ctx) => {
82
- if (!ctx) {
83
- throw new Error("Context must be provided in SSR mode");
84
- }
85
- ctx.req.body = payload;
86
- return callRoute(app, method, path, ctx.req, ctx.res);
87
- };
88
- };
89
- const apiClient = {
90
- get: createMethod("get"),
91
- post: createMethod("post"),
92
- put: createMethod("put"),
93
- delete: createMethod("delete")
94
- };
95
- return apiClient;
96
- };
97
- export default getServerApiClient;
@@ -1,50 +0,0 @@
1
- let apiClient;
2
- export const initApiClient = async (args) => {
3
- if (import.meta.env.SSR) {
4
- if (!args) {
5
- throw new Error("Server args must be provided in SSR mode");
6
- }
7
- const { getServerApiClient } = await import("./getServerApiClient");
8
- apiClient = await getServerApiClient(args.app);
9
- }
10
- else {
11
- const axios = (await import("axios")).default;
12
- const axiosClient = axios.create({
13
- baseURL: "/",
14
- withCredentials: true,
15
- headers: {
16
- "Content-Type": "application/json",
17
- },
18
- });
19
- const createMethod = (method) => {
20
- return async (path, payload, _ctx) => {
21
- const config = {
22
- method,
23
- url: path,
24
- data: payload,
25
- headers: {
26
- // ...(typeof ctxOrPath !== 'string' && {
27
- // // 'X-Custom-Header': ctxOrPath.someHeaderValue,
28
- // // ...ctxOrPath.additionalHeaders,
29
- // }),
30
- },
31
- };
32
- try {
33
- const response = await axiosClient(config);
34
- return response.data;
35
- }
36
- catch (error) {
37
- console.log("AXIOS API ERROR", error);
38
- throw error;
39
- }
40
- };
41
- };
42
- apiClient = {
43
- get: createMethod("get"),
44
- put: createMethod("put"),
45
- post: createMethod("post"),
46
- delete: createMethod("delete"),
47
- };
48
- }
49
- };
50
- export { apiClient };
@@ -1,37 +0,0 @@
1
- const CLEANUP_WAIT_DELAY = 1000;
2
- // Function to clean UTM params while preserving others
3
- export const cleanupURL = () => {
4
- if (import.meta.env.SSR) {
5
- return;
6
- }
7
- const runCleanup = () => {
8
- // Add a small delay before running cleanupURL
9
- setTimeout(() => {
10
- const url = new URL(window.location.href);
11
- const params = new URLSearchParams(url.search);
12
- // Get all current query parameter keys
13
- const paramKeys = Array.from(params.keys());
14
- // Remove any parameter starting with 'utm_'
15
- paramKeys.forEach((key) => {
16
- if (key.startsWith("utm_")) {
17
- params.delete(key);
18
- }
19
- });
20
- // Build the new URL: keep pathname and append remaining query params (if any)
21
- const cleanUrl = url.pathname +
22
- (params.toString() ? "?" + params.toString() : "") +
23
- url.hash;
24
- // Update the browser URL without reloading
25
- window.history.replaceState({}, document.title, cleanUrl);
26
- }, CLEANUP_WAIT_DELAY);
27
- };
28
- // If DOM is already loaded, schedule the cleanup
29
- if (document.readyState === "complete" ||
30
- document.readyState === "interactive") {
31
- runCleanup();
32
- }
33
- else {
34
- // Otherwise wait for the DOM content to be loaded
35
- document.addEventListener("DOMContentLoaded", runCleanup, { once: true });
36
- }
37
- };
@@ -1,43 +0,0 @@
1
- import _snakeCase from "lodash/snakeCase";
2
- export const getFeatureFlag = async (flag) => {
3
- const envKey = `RB_PUBLIC_FLAG_${_snakeCase(flag).toUpperCase()}`;
4
- if (import.meta.env.SSR) {
5
- if (process.env[envKey] !== undefined) {
6
- return process.env[envKey];
7
- }
8
- const startTime = performance.now();
9
- const { PostHog } = await import("posthog-node");
10
- const client = new PostHog(process.env.RB_PUBLIC_POSTHOG_KEY, { host: "https://eu.i.posthog.com" });
11
- const distinctId = "server";
12
- console.log("TODO: NYI server side feature flags client distinctId");
13
- const value = await client.getFeatureFlag(flag, distinctId);
14
- const endTime = performance.now();
15
- console.log(`SSR: Feature flag "${flag}" loaded in ${(endTime - startTime).toFixed(2)}ms`);
16
- return value;
17
- }
18
- else {
19
- if (import.meta.env[envKey] !== undefined) {
20
- return import.meta.env[envKey];
21
- }
22
- const startTime = performance.now();
23
- const { posthog } = await import("posthog-js");
24
- let hasLoadedFeatureFlags = false;
25
- function waitForFeatureFlags() {
26
- return new Promise((resolve) => {
27
- if (hasLoadedFeatureFlags) {
28
- resolve();
29
- }
30
- else {
31
- posthog.onFeatureFlags(() => {
32
- hasLoadedFeatureFlags = true;
33
- resolve();
34
- });
35
- }
36
- });
37
- }
38
- await waitForFeatureFlags();
39
- const endTime = performance.now();
40
- console.log(`Client: Feature flag "${flag}" loaded in ${(endTime - startTime).toFixed(2)}ms`);
41
- return posthog.getFeatureFlag(flag);
42
- }
43
- };
@@ -1,2 +0,0 @@
1
- export * from "./useThrottledMeasure";
2
- export * from "./useMediaQuery";
@@ -1,24 +0,0 @@
1
- import { useSyncExternalStore } from "react";
2
- const emptyUnsubscribe = () => { };
3
- export const useMediaQuery = (query) => {
4
- const isServer = typeof window === "undefined";
5
- const subscribe = (callback) => {
6
- if (isServer)
7
- return emptyUnsubscribe;
8
- const mql = window.matchMedia(query);
9
- // Modern browsers
10
- if (mql.addEventListener) {
11
- mql.addEventListener("change", callback);
12
- return () => mql.removeEventListener("change", callback);
13
- }
14
- // Legacy fallback
15
- mql.addListener(callback);
16
- return () => mql.removeListener(callback);
17
- };
18
- const getSnapshot = () => {
19
- if (isServer)
20
- return false;
21
- return window.matchMedia(query).matches;
22
- };
23
- return useSyncExternalStore(subscribe, getSnapshot, () => false);
24
- };
@@ -1,32 +0,0 @@
1
- import { useState, useEffect, useRef, useCallback } from "react";
2
- import useMeasure from "react-use/lib/useMeasure";
3
- import _throttle from "lodash/throttle";
4
- import { deepEqual } from "fast-equals";
5
- const useMeasureHook = useMeasure.default ?? useMeasure;
6
- const DEFAULT_THROTTLE_TIME = 16;
7
- export const useThrottledMeasure = (throttleDuration = DEFAULT_THROTTLE_TIME) => {
8
- const hasInitialMeasure = useRef(false);
9
- const [ref, measuredRect] = useMeasureHook();
10
- const [rect, setRect] = useState(() => {
11
- return { x: 0, y: 0, width: 0, height: 0, top: 0, left: 0, bottom: 0, right: 0 };
12
- });
13
- const throttledSetRect = useCallback(_throttle((newRect) => {
14
- setRect((current) => {
15
- return deepEqual(current, newRect) ? current : newRect;
16
- });
17
- }, throttleDuration, { leading: true, trailing: true }), [throttleDuration]);
18
- useEffect(() => {
19
- if (measuredRect.width > 0 && !hasInitialMeasure.current) {
20
- hasInitialMeasure.current = true;
21
- setRect((current) => {
22
- return deepEqual(current, measuredRect) ? current : measuredRect;
23
- });
24
- return;
25
- }
26
- throttledSetRect(measuredRect);
27
- return () => {
28
- throttledSetRect.cancel();
29
- };
30
- }, [measuredRect, throttledSetRect]);
31
- return [ref, rect];
32
- };
package/dist/hooks.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from "./src/hooks";
2
- //# sourceMappingURL=hooks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../pkg/client/hooks.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
package/dist/hooks.js DELETED
@@ -1 +0,0 @@
1
- export * from "./src/hooks";
@@ -1,80 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { StrictMode } from "react";
3
- import posthog from "posthog-js";
4
- import { createBrowserRouter, createRoutesFromElements, RouterProvider } from "@rpcbase/router";
5
- import { hydrateRoot } from "react-dom/client";
6
- import { initApiClient } from "./apiClient";
7
- import { cleanupURL } from "./cleanupURL";
8
- const isProduction = import.meta.env.MODE === "production";
9
- /* eslint-disable @typescript-eslint/no-explicit-any */
10
- const showErrorOverlay = (err) => {
11
- const ErrorOverlay = customElements.get("vite-error-overlay");
12
- // don't open outside vite environment
13
- if (!ErrorOverlay) {
14
- return;
15
- }
16
- console.log(err);
17
- const overlay = new ErrorOverlay(err);
18
- document.body.appendChild(overlay);
19
- };
20
- const handleServerErrors = () => {
21
- if (window.__staticRouterHydrationData?.errors) {
22
- const { errors } = window.__staticRouterHydrationData;
23
- Object.values(errors).forEach((error) => {
24
- showErrorOverlay({
25
- plugin: "ssr-router",
26
- ...error.reason
27
- });
28
- });
29
- }
30
- };
31
- export const initWithRoutes = async (routesElement, opts) => {
32
- await initApiClient();
33
- cleanupURL();
34
- handleServerErrors();
35
- const routes = createRoutesFromElements(routesElement);
36
- const router = createBrowserRouter(routes);
37
- const toError = (error) => error instanceof Error ? error : new Error(String(error));
38
- const mentionsHydration = (value, depth = 0) => {
39
- if (depth > 5) {
40
- return false;
41
- }
42
- if (typeof value === "string") {
43
- return value.toLowerCase().includes("hydrat");
44
- }
45
- if (value instanceof Error) {
46
- const digest = value.digest;
47
- const cause = value.cause;
48
- return (mentionsHydration(value.message, depth + 1) ||
49
- mentionsHydration(digest, depth + 1) ||
50
- mentionsHydration(cause, depth + 1));
51
- }
52
- return false;
53
- };
54
- const phReactHandler = (react_context) => (error, errorInfo) => {
55
- const err = toError(error);
56
- // send as exception (counts toward error tracking)
57
- posthog.captureException(err, {
58
- react_context,
59
- component_stack: errorInfo?.componentStack
60
- });
61
- if (react_context === "uncaught") {
62
- console.warn("Uncaught error", err, errorInfo?.componentStack);
63
- }
64
- };
65
- const hydrationOptions = isProduction ? {
66
- onUncaughtError: phReactHandler("uncaught"),
67
- onCaughtError: phReactHandler("caught"),
68
- onRecoverableError: phReactHandler("recoverable")
69
- } : (opts?.devThrowsOnHydrationErrors ? {
70
- onRecoverableError(error, errorInfo) {
71
- const err = toError(error);
72
- if (mentionsHydration(err) || mentionsHydration(errorInfo?.componentStack)) {
73
- throw err;
74
- }
75
- // For non-hydration recoverable errors in dev, keep a visible signal.
76
- console.error(err, errorInfo?.componentStack);
77
- }
78
- } : undefined);
79
- hydrateRoot(document.getElementById("root"), _jsx(StrictMode, { children: _jsx(RouterProvider, { router: router }) }), hydrationOptions);
80
- };
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=instrument.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"instrument.d.ts","sourceRoot":"","sources":["../../../pkg/client/instrument.ts"],"names":[],"mappings":""}
@@ -1,29 +0,0 @@
1
- import posthog from "posthog-js";
2
- const isProduction = import.meta.env.MODE === "production";
3
- const posthogKey = import.meta.env.RB_PUBLIC_POSTHOG_KEY;
4
- if (isProduction) {
5
- if (typeof posthogKey === "string" && posthogKey.length > 0) {
6
- posthog.init(posthogKey, {
7
- api_host: "/ingest",
8
- ui_host: "https://eu.posthog.com",
9
- person_profiles: "always",
10
- session_recording: {
11
- maskAllInputs: false
12
- },
13
- capture_pageview: isProduction,
14
- capture_exceptions: {
15
- capture_unhandled_errors: true,
16
- capture_unhandled_rejections: true,
17
- capture_console_errors: true,
18
- },
19
- autocapture: isProduction,
20
- disable_session_recording: !isProduction,
21
- });
22
- }
23
- else {
24
- console.warn("missing POSTHOG_KEY");
25
- }
26
- }
27
- else {
28
- console.info("ℹ️ Not initializing posthog in development");
29
- }
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,138 +0,0 @@
1
- import { useCallback, useEffect, useRef } from "react";
2
- import { useLocation } from "@rpcbase/router";
3
- function throttle(callback, limit) {
4
- let wait = false;
5
- return (...args) => {
6
- if (!wait) {
7
- callback(...args);
8
- wait = true;
9
- setTimeout(() => {
10
- wait = false;
11
- }, limit);
12
- }
13
- };
14
- }
15
- export function useApplyScroll() {
16
- const location = useLocation();
17
- const previousPathRef = useRef(location.pathname);
18
- const isScrollingProgrammatically = useRef(false);
19
- const scrollTimeoutRef = useRef(null);
20
- const lastAppliedHashRef = useRef("");
21
- useEffect(() => {
22
- if (typeof window !== "undefined") {
23
- lastAppliedHashRef.current = window.location.hash || "";
24
- }
25
- }, []);
26
- useEffect(() => {
27
- lastAppliedHashRef.current = location.hash || "";
28
- }, [location.hash]);
29
- const replaceHashSilently = useCallback((hash) => {
30
- if (typeof window === "undefined") {
31
- return;
32
- }
33
- if (lastAppliedHashRef.current === hash) {
34
- return;
35
- }
36
- const base = `${window.location.pathname}${window.location.search}`;
37
- window.history.replaceState(window.history.state, "", `${base}${hash}`);
38
- lastAppliedHashRef.current = hash;
39
- }, []);
40
- const markProgrammaticScroll = useCallback(() => {
41
- isScrollingProgrammatically.current = true;
42
- if (scrollTimeoutRef.current) {
43
- clearTimeout(scrollTimeoutRef.current);
44
- }
45
- scrollTimeoutRef.current = setTimeout(() => {
46
- isScrollingProgrammatically.current = false;
47
- }, 1000);
48
- }, []);
49
- useEffect(() => {
50
- const pathChanged = previousPathRef.current !== location.pathname;
51
- if (pathChanged) {
52
- previousPathRef.current = location.pathname;
53
- if (!location.hash) {
54
- window.scrollTo({ top: 0, left: 0, behavior: "auto" });
55
- return;
56
- }
57
- setTimeout(() => {
58
- const id = location.hash.substring(1);
59
- const element = document.getElementById(id);
60
- if (element) {
61
- markProgrammaticScroll();
62
- element.scrollIntoView({ behavior: "smooth" });
63
- }
64
- }, 100);
65
- return;
66
- }
67
- if (!location.hash) {
68
- return;
69
- }
70
- const id = location.hash.substring(1);
71
- const element = document.getElementById(id);
72
- if (element) {
73
- markProgrammaticScroll();
74
- element.scrollIntoView({ behavior: "smooth" });
75
- }
76
- }, [location.hash, location.pathname, markProgrammaticScroll]);
77
- useEffect(() => {
78
- if (typeof window === "undefined") {
79
- return;
80
- }
81
- const handleScroll = throttle(() => {
82
- if (isScrollingProgrammatically.current) {
83
- return;
84
- }
85
- const sections = Array.from(document.querySelectorAll("section[id]"));
86
- if (sections.length === 0) {
87
- replaceHashSilently("");
88
- return;
89
- }
90
- const scrollPosition = window.scrollY;
91
- const viewportHeight = window.innerHeight;
92
- const checkPoint = scrollPosition + viewportHeight / 3;
93
- let activeSectionId = null;
94
- for (const section of sections) {
95
- if (section.offsetTop <= checkPoint &&
96
- section.offsetTop + section.offsetHeight > checkPoint) {
97
- activeSectionId = section.id;
98
- break;
99
- }
100
- }
101
- const newHash = activeSectionId ? `#${activeSectionId}` : "";
102
- replaceHashSilently(newHash);
103
- }, 150);
104
- document.addEventListener("scroll", handleScroll);
105
- return () => {
106
- document.removeEventListener("scroll", handleScroll);
107
- if (scrollTimeoutRef.current) {
108
- clearTimeout(scrollTimeoutRef.current);
109
- scrollTimeoutRef.current = null;
110
- }
111
- };
112
- }, [replaceHashSilently]);
113
- useEffect(() => {
114
- const handleClick = (event) => {
115
- const target = event.target;
116
- const link = target?.closest("a");
117
- const currentHash = typeof window !== "undefined"
118
- ? window.location.hash
119
- : location.hash || "";
120
- if (!link ||
121
- !link.hash ||
122
- link.pathname !== location.pathname ||
123
- link.hash !== currentHash) {
124
- return;
125
- }
126
- const id = link.hash.substring(1);
127
- const element = document.getElementById(id);
128
- if (element) {
129
- event.preventDefault();
130
- event.stopPropagation();
131
- markProgrammaticScroll();
132
- element.scrollIntoView({ behavior: "smooth" });
133
- }
134
- };
135
- document.addEventListener("click", handleClick, true);
136
- return () => document.removeEventListener("click", handleClick, true);
137
- }, [location.hash, location.pathname, markProgrammaticScroll]);
138
- }