@liberfi.io/hooks 0.1.24 → 0.1.25

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 ADDED
@@ -0,0 +1,224 @@
1
+ # @liberfi.io/hooks
2
+
3
+ A collection of framework-agnostic React utility hooks used across the LiberFi frontend. Provides common patterns — boolean state, stable callback refs, resize observation, periodic ticking, and a shared event bus — so that consuming packages don't reinvent them.
4
+
5
+ ## Design Philosophy
6
+
7
+ - **One hook, one file** — each hook lives in its own module with a single, focused responsibility.
8
+ - **Stable references** — actions and callbacks are memoised via `useCallback` / `useRef` to prevent unnecessary consumer re-renders.
9
+ - **SSR-safe** — `useSafeLayoutEffect` guards `useLayoutEffect` behind a runtime check; other hooks use only `useEffect`.
10
+ - **Shared timer** — `useTick` multiplexes all subscribers through a single `GlobalTimer` singleton, avoiding per-hook intervals.
11
+ - **Minimal dependencies** — only `eventemitter3` and `@liberfi.io/utils` at runtime; throttle is implemented internally.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pnpm add @liberfi.io/hooks
17
+ ```
18
+
19
+ ### Peer dependencies
20
+
21
+ The consumer must provide:
22
+
23
+ | Package | Version |
24
+ | ------- | ------- |
25
+ | `react` | `>=18` |
26
+
27
+ ## API Reference
28
+
29
+ ### Hooks
30
+
31
+ #### `useBoolean`
32
+
33
+ Manage a boolean state with convenience setters.
34
+
35
+ ```typescript
36
+ function useBoolean(initialValue?: boolean): UseBooleanReturn;
37
+
38
+ type UseBooleanReturn = [
39
+ boolean,
40
+ { setTrue: () => void; setFalse: () => void; toggle: () => void },
41
+ ];
42
+ ```
43
+
44
+ #### `useCallbackRef`
45
+
46
+ Persist a callback reference that always points to the latest function, while returning a stable callable.
47
+
48
+ ```typescript
49
+ function useCallbackRef<T extends (...args: any[]) => any>(
50
+ fn: T | undefined,
51
+ deps?: React.DependencyList,
52
+ ): T;
53
+ ```
54
+
55
+ #### `useIsMounted`
56
+
57
+ Returns a function that reports whether the component is currently mounted.
58
+
59
+ ```typescript
60
+ function useIsMounted(): () => boolean;
61
+ ```
62
+
63
+ #### `useValueRef`
64
+
65
+ Returns a ref that always reflects the latest value (updated synchronously on render).
66
+
67
+ ```typescript
68
+ function useValueRef<T>(value: T): RefObject<T>;
69
+ ```
70
+
71
+ #### `useSafeLayoutEffect`
72
+
73
+ `useLayoutEffect` in the browser, `useEffect` on the server. Drop-in replacement to suppress SSR warnings.
74
+
75
+ ```typescript
76
+ const useSafeLayoutEffect: typeof useLayoutEffect;
77
+ ```
78
+
79
+ #### `useTick`
80
+
81
+ Calls a callback at a specified interval, powered by a shared `GlobalTimer` singleton.
82
+
83
+ ```typescript
84
+ function useTick(callback: TickCallback, interval?: number): void;
85
+
86
+ type TickEvent = { delta: number; now: number };
87
+ type TickCallback = (event: TickEvent) => void;
88
+ ```
89
+
90
+ | Parameter | Type | Default | Description |
91
+ | ---------- | -------------- | ------- | -------------------------------------- |
92
+ | `callback` | `TickCallback` | — | Called each tick with `{ delta, now }` |
93
+ | `interval` | `number` | `1000` | Milliseconds between ticks |
94
+
95
+ #### `useTickAge`
96
+
97
+ Returns the elapsed milliseconds since a given birthday, updated every tick.
98
+
99
+ ```typescript
100
+ function useTickAge(birthday?: number | Date, interval?: number): number;
101
+ ```
102
+
103
+ | Parameter | Type | Default | Description |
104
+ | ---------- | ---------------- | ------------ | ------------------- |
105
+ | `birthday` | `number \| Date` | `Date.now()` | Reference timestamp |
106
+ | `interval` | `number` | `1000` | Tick interval in ms |
107
+
108
+ #### `useResizeObserver`
109
+
110
+ Observes an element's size via the `ResizeObserver` API.
111
+
112
+ ```typescript
113
+ function useResizeObserver<T extends HTMLElement>(
114
+ options: UseResizeObserverOptions<T>,
115
+ ): Size;
116
+ ```
117
+
118
+ When `onResize` is provided, the hook delegates to it instead of updating internal state (no re-renders).
119
+
120
+ #### `useThrottledResizeObserver`
121
+
122
+ Throttled variant of `useResizeObserver`.
123
+
124
+ ```typescript
125
+ function useThrottledResizeObserver<T extends HTMLElement>(
126
+ options: UseThrottledResizeObserverOptions<T>,
127
+ ): Size;
128
+ ```
129
+
130
+ #### `useEventEmitter`
131
+
132
+ Returns a global `EventEmitter` singleton (from `eventemitter3`) managed by an internal DI container.
133
+
134
+ ```typescript
135
+ function useEventEmitter(): EventEmitter;
136
+ ```
137
+
138
+ ### Types
139
+
140
+ | Type | Description |
141
+ | -------------------------------------- | ----------------------------------------------------------------------------------- |
142
+ | `UseBooleanReturn` | Return type of `useBoolean` |
143
+ | `Size` | `{ width: number \| undefined; height: number \| undefined }` |
144
+ | `UseResizeObserverOptions<T>` | Options for `useResizeObserver`: `ref`, `onResize?`, `box?` |
145
+ | `UseThrottledResizeObserverOptions<T>` | Options for `useThrottledResizeObserver`: `ref`, `box?`, `throttleMs?` (default 50) |
146
+ | `TickEvent` | Tick payload: `{ delta: number; now: number }` |
147
+ | `TickCallback` | `(event: TickEvent) => void` |
148
+
149
+ ### Constants
150
+
151
+ | Name | Type | Description |
152
+ | --------- | -------- | ------------------------------------ |
153
+ | `version` | `string` | Current package version (`"0.1.24"`) |
154
+
155
+ ## Usage Examples
156
+
157
+ ### Basic boolean toggle
158
+
159
+ ```tsx
160
+ import { useBoolean } from "@liberfi.io/hooks";
161
+
162
+ function Panel() {
163
+ const [isOpen, { toggle, setFalse }] = useBoolean(false);
164
+ return (
165
+ <div>
166
+ <button onClick={toggle}>Toggle</button>
167
+ {isOpen && <div onClose={setFalse}>Content</div>}
168
+ </div>
169
+ );
170
+ }
171
+ ```
172
+
173
+ ### Periodic countdown
174
+
175
+ ```tsx
176
+ import { useTickAge } from "@liberfi.io/hooks";
177
+
178
+ function Timer({ startedAt }: { startedAt: number }) {
179
+ const elapsed = useTickAge(startedAt, 1000);
180
+ const seconds = Math.floor(elapsed / 1000);
181
+ return <span>{seconds}s elapsed</span>;
182
+ }
183
+ ```
184
+
185
+ ### Resize-aware component
186
+
187
+ ```tsx
188
+ import { useRef } from "react";
189
+ import { useResizeObserver } from "@liberfi.io/hooks";
190
+
191
+ function Card() {
192
+ const ref = useRef<HTMLDivElement>(null);
193
+ const { width = 0 } = useResizeObserver({ ref });
194
+ return <div ref={ref}>{width > 600 ? <WideLayout /> : <NarrowLayout />}</div>;
195
+ }
196
+ ```
197
+
198
+ ### Cross-component event bus
199
+
200
+ ```tsx
201
+ import { useEffect } from "react";
202
+ import { useEventEmitter } from "@liberfi.io/hooks";
203
+
204
+ function Sender() {
205
+ const ee = useEventEmitter();
206
+ return <button onClick={() => ee.emit("refresh")}>Refresh</button>;
207
+ }
208
+
209
+ function Receiver() {
210
+ const ee = useEventEmitter();
211
+ useEffect(() => {
212
+ const handler = () => console.log("refreshed");
213
+ ee.on("refresh", handler);
214
+ return () => {
215
+ ee.off("refresh", handler);
216
+ };
217
+ }, [ee]);
218
+ return null;
219
+ }
220
+ ```
221
+
222
+ ## Future Improvements
223
+
224
+ - Evaluate whether `version.ts` top-level side effect should be lazy-initialised.
package/dist/index.d.mts CHANGED
@@ -8,7 +8,7 @@ declare global {
8
8
  };
9
9
  }
10
10
  }
11
- declare const _default: "0.1.24";
11
+ declare const _default: "0.1.25";
12
12
 
13
13
  type UseBooleanReturn = [
14
14
  /** current state */
@@ -48,7 +48,7 @@ declare function useCallbackRef<T extends (...args: any[]) => any>(fn: T | undef
48
48
  declare function useIsMounted(): () => boolean;
49
49
 
50
50
  /** The size of the observed element. */
51
- type Size$1 = {
51
+ type Size = {
52
52
  /** The width of the observed element. */
53
53
  width: number | undefined;
54
54
  /** The height of the observed element. */
@@ -62,7 +62,7 @@ type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {
62
62
  * When using `onResize`, the hook doesn't re-render on element size changes; it delegates handling to the provided callback.
63
63
  * @default undefined
64
64
  */
65
- onResize?: (size: Size$1) => void;
65
+ onResize?: (size: Size) => void;
66
66
  /**
67
67
  * The box model to use for the ResizeObserver.
68
68
  * @default 'content-box'
@@ -84,7 +84,7 @@ type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {
84
84
  * <div ref={myRef}>Hello, world!</div>
85
85
  * ```
86
86
  */
87
- declare function useResizeObserver<T extends HTMLElement = HTMLElement>(options: UseResizeObserverOptions<T>): Size$1;
87
+ declare function useResizeObserver<T extends HTMLElement = HTMLElement>(options: UseResizeObserverOptions<T>): Size;
88
88
 
89
89
  declare const useSafeLayoutEffect: typeof useLayoutEffect;
90
90
 
@@ -95,7 +95,6 @@ type TickEvent = {
95
95
  now: number;
96
96
  };
97
97
  type TickCallback = (event: TickEvent) => void;
98
- type UnsubscribeTick = () => void;
99
98
  /**
100
99
  * Hook to call a callback at specified interval
101
100
  * @param callback Function to call at specified interval
@@ -117,13 +116,6 @@ declare function useTickAge(birthday?: number | Date, interval?: number): number
117
116
  */
118
117
  declare function useValueRef<T>(value: T): RefObject<T>;
119
118
 
120
- /** The size of the observed element. */
121
- type Size = {
122
- /** The width of the observed element. */
123
- width: number | undefined;
124
- /** The height of the observed element. */
125
- height: number | undefined;
126
- };
127
119
  type UseThrottledResizeObserverOptions<T extends HTMLElement = HTMLElement> = Pick<UseResizeObserverOptions<T>, "ref" | "box"> & {
128
120
  throttleMs?: number;
129
121
  };
@@ -131,4 +123,4 @@ declare function useThrottledResizeObserver<T extends HTMLElement = HTMLElement>
131
123
 
132
124
  declare const useEventEmitter: () => EventEmitter<string | symbol, any>;
133
125
 
134
- export { type TickCallback, type TickEvent, type UnsubscribeTick, type UseBooleanReturn, type UseResizeObserverOptions, type UseThrottledResizeObserverOptions, useBoolean, useCallbackRef, useEventEmitter, useIsMounted, useResizeObserver, useSafeLayoutEffect, useThrottledResizeObserver, useTick, useTickAge, useValueRef, _default as version };
126
+ export { type Size, type TickCallback, type TickEvent, type UseBooleanReturn, type UseResizeObserverOptions, type UseThrottledResizeObserverOptions, useBoolean, useCallbackRef, useEventEmitter, useIsMounted, useResizeObserver, useSafeLayoutEffect, useThrottledResizeObserver, useTick, useTickAge, useValueRef, _default as version };
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ declare global {
8
8
  };
9
9
  }
10
10
  }
11
- declare const _default: "0.1.24";
11
+ declare const _default: "0.1.25";
12
12
 
13
13
  type UseBooleanReturn = [
14
14
  /** current state */
@@ -48,7 +48,7 @@ declare function useCallbackRef<T extends (...args: any[]) => any>(fn: T | undef
48
48
  declare function useIsMounted(): () => boolean;
49
49
 
50
50
  /** The size of the observed element. */
51
- type Size$1 = {
51
+ type Size = {
52
52
  /** The width of the observed element. */
53
53
  width: number | undefined;
54
54
  /** The height of the observed element. */
@@ -62,7 +62,7 @@ type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {
62
62
  * When using `onResize`, the hook doesn't re-render on element size changes; it delegates handling to the provided callback.
63
63
  * @default undefined
64
64
  */
65
- onResize?: (size: Size$1) => void;
65
+ onResize?: (size: Size) => void;
66
66
  /**
67
67
  * The box model to use for the ResizeObserver.
68
68
  * @default 'content-box'
@@ -84,7 +84,7 @@ type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {
84
84
  * <div ref={myRef}>Hello, world!</div>
85
85
  * ```
86
86
  */
87
- declare function useResizeObserver<T extends HTMLElement = HTMLElement>(options: UseResizeObserverOptions<T>): Size$1;
87
+ declare function useResizeObserver<T extends HTMLElement = HTMLElement>(options: UseResizeObserverOptions<T>): Size;
88
88
 
89
89
  declare const useSafeLayoutEffect: typeof useLayoutEffect;
90
90
 
@@ -95,7 +95,6 @@ type TickEvent = {
95
95
  now: number;
96
96
  };
97
97
  type TickCallback = (event: TickEvent) => void;
98
- type UnsubscribeTick = () => void;
99
98
  /**
100
99
  * Hook to call a callback at specified interval
101
100
  * @param callback Function to call at specified interval
@@ -117,13 +116,6 @@ declare function useTickAge(birthday?: number | Date, interval?: number): number
117
116
  */
118
117
  declare function useValueRef<T>(value: T): RefObject<T>;
119
118
 
120
- /** The size of the observed element. */
121
- type Size = {
122
- /** The width of the observed element. */
123
- width: number | undefined;
124
- /** The height of the observed element. */
125
- height: number | undefined;
126
- };
127
119
  type UseThrottledResizeObserverOptions<T extends HTMLElement = HTMLElement> = Pick<UseResizeObserverOptions<T>, "ref" | "box"> & {
128
120
  throttleMs?: number;
129
121
  };
@@ -131,4 +123,4 @@ declare function useThrottledResizeObserver<T extends HTMLElement = HTMLElement>
131
123
 
132
124
  declare const useEventEmitter: () => EventEmitter<string | symbol, any>;
133
125
 
134
- export { type TickCallback, type TickEvent, type UnsubscribeTick, type UseBooleanReturn, type UseResizeObserverOptions, type UseThrottledResizeObserverOptions, useBoolean, useCallbackRef, useEventEmitter, useIsMounted, useResizeObserver, useSafeLayoutEffect, useThrottledResizeObserver, useTick, useTickAge, useValueRef, _default as version };
126
+ export { type Size, type TickCallback, type TickEvent, type UseBooleanReturn, type UseResizeObserverOptions, type UseThrottledResizeObserverOptions, useBoolean, useCallbackRef, useEventEmitter, useIsMounted, useResizeObserver, useSafeLayoutEffect, useThrottledResizeObserver, useTick, useTickAge, useValueRef, _default as version };
package/dist/index.js CHANGED
@@ -1,15 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
- var lodashEs = require('lodash-es');
5
4
  var EventEmitter = require('eventemitter3');
6
- var useConstant = require('use-constant');
7
- var utils = require('@liberfi.io/utils');
8
5
 
9
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
7
 
11
8
  var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
12
- var useConstant__default = /*#__PURE__*/_interopDefault(useConstant);
13
9
 
14
10
  var __defProp = Object.defineProperty;
15
11
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -18,9 +14,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
18
14
  // src/version.ts
19
15
  if (typeof window !== "undefined") {
20
16
  window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};
21
- window.__LIBERFI_VERSION__["@liberfi.io/hooks"] = "0.1.24";
17
+ window.__LIBERFI_VERSION__["@liberfi.io/hooks"] = "0.1.25";
22
18
  }
23
- var version_default = "0.1.24";
19
+ var version_default = "0.1.25";
24
20
  var useBoolean = (initialValue = false) => {
25
21
  const [value, setValue] = react.useState(initialValue);
26
22
  const setTrue = react.useCallback(() => setValue(true), []);
@@ -194,6 +190,40 @@ function useValueRef(value) {
194
190
  valueRef.current = value;
195
191
  return valueRef;
196
192
  }
193
+
194
+ // src/internal/throttle.ts
195
+ function throttle(fn, wait) {
196
+ let lastCallTime = 0;
197
+ let timeoutId = null;
198
+ let lastArgs = null;
199
+ const throttled = (...args) => {
200
+ const now = Date.now();
201
+ const remaining = wait - (now - lastCallTime);
202
+ if (remaining <= 0) {
203
+ if (timeoutId !== null) {
204
+ clearTimeout(timeoutId);
205
+ timeoutId = null;
206
+ }
207
+ lastCallTime = now;
208
+ fn(...args);
209
+ } else {
210
+ lastArgs = args;
211
+ if (timeoutId === null) {
212
+ timeoutId = setTimeout(() => {
213
+ lastCallTime = Date.now();
214
+ timeoutId = null;
215
+ if (lastArgs) {
216
+ fn(...lastArgs);
217
+ lastArgs = null;
218
+ }
219
+ }, remaining);
220
+ }
221
+ }
222
+ };
223
+ return throttled;
224
+ }
225
+
226
+ // src/useThrottledResizeObserver.ts
197
227
  function useThrottledResizeObserver(options) {
198
228
  const { ref, box, throttleMs = 50 } = options;
199
229
  const [size, setSize] = react.useState({
@@ -201,7 +231,7 @@ function useThrottledResizeObserver(options) {
201
231
  height: void 0
202
232
  });
203
233
  const onResize = react.useMemo(
204
- () => lodashEs.throttle(setSize, throttleMs, { leading: true, trailing: true }),
234
+ () => throttle(setSize, throttleMs),
205
235
  [throttleMs, setSize]
206
236
  );
207
237
  useResizeObserver({ ref, box, onResize });
@@ -238,6 +268,11 @@ var Container = class {
238
268
  add(service) {
239
269
  return this.addByName(service.constructor.name, service);
240
270
  }
271
+ /**
272
+ * Stores the service under three keys — original, lowercase, and uppercase —
273
+ * so that callers can retrieve it case-insensitively (e.g. "EE", "ee", "Ee"
274
+ * all resolve to the same instance).
275
+ */
241
276
  addByName(name, service) {
242
277
  this.services[name] = service;
243
278
  this.services[name.toLowerCase()] = service;
@@ -246,11 +281,28 @@ var Container = class {
246
281
  }
247
282
  };
248
283
 
284
+ // src/internal/di/getGlobalObject.ts
285
+ var getGlobalObject = () => {
286
+ if (typeof globalThis !== "undefined") {
287
+ return globalThis;
288
+ }
289
+ if (typeof self !== "undefined") {
290
+ return self;
291
+ }
292
+ if (typeof window !== "undefined") {
293
+ return window;
294
+ }
295
+ if (typeof global !== "undefined") {
296
+ return global;
297
+ }
298
+ throw new Error("cannot find the global object");
299
+ };
300
+
249
301
  // src/internal/di/simpleDI.ts
250
302
  var _SimpleDI = class _SimpleDI {
251
303
  static getContainer() {
252
304
  if (!_SimpleDI.container) {
253
- utils.getGlobalObject()[_SimpleDI.KEY] = _SimpleDI.container = new Container();
305
+ getGlobalObject()[_SimpleDI.KEY] = _SimpleDI.container = new Container();
254
306
  }
255
307
  return _SimpleDI.container;
256
308
  }
@@ -273,23 +325,35 @@ var _SimpleDI = class _SimpleDI {
273
325
  static getAll() {
274
326
  return _SimpleDI.getContainer().getAll();
275
327
  }
328
+ /**
329
+ * Reset the global container, removing all registered services.
330
+ * Primarily used in test teardown to ensure isolation between suites.
331
+ */
332
+ static reset() {
333
+ if (_SimpleDI.container) {
334
+ _SimpleDI.container = null;
335
+ delete getGlobalObject()[_SimpleDI.KEY];
336
+ }
337
+ }
276
338
  constructor() {
277
339
  }
278
340
  };
279
341
  __publicField(_SimpleDI, "KEY", "__LIBERFI_CONTAINER__");
280
- __publicField(_SimpleDI, "container", utils.getGlobalObject()[_SimpleDI.KEY] || null);
342
+ __publicField(_SimpleDI, "container", getGlobalObject()[_SimpleDI.KEY] || null);
281
343
  var SimpleDI = _SimpleDI;
282
344
 
283
345
  // src/useEventEmitter.ts
284
346
  var useEventEmitter = () => {
285
- return useConstant__default.default(() => {
347
+ const ref = react.useRef(null);
348
+ if (ref.current === null) {
286
349
  let ee = SimpleDI.get("EE");
287
350
  if (!ee) {
288
351
  ee = new EventEmitter__default.default();
289
352
  SimpleDI.registerByName("EE", ee);
290
353
  }
291
- return ee;
292
- });
354
+ ref.current = ee;
355
+ }
356
+ return ref.current;
293
357
  };
294
358
 
295
359
  exports.useBoolean = useBoolean;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts","../src/useBoolean.ts","../src/useSafeLayoutEffect.ts","../src/useCallbackRef.ts","../src/useIsMounted.ts","../src/useResizeObserver.ts","../src/useTick.ts","../src/useTickAge.ts","../src/useValueRef.ts","../src/useThrottledResizeObserver.ts","../src/internal/di/container.ts","../src/internal/di/simpleDI.ts","../src/useEventEmitter.ts"],"names":["useState","useCallback","useLayoutEffect","useEffect","useRef","useMemo","throttle","getGlobalObject","useConstant","EventEmitter"],"mappings":"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","file":"index.js","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/hooks\"] = \"0.1.24\";\n}\n\nexport default \"0.1.24\";\n","import { useCallback, useState } from \"react\";\n\nexport type UseBooleanReturn = [\n /** current state */\n boolean,\n {\n /** set state to true */\n setTrue: () => void;\n /** set state to false */\n setFalse: () => void;\n /** toggle state */\n toggle: () => void;\n },\n];\n\n/**\n * Hook to manage a boolean state\n * @param initialValue Initial value of the boolean\n * @returns\n */\nexport const useBoolean = (initialValue = false): UseBooleanReturn => {\n const [value, setValue] = useState(initialValue);\n const setTrue = useCallback(() => setValue(true), []);\n const setFalse = useCallback(() => setValue(false), []);\n const toggle = useCallback(() => setValue((v) => !v), []);\n return [value, { setTrue, setFalse, toggle }];\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\nexport const useSafeLayoutEffect = globalThis?.document\n ? useLayoutEffect\n : useEffect;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Part of this code is taken from @chakra-ui/system ❤️\n */\nimport { useCallback, useRef } from \"react\";\nimport { useSafeLayoutEffect } from \"./useSafeLayoutEffect\";\n\n/**\n * React hook to persist any value between renders,\n * but keeps it up-to-date if it changes.\n * @param fn the function to persist\n * @param deps the function dependency list\n */\nexport function useCallbackRef<T extends (...args: any[]) => any>(\n fn: T | undefined,\n deps: React.DependencyList = [],\n): T {\n const ref = useRef(fn);\n\n useSafeLayoutEffect(() => {\n ref.current = fn;\n });\n\n return useCallback(((...args) => ref.current?.(...args)) as T, deps);\n}\n","import { useCallback, useEffect, useRef } from \"react\";\n\n/**\n * Custom hook that determines if the component is currently mounted.\n * @example\n * ```tsx\n * const isComponentMounted = useIsMounted();\n * // Use isComponentMounted() to check if the component is currently mounted before performing certain actions.\n * ```\n */\nexport function useIsMounted(): () => boolean {\n const isMounted = useRef(false);\n\n useEffect(() => {\n isMounted.current = true;\n\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n return useCallback(() => isMounted.current, []);\n}\n","import type { RefObject } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useIsMounted } from \"./useIsMounted\";\n\n/** The size of the observed element. */\ntype Size = {\n /** The width of the observed element. */\n width: number | undefined;\n /** The height of the observed element. */\n height: number | undefined;\n};\n\n/** The options for the ResizeObserver. */\nexport type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {\n /** The ref of the element to observe. */\n ref: RefObject<T | null>;\n /**\n * When using `onResize`, the hook doesn't re-render on element size changes; it delegates handling to the provided callback.\n * @default undefined\n */\n onResize?: (size: Size) => void;\n /**\n * The box model to use for the ResizeObserver.\n * @default 'content-box'\n */\n box?: \"border-box\" | \"content-box\" | \"device-pixel-content-box\";\n};\n\nconst initialSize: Size = {\n width: undefined,\n height: undefined,\n};\n\n/**\n * Custom hook that observes the size of an element using the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n * @template T - The type of the element to observe.\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-resize-observer)\n * @example\n * ```tsx\n * const myRef = useRef(null);\n * const { width = 0, height = 0 } = useResizeObserver({\n * ref: myRef,\n * box: 'content-box',\n * });\n *\n * <div ref={myRef}>Hello, world!</div>\n * ```\n */\nexport function useResizeObserver<T extends HTMLElement = HTMLElement>(\n options: UseResizeObserverOptions<T>,\n): Size {\n const { ref, box = \"content-box\" } = options;\n const [{ width, height }, setSize] = useState<Size>(initialSize);\n const isMounted = useIsMounted();\n const previousSize = useRef<Size>({ ...initialSize });\n const onResize = useRef<((size: Size) => void) | undefined>(undefined);\n onResize.current = options.onResize;\n\n useEffect(() => {\n if (!ref.current) return;\n\n if (typeof window === \"undefined\" || !(\"ResizeObserver\" in window)) return;\n\n const observer = new ResizeObserver(([entry]) => {\n const boxProp =\n box === \"border-box\"\n ? \"borderBoxSize\"\n : box === \"device-pixel-content-box\"\n ? \"devicePixelContentBoxSize\"\n : \"contentBoxSize\";\n\n const newWidth = extractSize(entry, boxProp, \"inlineSize\");\n const newHeight = extractSize(entry, boxProp, \"blockSize\");\n\n const hasChanged =\n previousSize.current.width !== newWidth ||\n previousSize.current.height !== newHeight;\n\n if (hasChanged) {\n const newSize: Size = { width: newWidth, height: newHeight };\n previousSize.current.width = newWidth;\n previousSize.current.height = newHeight;\n\n if (onResize.current) {\n onResize.current(newSize);\n } else {\n if (isMounted()) {\n setSize(newSize);\n }\n }\n }\n });\n\n observer.observe(ref.current, { box });\n\n return () => {\n observer.disconnect();\n };\n }, [box, ref, isMounted]);\n\n return { width, height };\n}\n\ntype BoxSizesKey = keyof Pick<\n ResizeObserverEntry,\n \"borderBoxSize\" | \"contentBoxSize\" | \"devicePixelContentBoxSize\"\n>;\n\nfunction extractSize(\n entry: ResizeObserverEntry,\n box: BoxSizesKey,\n sizeType: keyof ResizeObserverSize,\n): number | undefined {\n if (!entry[box]) {\n if (box === \"contentBoxSize\") {\n return entry.contentRect[sizeType === \"inlineSize\" ? \"width\" : \"height\"];\n }\n return undefined;\n }\n const boxSize = (\n Array.isArray(entry[box]) ? entry[box][0] : entry[box]\n ) as ResizeObserverSize;\n return boxSize[sizeType];\n}\n","import { useEffect } from \"react\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\nexport type TickEvent = {\n /** delta time in milliseconds since last tick */\n delta: number;\n /** current timestamp in milliseconds */\n now: number;\n};\n\nexport type TickCallback = (event: TickEvent) => void;\n\nexport type UnsubscribeTick = () => void;\n\ntype TickSubscription = {\n /** interval in milliseconds to execute the callback */\n interval: number;\n /** last executed timestamp in milliseconds */\n lastExecuted: number;\n};\n\n/**\n * Global timer singleton using setTimeout for better performance\n */\nclass GlobalTimer {\n /** singleton instance */\n private static instance: GlobalTimer;\n\n /** setTimeout id */\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n /** subscription map */\n private subscribers: Map<TickCallback, TickSubscription> = new Map();\n\n /** is timer running */\n private isRunning = false;\n\n /** internal update interval for smoothness */\n private readonly internalInterval = 200;\n\n /**\n * Get the singleton instance of the timer\n * @returns Timer instance\n */\n static getInstance(): GlobalTimer {\n if (!GlobalTimer.instance) {\n GlobalTimer.instance = new GlobalTimer();\n }\n return GlobalTimer.instance;\n }\n\n /**\n * Subscribe to the timer\n * @param callback tick callback\n * @param interval interval in milliseconds to execute the callback\n * @returns unsubscribe function\n */\n subscribe(callback: TickCallback, interval: number = 1000): UnsubscribeTick {\n this.subscribers.set(callback, {\n interval,\n lastExecuted: Date.now(),\n });\n\n // start timer if this is the first subscriber\n if (!this.isRunning) {\n this.start();\n }\n\n // return unsubscribe function\n return () => {\n this.subscribers.delete(callback);\n // stop timer if no more subscribers\n if (this.subscribers.size === 0) {\n this.stop();\n }\n };\n }\n\n private start(): void {\n if (this.isRunning) return;\n this.isRunning = true;\n this.scheduleNext();\n }\n\n private scheduleNext(): void {\n this.timeoutId = setTimeout(() => {\n const now = Date.now();\n\n // check each subscriber and execute if their interval has passed\n this.subscribers.forEach((config, callback) => {\n if (now - config.lastExecuted >= config.interval) {\n callback({ delta: now - config.lastExecuted, now });\n config.lastExecuted = now;\n }\n });\n\n // schedule next tick if still running\n if (this.isRunning) {\n this.scheduleNext();\n }\n }, this.internalInterval);\n }\n\n private stop(): void {\n this.isRunning = false;\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n}\n\n/**\n * Hook to call a callback at specified interval\n * @param callback Function to call at specified interval\n * @param interval Interval in milliseconds (default: 1000ms)\n * @returns\n */\nexport function useTick(callback: TickCallback, interval: number = 1000) {\n const callbackRef = useCallbackRef(callback);\n useEffect(\n () => GlobalTimer.getInstance().subscribe(callbackRef, interval),\n [interval],\n );\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { TickEvent, useTick } from \"./useTick\";\n\n/**\n * Hook to get the age in milliseconds since birthday in every tick\n * @param birthday Timestamp in milliseconds or Date object (default: now)\n * @param interval Tick interval in milliseconds (default: 1000ms)\n * @returns age in milliseconds since birthday\n */\nexport function useTickAge(\n birthday: number | Date = Date.now(),\n interval: number = 1000,\n) {\n const birthdayRef = useRef(\n birthday instanceof Date ? birthday.getTime() : birthday,\n );\n // keep ref updated\n birthdayRef.current =\n birthday instanceof Date ? birthday.getTime() : birthday;\n\n const [age, setAge] = useState(Math.max(0, Date.now() - birthdayRef.current));\n\n const tickAge = useCallback(\n ({ now }: TickEvent) => setAge(Math.max(0, now - birthdayRef.current)),\n [],\n );\n\n useTick(tickAge, interval);\n\n return age;\n}\n","import { RefObject, useRef } from \"react\";\n\n/**\n * Returns an always updated ref to value\n */\nexport function useValueRef<T>(value: T): RefObject<T> {\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n return valueRef;\n}\n","import { useMemo, useState } from \"react\";\nimport { throttle } from \"lodash-es\";\nimport { useResizeObserver } from \"./useResizeObserver\";\nimport type { UseResizeObserverOptions } from \"./useResizeObserver\";\n\n/** The size of the observed element. */\ntype Size = {\n /** The width of the observed element. */\n width: number | undefined;\n /** The height of the observed element. */\n height: number | undefined;\n};\n\nexport type UseThrottledResizeObserverOptions<\n T extends HTMLElement = HTMLElement,\n> = Pick<UseResizeObserverOptions<T>, \"ref\" | \"box\"> & {\n throttleMs?: number;\n};\n\nexport function useThrottledResizeObserver<T extends HTMLElement = HTMLElement>(\n options: UseThrottledResizeObserverOptions<T>,\n): Size {\n const { ref, box, throttleMs = 50 } = options;\n\n const [size, setSize] = useState<Size>({\n width: undefined,\n height: undefined,\n });\n\n const onResize = useMemo(\n () => throttle(setSize, throttleMs, { leading: true, trailing: true }),\n [throttleMs, setSize],\n );\n\n useResizeObserver({ ref, box, onResize });\n\n return size;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class Container {\n public constructor(private services: { [name: string]: any } = {}) {}\n\n register(...serviceClasses: any[]): void {\n serviceClasses.forEach((serviceClass) => {\n let service = serviceClass;\n if (service instanceof Function) {\n service = new serviceClass();\n }\n this.add(service);\n });\n }\n\n registerByName(name: string, serviceClass: any): void {\n let service = serviceClass;\n if (service instanceof Function) {\n service = new serviceClass();\n }\n this.addByName(name, service);\n }\n\n get<T = any>(name: string): T {\n return this.services[name];\n }\n\n getAll(): { [name: string]: any } {\n return Object.assign({}, this.services);\n }\n\n private add(service: any): any {\n return this.addByName(service.constructor.name, service);\n }\n\n private addByName(name: string, service: any): any {\n this.services[name] = service;\n this.services[name.toLowerCase()] = service;\n this.services[name.toUpperCase()] = service;\n return this.get(name);\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { getGlobalObject } from \"@liberfi.io/utils\";\nimport { Container } from \"./container\";\n\n/**\n * Global Dependency Injection Container\n */\nexport class SimpleDI {\n private static KEY = \"__LIBERFI_CONTAINER__\";\n private static container: Container =\n (getGlobalObject() as any)[SimpleDI.KEY] || null;\n\n private static getContainer(): Container {\n if (!SimpleDI.container) {\n (getGlobalObject() as any)[SimpleDI.KEY] = SimpleDI.container =\n new Container();\n }\n return SimpleDI.container;\n }\n\n static register(...serviceClasses: any[]): void {\n SimpleDI.getContainer().register(...serviceClasses);\n }\n\n static registerByName(name: string, serviceClass: any): void {\n SimpleDI.getContainer().registerByName(name, serviceClass);\n }\n\n static get<T = any>(name: string): T {\n return SimpleDI.getContainer().get<T>(name);\n }\n\n static getOr<T = any>(name: string, instance: T): T {\n const s = SimpleDI.getContainer().get<T>(name);\n if (!s) {\n SimpleDI.registerByName(name, instance);\n }\n return instance;\n }\n\n static getAll(): { [name: string]: any } {\n return SimpleDI.getContainer().getAll();\n }\n\n private constructor() {}\n}\n","import EventEmitter from \"eventemitter3\";\nimport useConstant from \"use-constant\";\nimport { SimpleDI } from \"./internal/di\";\n\nexport const useEventEmitter = () => {\n return useConstant(() => {\n let ee = SimpleDI.get<EventEmitter>(\"EE\");\n if (!ee) {\n ee = new EventEmitter();\n SimpleDI.registerByName(\"EE\", ee);\n }\n return ee;\n });\n};\n"]}
1
+ {"version":3,"sources":["../src/version.ts","../src/useBoolean.ts","../src/useSafeLayoutEffect.ts","../src/useCallbackRef.ts","../src/useIsMounted.ts","../src/useResizeObserver.ts","../src/useTick.ts","../src/useTickAge.ts","../src/useValueRef.ts","../src/internal/throttle.ts","../src/useThrottledResizeObserver.ts","../src/internal/di/container.ts","../src/internal/di/getGlobalObject.ts","../src/internal/di/simpleDI.ts","../src/useEventEmitter.ts"],"names":["useState","useCallback","useLayoutEffect","useEffect","useRef","useMemo","EventEmitter"],"mappings":"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","file":"index.js","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/hooks\"] = \"0.1.25\";\n}\n\nexport default \"0.1.25\";\n","import { useCallback, useState } from \"react\";\n\nexport type UseBooleanReturn = [\n /** current state */\n boolean,\n {\n /** set state to true */\n setTrue: () => void;\n /** set state to false */\n setFalse: () => void;\n /** toggle state */\n toggle: () => void;\n },\n];\n\n/**\n * Hook to manage a boolean state\n * @param initialValue Initial value of the boolean\n * @returns\n */\nexport const useBoolean = (initialValue = false): UseBooleanReturn => {\n const [value, setValue] = useState(initialValue);\n const setTrue = useCallback(() => setValue(true), []);\n const setFalse = useCallback(() => setValue(false), []);\n const toggle = useCallback(() => setValue((v) => !v), []);\n return [value, { setTrue, setFalse, toggle }];\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\nexport const useSafeLayoutEffect = globalThis?.document\n ? useLayoutEffect\n : useEffect;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Part of this code is taken from @chakra-ui/system ❤️\n */\nimport { useCallback, useRef } from \"react\";\nimport { useSafeLayoutEffect } from \"./useSafeLayoutEffect\";\n\n/**\n * React hook to persist any value between renders,\n * but keeps it up-to-date if it changes.\n * @param fn the function to persist\n * @param deps the function dependency list\n */\nexport function useCallbackRef<T extends (...args: any[]) => any>(\n fn: T | undefined,\n deps: React.DependencyList = [],\n): T {\n const ref = useRef(fn);\n\n useSafeLayoutEffect(() => {\n ref.current = fn;\n });\n\n return useCallback(((...args) => ref.current?.(...args)) as T, deps);\n}\n","import { useCallback, useEffect, useRef } from \"react\";\n\n/**\n * Custom hook that determines if the component is currently mounted.\n * @example\n * ```tsx\n * const isComponentMounted = useIsMounted();\n * // Use isComponentMounted() to check if the component is currently mounted before performing certain actions.\n * ```\n */\nexport function useIsMounted(): () => boolean {\n const isMounted = useRef(false);\n\n useEffect(() => {\n isMounted.current = true;\n\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n return useCallback(() => isMounted.current, []);\n}\n","import type { RefObject } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useIsMounted } from \"./useIsMounted\";\n\n/** The size of the observed element. */\nexport type Size = {\n /** The width of the observed element. */\n width: number | undefined;\n /** The height of the observed element. */\n height: number | undefined;\n};\n\n/** The options for the ResizeObserver. */\nexport type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {\n /** The ref of the element to observe. */\n ref: RefObject<T | null>;\n /**\n * When using `onResize`, the hook doesn't re-render on element size changes; it delegates handling to the provided callback.\n * @default undefined\n */\n onResize?: (size: Size) => void;\n /**\n * The box model to use for the ResizeObserver.\n * @default 'content-box'\n */\n box?: \"border-box\" | \"content-box\" | \"device-pixel-content-box\";\n};\n\nconst initialSize: Size = {\n width: undefined,\n height: undefined,\n};\n\n/**\n * Custom hook that observes the size of an element using the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n * @template T - The type of the element to observe.\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-resize-observer)\n * @example\n * ```tsx\n * const myRef = useRef(null);\n * const { width = 0, height = 0 } = useResizeObserver({\n * ref: myRef,\n * box: 'content-box',\n * });\n *\n * <div ref={myRef}>Hello, world!</div>\n * ```\n */\nexport function useResizeObserver<T extends HTMLElement = HTMLElement>(\n options: UseResizeObserverOptions<T>,\n): Size {\n const { ref, box = \"content-box\" } = options;\n const [{ width, height }, setSize] = useState<Size>(initialSize);\n const isMounted = useIsMounted();\n const previousSize = useRef<Size>({ ...initialSize });\n const onResize = useRef<((size: Size) => void) | undefined>(undefined);\n onResize.current = options.onResize;\n\n useEffect(() => {\n if (!ref.current) return;\n\n if (typeof window === \"undefined\" || !(\"ResizeObserver\" in window)) return;\n\n const observer = new ResizeObserver(([entry]) => {\n const boxProp =\n box === \"border-box\"\n ? \"borderBoxSize\"\n : box === \"device-pixel-content-box\"\n ? \"devicePixelContentBoxSize\"\n : \"contentBoxSize\";\n\n const newWidth = extractSize(entry, boxProp, \"inlineSize\");\n const newHeight = extractSize(entry, boxProp, \"blockSize\");\n\n const hasChanged =\n previousSize.current.width !== newWidth ||\n previousSize.current.height !== newHeight;\n\n if (hasChanged) {\n const newSize: Size = { width: newWidth, height: newHeight };\n previousSize.current.width = newWidth;\n previousSize.current.height = newHeight;\n\n if (onResize.current) {\n onResize.current(newSize);\n } else {\n if (isMounted()) {\n setSize(newSize);\n }\n }\n }\n });\n\n observer.observe(ref.current, { box });\n\n return () => {\n observer.disconnect();\n };\n }, [box, ref, isMounted]);\n\n return { width, height };\n}\n\ntype BoxSizesKey = keyof Pick<\n ResizeObserverEntry,\n \"borderBoxSize\" | \"contentBoxSize\" | \"devicePixelContentBoxSize\"\n>;\n\nfunction extractSize(\n entry: ResizeObserverEntry,\n box: BoxSizesKey,\n sizeType: keyof ResizeObserverSize,\n): number | undefined {\n if (!entry[box]) {\n if (box === \"contentBoxSize\") {\n return entry.contentRect[sizeType === \"inlineSize\" ? \"width\" : \"height\"];\n }\n return undefined;\n }\n const boxSize = (\n Array.isArray(entry[box]) ? entry[box][0] : entry[box]\n ) as ResizeObserverSize;\n return boxSize[sizeType];\n}\n","import { useEffect } from \"react\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\nexport type TickEvent = {\n /** delta time in milliseconds since last tick */\n delta: number;\n /** current timestamp in milliseconds */\n now: number;\n};\n\nexport type TickCallback = (event: TickEvent) => void;\n\ntype UnsubscribeTick = () => void;\n\ntype TickSubscription = {\n /** interval in milliseconds to execute the callback */\n interval: number;\n /** last executed timestamp in milliseconds */\n lastExecuted: number;\n};\n\n/**\n * Global timer singleton using setTimeout for better performance\n */\nclass GlobalTimer {\n /** singleton instance */\n private static instance: GlobalTimer;\n\n /** setTimeout id */\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n /** subscription map */\n private subscribers: Map<TickCallback, TickSubscription> = new Map();\n\n /** is timer running */\n private isRunning = false;\n\n /** internal update interval for smoothness */\n private readonly internalInterval = 200;\n\n /**\n * Get the singleton instance of the timer\n * @returns Timer instance\n */\n static getInstance(): GlobalTimer {\n if (!GlobalTimer.instance) {\n GlobalTimer.instance = new GlobalTimer();\n }\n return GlobalTimer.instance;\n }\n\n /**\n * Subscribe to the timer\n * @param callback tick callback\n * @param interval interval in milliseconds to execute the callback\n * @returns unsubscribe function\n */\n subscribe(callback: TickCallback, interval: number = 1000): UnsubscribeTick {\n this.subscribers.set(callback, {\n interval,\n lastExecuted: Date.now(),\n });\n\n // start timer if this is the first subscriber\n if (!this.isRunning) {\n this.start();\n }\n\n // return unsubscribe function\n return () => {\n this.subscribers.delete(callback);\n // stop timer if no more subscribers\n if (this.subscribers.size === 0) {\n this.stop();\n }\n };\n }\n\n private start(): void {\n if (this.isRunning) return;\n this.isRunning = true;\n this.scheduleNext();\n }\n\n private scheduleNext(): void {\n this.timeoutId = setTimeout(() => {\n const now = Date.now();\n\n // check each subscriber and execute if their interval has passed\n this.subscribers.forEach((config, callback) => {\n if (now - config.lastExecuted >= config.interval) {\n callback({ delta: now - config.lastExecuted, now });\n config.lastExecuted = now;\n }\n });\n\n // schedule next tick if still running\n if (this.isRunning) {\n this.scheduleNext();\n }\n }, this.internalInterval);\n }\n\n private stop(): void {\n this.isRunning = false;\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n}\n\n/**\n * Hook to call a callback at specified interval\n * @param callback Function to call at specified interval\n * @param interval Interval in milliseconds (default: 1000ms)\n * @returns\n */\nexport function useTick(callback: TickCallback, interval: number = 1000) {\n const callbackRef = useCallbackRef(callback);\n useEffect(\n () => GlobalTimer.getInstance().subscribe(callbackRef, interval),\n [interval],\n );\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { TickEvent, useTick } from \"./useTick\";\n\n/**\n * Hook to get the age in milliseconds since birthday in every tick\n * @param birthday Timestamp in milliseconds or Date object (default: now)\n * @param interval Tick interval in milliseconds (default: 1000ms)\n * @returns age in milliseconds since birthday\n */\nexport function useTickAge(\n birthday: number | Date = Date.now(),\n interval: number = 1000,\n) {\n const birthdayRef = useRef(\n birthday instanceof Date ? birthday.getTime() : birthday,\n );\n // keep ref updated\n birthdayRef.current =\n birthday instanceof Date ? birthday.getTime() : birthday;\n\n const [age, setAge] = useState(Math.max(0, Date.now() - birthdayRef.current));\n\n const tickAge = useCallback(\n ({ now }: TickEvent) => setAge(Math.max(0, now - birthdayRef.current)),\n [],\n );\n\n useTick(tickAge, interval);\n\n return age;\n}\n","import { RefObject, useRef } from \"react\";\n\n/**\n * Returns an always updated ref to value\n */\nexport function useValueRef<T>(value: T): RefObject<T> {\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n return valueRef;\n}\n","/**\n * Minimal throttle with leading + trailing execution.\n * Replaces lodash-es/throttle for the single call-site in this package.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function throttle<T extends (...args: any[]) => void>(\n fn: T,\n wait: number,\n): T {\n let lastCallTime = 0;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n const throttled = (...args: Parameters<T>) => {\n const now = Date.now();\n const remaining = wait - (now - lastCallTime);\n\n if (remaining <= 0) {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n lastCallTime = now;\n fn(...args);\n } else {\n lastArgs = args;\n if (timeoutId === null) {\n timeoutId = setTimeout(() => {\n lastCallTime = Date.now();\n timeoutId = null;\n if (lastArgs) {\n fn(...lastArgs);\n lastArgs = null;\n }\n }, remaining);\n }\n }\n };\n\n return throttled as T;\n}\n","import { useMemo, useState } from \"react\";\nimport { throttle } from \"./internal/throttle\";\nimport { useResizeObserver } from \"./useResizeObserver\";\nimport type { Size, UseResizeObserverOptions } from \"./useResizeObserver\";\n\nexport type UseThrottledResizeObserverOptions<\n T extends HTMLElement = HTMLElement,\n> = Pick<UseResizeObserverOptions<T>, \"ref\" | \"box\"> & {\n throttleMs?: number;\n};\n\nexport function useThrottledResizeObserver<T extends HTMLElement = HTMLElement>(\n options: UseThrottledResizeObserverOptions<T>,\n): Size {\n const { ref, box, throttleMs = 50 } = options;\n\n const [size, setSize] = useState<Size>({\n width: undefined,\n height: undefined,\n });\n\n const onResize = useMemo(\n () => throttle(setSize, throttleMs),\n [throttleMs, setSize],\n );\n\n useResizeObserver({ ref, box, onResize });\n\n return size;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class Container {\n public constructor(private services: { [name: string]: any } = {}) {}\n\n register(...serviceClasses: any[]): void {\n serviceClasses.forEach((serviceClass) => {\n let service = serviceClass;\n if (service instanceof Function) {\n service = new serviceClass();\n }\n this.add(service);\n });\n }\n\n registerByName(name: string, serviceClass: any): void {\n let service = serviceClass;\n if (service instanceof Function) {\n service = new serviceClass();\n }\n this.addByName(name, service);\n }\n\n get<T = any>(name: string): T {\n return this.services[name];\n }\n\n getAll(): { [name: string]: any } {\n return Object.assign({}, this.services);\n }\n\n private add(service: any): any {\n return this.addByName(service.constructor.name, service);\n }\n\n /**\n * Stores the service under three keys — original, lowercase, and uppercase —\n * so that callers can retrieve it case-insensitively (e.g. \"EE\", \"ee\", \"Ee\"\n * all resolve to the same instance).\n */\n private addByName(name: string, service: any): any {\n this.services[name] = service;\n this.services[name.toLowerCase()] = service;\n this.services[name.toUpperCase()] = service;\n return this.get(name);\n }\n}\n","export const getGlobalObject = () => {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n if (typeof self !== \"undefined\") {\n return self;\n }\n if (typeof window !== \"undefined\") {\n return window;\n }\n // @ts-ignore\n if (typeof global !== \"undefined\") {\n // @ts-ignore\n return global;\n }\n throw new Error(\"cannot find the global object\");\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Container } from \"./container\";\nimport { getGlobalObject } from \"./getGlobalObject\";\n\n/**\n * Global Dependency Injection Container\n */\nexport class SimpleDI {\n private static KEY = \"__LIBERFI_CONTAINER__\";\n private static container: Container =\n (getGlobalObject() as any)[SimpleDI.KEY] || null;\n\n private static getContainer(): Container {\n if (!SimpleDI.container) {\n (getGlobalObject() as any)[SimpleDI.KEY] = SimpleDI.container =\n new Container();\n }\n return SimpleDI.container;\n }\n\n static register(...serviceClasses: any[]): void {\n SimpleDI.getContainer().register(...serviceClasses);\n }\n\n static registerByName(name: string, serviceClass: any): void {\n SimpleDI.getContainer().registerByName(name, serviceClass);\n }\n\n static get<T = any>(name: string): T {\n return SimpleDI.getContainer().get<T>(name);\n }\n\n static getOr<T = any>(name: string, instance: T): T {\n const s = SimpleDI.getContainer().get<T>(name);\n if (!s) {\n SimpleDI.registerByName(name, instance);\n }\n return instance;\n }\n\n static getAll(): { [name: string]: any } {\n return SimpleDI.getContainer().getAll();\n }\n\n /**\n * Reset the global container, removing all registered services.\n * Primarily used in test teardown to ensure isolation between suites.\n */\n static reset(): void {\n if (SimpleDI.container) {\n SimpleDI.container = null!;\n delete (getGlobalObject() as any)[SimpleDI.KEY];\n }\n }\n\n private constructor() {}\n}\n","import { useRef } from \"react\";\nimport EventEmitter from \"eventemitter3\";\nimport { SimpleDI } from \"./internal/di\";\n\nexport const useEventEmitter = () => {\n const ref = useRef<EventEmitter | null>(null);\n if (ref.current === null) {\n let ee = SimpleDI.get<EventEmitter>(\"EE\");\n if (!ee) {\n ee = new EventEmitter();\n SimpleDI.registerByName(\"EE\", ee);\n }\n ref.current = ee;\n }\n return ref.current;\n};\n"]}
package/dist/index.mjs CHANGED
@@ -1,8 +1,5 @@
1
1
  import { useLayoutEffect, useEffect, useState, useCallback, useRef, useMemo } from 'react';
2
- import { throttle } from 'lodash-es';
3
2
  import EventEmitter from 'eventemitter3';
4
- import useConstant from 'use-constant';
5
- import { getGlobalObject } from '@liberfi.io/utils';
6
3
 
7
4
  var __defProp = Object.defineProperty;
8
5
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -11,9 +8,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11
8
  // src/version.ts
12
9
  if (typeof window !== "undefined") {
13
10
  window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};
14
- window.__LIBERFI_VERSION__["@liberfi.io/hooks"] = "0.1.24";
11
+ window.__LIBERFI_VERSION__["@liberfi.io/hooks"] = "0.1.25";
15
12
  }
16
- var version_default = "0.1.24";
13
+ var version_default = "0.1.25";
17
14
  var useBoolean = (initialValue = false) => {
18
15
  const [value, setValue] = useState(initialValue);
19
16
  const setTrue = useCallback(() => setValue(true), []);
@@ -187,6 +184,40 @@ function useValueRef(value) {
187
184
  valueRef.current = value;
188
185
  return valueRef;
189
186
  }
187
+
188
+ // src/internal/throttle.ts
189
+ function throttle(fn, wait) {
190
+ let lastCallTime = 0;
191
+ let timeoutId = null;
192
+ let lastArgs = null;
193
+ const throttled = (...args) => {
194
+ const now = Date.now();
195
+ const remaining = wait - (now - lastCallTime);
196
+ if (remaining <= 0) {
197
+ if (timeoutId !== null) {
198
+ clearTimeout(timeoutId);
199
+ timeoutId = null;
200
+ }
201
+ lastCallTime = now;
202
+ fn(...args);
203
+ } else {
204
+ lastArgs = args;
205
+ if (timeoutId === null) {
206
+ timeoutId = setTimeout(() => {
207
+ lastCallTime = Date.now();
208
+ timeoutId = null;
209
+ if (lastArgs) {
210
+ fn(...lastArgs);
211
+ lastArgs = null;
212
+ }
213
+ }, remaining);
214
+ }
215
+ }
216
+ };
217
+ return throttled;
218
+ }
219
+
220
+ // src/useThrottledResizeObserver.ts
190
221
  function useThrottledResizeObserver(options) {
191
222
  const { ref, box, throttleMs = 50 } = options;
192
223
  const [size, setSize] = useState({
@@ -194,7 +225,7 @@ function useThrottledResizeObserver(options) {
194
225
  height: void 0
195
226
  });
196
227
  const onResize = useMemo(
197
- () => throttle(setSize, throttleMs, { leading: true, trailing: true }),
228
+ () => throttle(setSize, throttleMs),
198
229
  [throttleMs, setSize]
199
230
  );
200
231
  useResizeObserver({ ref, box, onResize });
@@ -231,6 +262,11 @@ var Container = class {
231
262
  add(service) {
232
263
  return this.addByName(service.constructor.name, service);
233
264
  }
265
+ /**
266
+ * Stores the service under three keys — original, lowercase, and uppercase —
267
+ * so that callers can retrieve it case-insensitively (e.g. "EE", "ee", "Ee"
268
+ * all resolve to the same instance).
269
+ */
234
270
  addByName(name, service) {
235
271
  this.services[name] = service;
236
272
  this.services[name.toLowerCase()] = service;
@@ -239,6 +275,23 @@ var Container = class {
239
275
  }
240
276
  };
241
277
 
278
+ // src/internal/di/getGlobalObject.ts
279
+ var getGlobalObject = () => {
280
+ if (typeof globalThis !== "undefined") {
281
+ return globalThis;
282
+ }
283
+ if (typeof self !== "undefined") {
284
+ return self;
285
+ }
286
+ if (typeof window !== "undefined") {
287
+ return window;
288
+ }
289
+ if (typeof global !== "undefined") {
290
+ return global;
291
+ }
292
+ throw new Error("cannot find the global object");
293
+ };
294
+
242
295
  // src/internal/di/simpleDI.ts
243
296
  var _SimpleDI = class _SimpleDI {
244
297
  static getContainer() {
@@ -266,6 +319,16 @@ var _SimpleDI = class _SimpleDI {
266
319
  static getAll() {
267
320
  return _SimpleDI.getContainer().getAll();
268
321
  }
322
+ /**
323
+ * Reset the global container, removing all registered services.
324
+ * Primarily used in test teardown to ensure isolation between suites.
325
+ */
326
+ static reset() {
327
+ if (_SimpleDI.container) {
328
+ _SimpleDI.container = null;
329
+ delete getGlobalObject()[_SimpleDI.KEY];
330
+ }
331
+ }
269
332
  constructor() {
270
333
  }
271
334
  };
@@ -275,14 +338,16 @@ var SimpleDI = _SimpleDI;
275
338
 
276
339
  // src/useEventEmitter.ts
277
340
  var useEventEmitter = () => {
278
- return useConstant(() => {
341
+ const ref = useRef(null);
342
+ if (ref.current === null) {
279
343
  let ee = SimpleDI.get("EE");
280
344
  if (!ee) {
281
345
  ee = new EventEmitter();
282
346
  SimpleDI.registerByName("EE", ee);
283
347
  }
284
- return ee;
285
- });
348
+ ref.current = ee;
349
+ }
350
+ return ref.current;
286
351
  };
287
352
 
288
353
  export { useBoolean, useCallbackRef, useEventEmitter, useIsMounted, useResizeObserver, useSafeLayoutEffect, useThrottledResizeObserver, useTick, useTickAge, useValueRef, version_default as version };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts","../src/useBoolean.ts","../src/useSafeLayoutEffect.ts","../src/useCallbackRef.ts","../src/useIsMounted.ts","../src/useResizeObserver.ts","../src/useTick.ts","../src/useTickAge.ts","../src/useValueRef.ts","../src/useThrottledResizeObserver.ts","../src/internal/di/container.ts","../src/internal/di/simpleDI.ts","../src/useEventEmitter.ts"],"names":["useCallback","useRef","useEffect","useState"],"mappings":"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","file":"index.mjs","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/hooks\"] = \"0.1.24\";\n}\n\nexport default \"0.1.24\";\n","import { useCallback, useState } from \"react\";\n\nexport type UseBooleanReturn = [\n /** current state */\n boolean,\n {\n /** set state to true */\n setTrue: () => void;\n /** set state to false */\n setFalse: () => void;\n /** toggle state */\n toggle: () => void;\n },\n];\n\n/**\n * Hook to manage a boolean state\n * @param initialValue Initial value of the boolean\n * @returns\n */\nexport const useBoolean = (initialValue = false): UseBooleanReturn => {\n const [value, setValue] = useState(initialValue);\n const setTrue = useCallback(() => setValue(true), []);\n const setFalse = useCallback(() => setValue(false), []);\n const toggle = useCallback(() => setValue((v) => !v), []);\n return [value, { setTrue, setFalse, toggle }];\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\nexport const useSafeLayoutEffect = globalThis?.document\n ? useLayoutEffect\n : useEffect;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Part of this code is taken from @chakra-ui/system ❤️\n */\nimport { useCallback, useRef } from \"react\";\nimport { useSafeLayoutEffect } from \"./useSafeLayoutEffect\";\n\n/**\n * React hook to persist any value between renders,\n * but keeps it up-to-date if it changes.\n * @param fn the function to persist\n * @param deps the function dependency list\n */\nexport function useCallbackRef<T extends (...args: any[]) => any>(\n fn: T | undefined,\n deps: React.DependencyList = [],\n): T {\n const ref = useRef(fn);\n\n useSafeLayoutEffect(() => {\n ref.current = fn;\n });\n\n return useCallback(((...args) => ref.current?.(...args)) as T, deps);\n}\n","import { useCallback, useEffect, useRef } from \"react\";\n\n/**\n * Custom hook that determines if the component is currently mounted.\n * @example\n * ```tsx\n * const isComponentMounted = useIsMounted();\n * // Use isComponentMounted() to check if the component is currently mounted before performing certain actions.\n * ```\n */\nexport function useIsMounted(): () => boolean {\n const isMounted = useRef(false);\n\n useEffect(() => {\n isMounted.current = true;\n\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n return useCallback(() => isMounted.current, []);\n}\n","import type { RefObject } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useIsMounted } from \"./useIsMounted\";\n\n/** The size of the observed element. */\ntype Size = {\n /** The width of the observed element. */\n width: number | undefined;\n /** The height of the observed element. */\n height: number | undefined;\n};\n\n/** The options for the ResizeObserver. */\nexport type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {\n /** The ref of the element to observe. */\n ref: RefObject<T | null>;\n /**\n * When using `onResize`, the hook doesn't re-render on element size changes; it delegates handling to the provided callback.\n * @default undefined\n */\n onResize?: (size: Size) => void;\n /**\n * The box model to use for the ResizeObserver.\n * @default 'content-box'\n */\n box?: \"border-box\" | \"content-box\" | \"device-pixel-content-box\";\n};\n\nconst initialSize: Size = {\n width: undefined,\n height: undefined,\n};\n\n/**\n * Custom hook that observes the size of an element using the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n * @template T - The type of the element to observe.\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-resize-observer)\n * @example\n * ```tsx\n * const myRef = useRef(null);\n * const { width = 0, height = 0 } = useResizeObserver({\n * ref: myRef,\n * box: 'content-box',\n * });\n *\n * <div ref={myRef}>Hello, world!</div>\n * ```\n */\nexport function useResizeObserver<T extends HTMLElement = HTMLElement>(\n options: UseResizeObserverOptions<T>,\n): Size {\n const { ref, box = \"content-box\" } = options;\n const [{ width, height }, setSize] = useState<Size>(initialSize);\n const isMounted = useIsMounted();\n const previousSize = useRef<Size>({ ...initialSize });\n const onResize = useRef<((size: Size) => void) | undefined>(undefined);\n onResize.current = options.onResize;\n\n useEffect(() => {\n if (!ref.current) return;\n\n if (typeof window === \"undefined\" || !(\"ResizeObserver\" in window)) return;\n\n const observer = new ResizeObserver(([entry]) => {\n const boxProp =\n box === \"border-box\"\n ? \"borderBoxSize\"\n : box === \"device-pixel-content-box\"\n ? \"devicePixelContentBoxSize\"\n : \"contentBoxSize\";\n\n const newWidth = extractSize(entry, boxProp, \"inlineSize\");\n const newHeight = extractSize(entry, boxProp, \"blockSize\");\n\n const hasChanged =\n previousSize.current.width !== newWidth ||\n previousSize.current.height !== newHeight;\n\n if (hasChanged) {\n const newSize: Size = { width: newWidth, height: newHeight };\n previousSize.current.width = newWidth;\n previousSize.current.height = newHeight;\n\n if (onResize.current) {\n onResize.current(newSize);\n } else {\n if (isMounted()) {\n setSize(newSize);\n }\n }\n }\n });\n\n observer.observe(ref.current, { box });\n\n return () => {\n observer.disconnect();\n };\n }, [box, ref, isMounted]);\n\n return { width, height };\n}\n\ntype BoxSizesKey = keyof Pick<\n ResizeObserverEntry,\n \"borderBoxSize\" | \"contentBoxSize\" | \"devicePixelContentBoxSize\"\n>;\n\nfunction extractSize(\n entry: ResizeObserverEntry,\n box: BoxSizesKey,\n sizeType: keyof ResizeObserverSize,\n): number | undefined {\n if (!entry[box]) {\n if (box === \"contentBoxSize\") {\n return entry.contentRect[sizeType === \"inlineSize\" ? \"width\" : \"height\"];\n }\n return undefined;\n }\n const boxSize = (\n Array.isArray(entry[box]) ? entry[box][0] : entry[box]\n ) as ResizeObserverSize;\n return boxSize[sizeType];\n}\n","import { useEffect } from \"react\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\nexport type TickEvent = {\n /** delta time in milliseconds since last tick */\n delta: number;\n /** current timestamp in milliseconds */\n now: number;\n};\n\nexport type TickCallback = (event: TickEvent) => void;\n\nexport type UnsubscribeTick = () => void;\n\ntype TickSubscription = {\n /** interval in milliseconds to execute the callback */\n interval: number;\n /** last executed timestamp in milliseconds */\n lastExecuted: number;\n};\n\n/**\n * Global timer singleton using setTimeout for better performance\n */\nclass GlobalTimer {\n /** singleton instance */\n private static instance: GlobalTimer;\n\n /** setTimeout id */\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n /** subscription map */\n private subscribers: Map<TickCallback, TickSubscription> = new Map();\n\n /** is timer running */\n private isRunning = false;\n\n /** internal update interval for smoothness */\n private readonly internalInterval = 200;\n\n /**\n * Get the singleton instance of the timer\n * @returns Timer instance\n */\n static getInstance(): GlobalTimer {\n if (!GlobalTimer.instance) {\n GlobalTimer.instance = new GlobalTimer();\n }\n return GlobalTimer.instance;\n }\n\n /**\n * Subscribe to the timer\n * @param callback tick callback\n * @param interval interval in milliseconds to execute the callback\n * @returns unsubscribe function\n */\n subscribe(callback: TickCallback, interval: number = 1000): UnsubscribeTick {\n this.subscribers.set(callback, {\n interval,\n lastExecuted: Date.now(),\n });\n\n // start timer if this is the first subscriber\n if (!this.isRunning) {\n this.start();\n }\n\n // return unsubscribe function\n return () => {\n this.subscribers.delete(callback);\n // stop timer if no more subscribers\n if (this.subscribers.size === 0) {\n this.stop();\n }\n };\n }\n\n private start(): void {\n if (this.isRunning) return;\n this.isRunning = true;\n this.scheduleNext();\n }\n\n private scheduleNext(): void {\n this.timeoutId = setTimeout(() => {\n const now = Date.now();\n\n // check each subscriber and execute if their interval has passed\n this.subscribers.forEach((config, callback) => {\n if (now - config.lastExecuted >= config.interval) {\n callback({ delta: now - config.lastExecuted, now });\n config.lastExecuted = now;\n }\n });\n\n // schedule next tick if still running\n if (this.isRunning) {\n this.scheduleNext();\n }\n }, this.internalInterval);\n }\n\n private stop(): void {\n this.isRunning = false;\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n}\n\n/**\n * Hook to call a callback at specified interval\n * @param callback Function to call at specified interval\n * @param interval Interval in milliseconds (default: 1000ms)\n * @returns\n */\nexport function useTick(callback: TickCallback, interval: number = 1000) {\n const callbackRef = useCallbackRef(callback);\n useEffect(\n () => GlobalTimer.getInstance().subscribe(callbackRef, interval),\n [interval],\n );\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { TickEvent, useTick } from \"./useTick\";\n\n/**\n * Hook to get the age in milliseconds since birthday in every tick\n * @param birthday Timestamp in milliseconds or Date object (default: now)\n * @param interval Tick interval in milliseconds (default: 1000ms)\n * @returns age in milliseconds since birthday\n */\nexport function useTickAge(\n birthday: number | Date = Date.now(),\n interval: number = 1000,\n) {\n const birthdayRef = useRef(\n birthday instanceof Date ? birthday.getTime() : birthday,\n );\n // keep ref updated\n birthdayRef.current =\n birthday instanceof Date ? birthday.getTime() : birthday;\n\n const [age, setAge] = useState(Math.max(0, Date.now() - birthdayRef.current));\n\n const tickAge = useCallback(\n ({ now }: TickEvent) => setAge(Math.max(0, now - birthdayRef.current)),\n [],\n );\n\n useTick(tickAge, interval);\n\n return age;\n}\n","import { RefObject, useRef } from \"react\";\n\n/**\n * Returns an always updated ref to value\n */\nexport function useValueRef<T>(value: T): RefObject<T> {\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n return valueRef;\n}\n","import { useMemo, useState } from \"react\";\nimport { throttle } from \"lodash-es\";\nimport { useResizeObserver } from \"./useResizeObserver\";\nimport type { UseResizeObserverOptions } from \"./useResizeObserver\";\n\n/** The size of the observed element. */\ntype Size = {\n /** The width of the observed element. */\n width: number | undefined;\n /** The height of the observed element. */\n height: number | undefined;\n};\n\nexport type UseThrottledResizeObserverOptions<\n T extends HTMLElement = HTMLElement,\n> = Pick<UseResizeObserverOptions<T>, \"ref\" | \"box\"> & {\n throttleMs?: number;\n};\n\nexport function useThrottledResizeObserver<T extends HTMLElement = HTMLElement>(\n options: UseThrottledResizeObserverOptions<T>,\n): Size {\n const { ref, box, throttleMs = 50 } = options;\n\n const [size, setSize] = useState<Size>({\n width: undefined,\n height: undefined,\n });\n\n const onResize = useMemo(\n () => throttle(setSize, throttleMs, { leading: true, trailing: true }),\n [throttleMs, setSize],\n );\n\n useResizeObserver({ ref, box, onResize });\n\n return size;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class Container {\n public constructor(private services: { [name: string]: any } = {}) {}\n\n register(...serviceClasses: any[]): void {\n serviceClasses.forEach((serviceClass) => {\n let service = serviceClass;\n if (service instanceof Function) {\n service = new serviceClass();\n }\n this.add(service);\n });\n }\n\n registerByName(name: string, serviceClass: any): void {\n let service = serviceClass;\n if (service instanceof Function) {\n service = new serviceClass();\n }\n this.addByName(name, service);\n }\n\n get<T = any>(name: string): T {\n return this.services[name];\n }\n\n getAll(): { [name: string]: any } {\n return Object.assign({}, this.services);\n }\n\n private add(service: any): any {\n return this.addByName(service.constructor.name, service);\n }\n\n private addByName(name: string, service: any): any {\n this.services[name] = service;\n this.services[name.toLowerCase()] = service;\n this.services[name.toUpperCase()] = service;\n return this.get(name);\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { getGlobalObject } from \"@liberfi.io/utils\";\nimport { Container } from \"./container\";\n\n/**\n * Global Dependency Injection Container\n */\nexport class SimpleDI {\n private static KEY = \"__LIBERFI_CONTAINER__\";\n private static container: Container =\n (getGlobalObject() as any)[SimpleDI.KEY] || null;\n\n private static getContainer(): Container {\n if (!SimpleDI.container) {\n (getGlobalObject() as any)[SimpleDI.KEY] = SimpleDI.container =\n new Container();\n }\n return SimpleDI.container;\n }\n\n static register(...serviceClasses: any[]): void {\n SimpleDI.getContainer().register(...serviceClasses);\n }\n\n static registerByName(name: string, serviceClass: any): void {\n SimpleDI.getContainer().registerByName(name, serviceClass);\n }\n\n static get<T = any>(name: string): T {\n return SimpleDI.getContainer().get<T>(name);\n }\n\n static getOr<T = any>(name: string, instance: T): T {\n const s = SimpleDI.getContainer().get<T>(name);\n if (!s) {\n SimpleDI.registerByName(name, instance);\n }\n return instance;\n }\n\n static getAll(): { [name: string]: any } {\n return SimpleDI.getContainer().getAll();\n }\n\n private constructor() {}\n}\n","import EventEmitter from \"eventemitter3\";\nimport useConstant from \"use-constant\";\nimport { SimpleDI } from \"./internal/di\";\n\nexport const useEventEmitter = () => {\n return useConstant(() => {\n let ee = SimpleDI.get<EventEmitter>(\"EE\");\n if (!ee) {\n ee = new EventEmitter();\n SimpleDI.registerByName(\"EE\", ee);\n }\n return ee;\n });\n};\n"]}
1
+ {"version":3,"sources":["../src/version.ts","../src/useBoolean.ts","../src/useSafeLayoutEffect.ts","../src/useCallbackRef.ts","../src/useIsMounted.ts","../src/useResizeObserver.ts","../src/useTick.ts","../src/useTickAge.ts","../src/useValueRef.ts","../src/internal/throttle.ts","../src/useThrottledResizeObserver.ts","../src/internal/di/container.ts","../src/internal/di/getGlobalObject.ts","../src/internal/di/simpleDI.ts","../src/useEventEmitter.ts"],"names":["useCallback","useRef","useEffect","useState"],"mappings":"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","file":"index.mjs","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/hooks\"] = \"0.1.25\";\n}\n\nexport default \"0.1.25\";\n","import { useCallback, useState } from \"react\";\n\nexport type UseBooleanReturn = [\n /** current state */\n boolean,\n {\n /** set state to true */\n setTrue: () => void;\n /** set state to false */\n setFalse: () => void;\n /** toggle state */\n toggle: () => void;\n },\n];\n\n/**\n * Hook to manage a boolean state\n * @param initialValue Initial value of the boolean\n * @returns\n */\nexport const useBoolean = (initialValue = false): UseBooleanReturn => {\n const [value, setValue] = useState(initialValue);\n const setTrue = useCallback(() => setValue(true), []);\n const setFalse = useCallback(() => setValue(false), []);\n const toggle = useCallback(() => setValue((v) => !v), []);\n return [value, { setTrue, setFalse, toggle }];\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\nexport const useSafeLayoutEffect = globalThis?.document\n ? useLayoutEffect\n : useEffect;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Part of this code is taken from @chakra-ui/system ❤️\n */\nimport { useCallback, useRef } from \"react\";\nimport { useSafeLayoutEffect } from \"./useSafeLayoutEffect\";\n\n/**\n * React hook to persist any value between renders,\n * but keeps it up-to-date if it changes.\n * @param fn the function to persist\n * @param deps the function dependency list\n */\nexport function useCallbackRef<T extends (...args: any[]) => any>(\n fn: T | undefined,\n deps: React.DependencyList = [],\n): T {\n const ref = useRef(fn);\n\n useSafeLayoutEffect(() => {\n ref.current = fn;\n });\n\n return useCallback(((...args) => ref.current?.(...args)) as T, deps);\n}\n","import { useCallback, useEffect, useRef } from \"react\";\n\n/**\n * Custom hook that determines if the component is currently mounted.\n * @example\n * ```tsx\n * const isComponentMounted = useIsMounted();\n * // Use isComponentMounted() to check if the component is currently mounted before performing certain actions.\n * ```\n */\nexport function useIsMounted(): () => boolean {\n const isMounted = useRef(false);\n\n useEffect(() => {\n isMounted.current = true;\n\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n return useCallback(() => isMounted.current, []);\n}\n","import type { RefObject } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useIsMounted } from \"./useIsMounted\";\n\n/** The size of the observed element. */\nexport type Size = {\n /** The width of the observed element. */\n width: number | undefined;\n /** The height of the observed element. */\n height: number | undefined;\n};\n\n/** The options for the ResizeObserver. */\nexport type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {\n /** The ref of the element to observe. */\n ref: RefObject<T | null>;\n /**\n * When using `onResize`, the hook doesn't re-render on element size changes; it delegates handling to the provided callback.\n * @default undefined\n */\n onResize?: (size: Size) => void;\n /**\n * The box model to use for the ResizeObserver.\n * @default 'content-box'\n */\n box?: \"border-box\" | \"content-box\" | \"device-pixel-content-box\";\n};\n\nconst initialSize: Size = {\n width: undefined,\n height: undefined,\n};\n\n/**\n * Custom hook that observes the size of an element using the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n * @template T - The type of the element to observe.\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-resize-observer)\n * @example\n * ```tsx\n * const myRef = useRef(null);\n * const { width = 0, height = 0 } = useResizeObserver({\n * ref: myRef,\n * box: 'content-box',\n * });\n *\n * <div ref={myRef}>Hello, world!</div>\n * ```\n */\nexport function useResizeObserver<T extends HTMLElement = HTMLElement>(\n options: UseResizeObserverOptions<T>,\n): Size {\n const { ref, box = \"content-box\" } = options;\n const [{ width, height }, setSize] = useState<Size>(initialSize);\n const isMounted = useIsMounted();\n const previousSize = useRef<Size>({ ...initialSize });\n const onResize = useRef<((size: Size) => void) | undefined>(undefined);\n onResize.current = options.onResize;\n\n useEffect(() => {\n if (!ref.current) return;\n\n if (typeof window === \"undefined\" || !(\"ResizeObserver\" in window)) return;\n\n const observer = new ResizeObserver(([entry]) => {\n const boxProp =\n box === \"border-box\"\n ? \"borderBoxSize\"\n : box === \"device-pixel-content-box\"\n ? \"devicePixelContentBoxSize\"\n : \"contentBoxSize\";\n\n const newWidth = extractSize(entry, boxProp, \"inlineSize\");\n const newHeight = extractSize(entry, boxProp, \"blockSize\");\n\n const hasChanged =\n previousSize.current.width !== newWidth ||\n previousSize.current.height !== newHeight;\n\n if (hasChanged) {\n const newSize: Size = { width: newWidth, height: newHeight };\n previousSize.current.width = newWidth;\n previousSize.current.height = newHeight;\n\n if (onResize.current) {\n onResize.current(newSize);\n } else {\n if (isMounted()) {\n setSize(newSize);\n }\n }\n }\n });\n\n observer.observe(ref.current, { box });\n\n return () => {\n observer.disconnect();\n };\n }, [box, ref, isMounted]);\n\n return { width, height };\n}\n\ntype BoxSizesKey = keyof Pick<\n ResizeObserverEntry,\n \"borderBoxSize\" | \"contentBoxSize\" | \"devicePixelContentBoxSize\"\n>;\n\nfunction extractSize(\n entry: ResizeObserverEntry,\n box: BoxSizesKey,\n sizeType: keyof ResizeObserverSize,\n): number | undefined {\n if (!entry[box]) {\n if (box === \"contentBoxSize\") {\n return entry.contentRect[sizeType === \"inlineSize\" ? \"width\" : \"height\"];\n }\n return undefined;\n }\n const boxSize = (\n Array.isArray(entry[box]) ? entry[box][0] : entry[box]\n ) as ResizeObserverSize;\n return boxSize[sizeType];\n}\n","import { useEffect } from \"react\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\nexport type TickEvent = {\n /** delta time in milliseconds since last tick */\n delta: number;\n /** current timestamp in milliseconds */\n now: number;\n};\n\nexport type TickCallback = (event: TickEvent) => void;\n\ntype UnsubscribeTick = () => void;\n\ntype TickSubscription = {\n /** interval in milliseconds to execute the callback */\n interval: number;\n /** last executed timestamp in milliseconds */\n lastExecuted: number;\n};\n\n/**\n * Global timer singleton using setTimeout for better performance\n */\nclass GlobalTimer {\n /** singleton instance */\n private static instance: GlobalTimer;\n\n /** setTimeout id */\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n /** subscription map */\n private subscribers: Map<TickCallback, TickSubscription> = new Map();\n\n /** is timer running */\n private isRunning = false;\n\n /** internal update interval for smoothness */\n private readonly internalInterval = 200;\n\n /**\n * Get the singleton instance of the timer\n * @returns Timer instance\n */\n static getInstance(): GlobalTimer {\n if (!GlobalTimer.instance) {\n GlobalTimer.instance = new GlobalTimer();\n }\n return GlobalTimer.instance;\n }\n\n /**\n * Subscribe to the timer\n * @param callback tick callback\n * @param interval interval in milliseconds to execute the callback\n * @returns unsubscribe function\n */\n subscribe(callback: TickCallback, interval: number = 1000): UnsubscribeTick {\n this.subscribers.set(callback, {\n interval,\n lastExecuted: Date.now(),\n });\n\n // start timer if this is the first subscriber\n if (!this.isRunning) {\n this.start();\n }\n\n // return unsubscribe function\n return () => {\n this.subscribers.delete(callback);\n // stop timer if no more subscribers\n if (this.subscribers.size === 0) {\n this.stop();\n }\n };\n }\n\n private start(): void {\n if (this.isRunning) return;\n this.isRunning = true;\n this.scheduleNext();\n }\n\n private scheduleNext(): void {\n this.timeoutId = setTimeout(() => {\n const now = Date.now();\n\n // check each subscriber and execute if their interval has passed\n this.subscribers.forEach((config, callback) => {\n if (now - config.lastExecuted >= config.interval) {\n callback({ delta: now - config.lastExecuted, now });\n config.lastExecuted = now;\n }\n });\n\n // schedule next tick if still running\n if (this.isRunning) {\n this.scheduleNext();\n }\n }, this.internalInterval);\n }\n\n private stop(): void {\n this.isRunning = false;\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n}\n\n/**\n * Hook to call a callback at specified interval\n * @param callback Function to call at specified interval\n * @param interval Interval in milliseconds (default: 1000ms)\n * @returns\n */\nexport function useTick(callback: TickCallback, interval: number = 1000) {\n const callbackRef = useCallbackRef(callback);\n useEffect(\n () => GlobalTimer.getInstance().subscribe(callbackRef, interval),\n [interval],\n );\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { TickEvent, useTick } from \"./useTick\";\n\n/**\n * Hook to get the age in milliseconds since birthday in every tick\n * @param birthday Timestamp in milliseconds or Date object (default: now)\n * @param interval Tick interval in milliseconds (default: 1000ms)\n * @returns age in milliseconds since birthday\n */\nexport function useTickAge(\n birthday: number | Date = Date.now(),\n interval: number = 1000,\n) {\n const birthdayRef = useRef(\n birthday instanceof Date ? birthday.getTime() : birthday,\n );\n // keep ref updated\n birthdayRef.current =\n birthday instanceof Date ? birthday.getTime() : birthday;\n\n const [age, setAge] = useState(Math.max(0, Date.now() - birthdayRef.current));\n\n const tickAge = useCallback(\n ({ now }: TickEvent) => setAge(Math.max(0, now - birthdayRef.current)),\n [],\n );\n\n useTick(tickAge, interval);\n\n return age;\n}\n","import { RefObject, useRef } from \"react\";\n\n/**\n * Returns an always updated ref to value\n */\nexport function useValueRef<T>(value: T): RefObject<T> {\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n return valueRef;\n}\n","/**\n * Minimal throttle with leading + trailing execution.\n * Replaces lodash-es/throttle for the single call-site in this package.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function throttle<T extends (...args: any[]) => void>(\n fn: T,\n wait: number,\n): T {\n let lastCallTime = 0;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n const throttled = (...args: Parameters<T>) => {\n const now = Date.now();\n const remaining = wait - (now - lastCallTime);\n\n if (remaining <= 0) {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n lastCallTime = now;\n fn(...args);\n } else {\n lastArgs = args;\n if (timeoutId === null) {\n timeoutId = setTimeout(() => {\n lastCallTime = Date.now();\n timeoutId = null;\n if (lastArgs) {\n fn(...lastArgs);\n lastArgs = null;\n }\n }, remaining);\n }\n }\n };\n\n return throttled as T;\n}\n","import { useMemo, useState } from \"react\";\nimport { throttle } from \"./internal/throttle\";\nimport { useResizeObserver } from \"./useResizeObserver\";\nimport type { Size, UseResizeObserverOptions } from \"./useResizeObserver\";\n\nexport type UseThrottledResizeObserverOptions<\n T extends HTMLElement = HTMLElement,\n> = Pick<UseResizeObserverOptions<T>, \"ref\" | \"box\"> & {\n throttleMs?: number;\n};\n\nexport function useThrottledResizeObserver<T extends HTMLElement = HTMLElement>(\n options: UseThrottledResizeObserverOptions<T>,\n): Size {\n const { ref, box, throttleMs = 50 } = options;\n\n const [size, setSize] = useState<Size>({\n width: undefined,\n height: undefined,\n });\n\n const onResize = useMemo(\n () => throttle(setSize, throttleMs),\n [throttleMs, setSize],\n );\n\n useResizeObserver({ ref, box, onResize });\n\n return size;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class Container {\n public constructor(private services: { [name: string]: any } = {}) {}\n\n register(...serviceClasses: any[]): void {\n serviceClasses.forEach((serviceClass) => {\n let service = serviceClass;\n if (service instanceof Function) {\n service = new serviceClass();\n }\n this.add(service);\n });\n }\n\n registerByName(name: string, serviceClass: any): void {\n let service = serviceClass;\n if (service instanceof Function) {\n service = new serviceClass();\n }\n this.addByName(name, service);\n }\n\n get<T = any>(name: string): T {\n return this.services[name];\n }\n\n getAll(): { [name: string]: any } {\n return Object.assign({}, this.services);\n }\n\n private add(service: any): any {\n return this.addByName(service.constructor.name, service);\n }\n\n /**\n * Stores the service under three keys — original, lowercase, and uppercase —\n * so that callers can retrieve it case-insensitively (e.g. \"EE\", \"ee\", \"Ee\"\n * all resolve to the same instance).\n */\n private addByName(name: string, service: any): any {\n this.services[name] = service;\n this.services[name.toLowerCase()] = service;\n this.services[name.toUpperCase()] = service;\n return this.get(name);\n }\n}\n","export const getGlobalObject = () => {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n if (typeof self !== \"undefined\") {\n return self;\n }\n if (typeof window !== \"undefined\") {\n return window;\n }\n // @ts-ignore\n if (typeof global !== \"undefined\") {\n // @ts-ignore\n return global;\n }\n throw new Error(\"cannot find the global object\");\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Container } from \"./container\";\nimport { getGlobalObject } from \"./getGlobalObject\";\n\n/**\n * Global Dependency Injection Container\n */\nexport class SimpleDI {\n private static KEY = \"__LIBERFI_CONTAINER__\";\n private static container: Container =\n (getGlobalObject() as any)[SimpleDI.KEY] || null;\n\n private static getContainer(): Container {\n if (!SimpleDI.container) {\n (getGlobalObject() as any)[SimpleDI.KEY] = SimpleDI.container =\n new Container();\n }\n return SimpleDI.container;\n }\n\n static register(...serviceClasses: any[]): void {\n SimpleDI.getContainer().register(...serviceClasses);\n }\n\n static registerByName(name: string, serviceClass: any): void {\n SimpleDI.getContainer().registerByName(name, serviceClass);\n }\n\n static get<T = any>(name: string): T {\n return SimpleDI.getContainer().get<T>(name);\n }\n\n static getOr<T = any>(name: string, instance: T): T {\n const s = SimpleDI.getContainer().get<T>(name);\n if (!s) {\n SimpleDI.registerByName(name, instance);\n }\n return instance;\n }\n\n static getAll(): { [name: string]: any } {\n return SimpleDI.getContainer().getAll();\n }\n\n /**\n * Reset the global container, removing all registered services.\n * Primarily used in test teardown to ensure isolation between suites.\n */\n static reset(): void {\n if (SimpleDI.container) {\n SimpleDI.container = null!;\n delete (getGlobalObject() as any)[SimpleDI.KEY];\n }\n }\n\n private constructor() {}\n}\n","import { useRef } from \"react\";\nimport EventEmitter from \"eventemitter3\";\nimport { SimpleDI } from \"./internal/di\";\n\nexport const useEventEmitter = () => {\n const ref = useRef<EventEmitter | null>(null);\n if (ref.current === null) {\n let ee = SimpleDI.get<EventEmitter>(\"EE\");\n if (!ee) {\n ee = new EventEmitter();\n SimpleDI.registerByName(\"EE\", ee);\n }\n ref.current = ee;\n }\n return ref.current;\n};\n"]}
package/package.json CHANGED
@@ -1,52 +1,46 @@
1
1
  {
2
2
  "name": "@liberfi.io/hooks",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ }
18
+ }
19
+ },
8
20
  "keywords": [],
9
21
  "files": [
10
22
  "dist"
11
23
  ],
12
24
  "peerDependencies": {
13
- "react": ">=18",
14
- "react-dom": ">=18"
25
+ "react": ">=18"
15
26
  },
16
27
  "dependencies": {
17
- "eventemitter3": "^5.0.1",
18
- "lodash-es": "^4.17.21",
19
- "use-constant": "^2.0.0",
20
- "@liberfi.io/types": "0.1.27",
21
- "@liberfi.io/utils": "0.1.24"
28
+ "eventemitter3": "^5.0.1"
22
29
  },
23
30
  "devDependencies": {
24
- "@babel/core": "^7.22.9",
25
- "@babel/preset-env": "^7.22.9",
26
- "@babel/preset-react": "^7.27.1",
27
- "@babel/preset-typescript": "^7.22.5",
28
- "@jest/globals": "^30.0.2",
29
- "@swc/cli": "^0.3.12",
30
- "@swc/core": "^1.4.12",
31
- "@swc/plugin-remove-console": "^1.5.121",
32
31
  "@testing-library/dom": "^10.4.1",
33
32
  "@testing-library/react": "^16.3.0",
34
33
  "@types/jest": "^29.5.3",
35
- "@types/lodash-es": "^4.17.12",
36
34
  "@types/react": "^19.1.13",
37
35
  "@types/react-dom": "^19.1.9",
38
- "babel-jest": "^29.6.1",
39
- "chokidar-cli": "^3.0.0",
40
36
  "jest": "^29.6.1",
41
37
  "jest-environment-jsdom": "^29.7.0",
42
- "live-server": "^1.2.2",
43
38
  "react": "^19.1.1",
44
39
  "react-dom": "^19.1.1",
45
- "rimraf": "^5.0.5",
40
+ "ts-jest": "^29.4.6",
46
41
  "tsup": "^8.5.0",
47
- "typedoc": "^0.28.12",
48
42
  "typescript": "^5.9.2",
49
- "tsconfig": "0.1.15"
43
+ "tsconfig": "0.1.16"
50
44
  },
51
45
  "publishConfig": {
52
46
  "access": "public"
@@ -67,21 +61,7 @@
67
61
  },
68
62
  "scripts": {
69
63
  "dev": "tsup --watch",
70
- "build:tsc": "rimraf -rf dist esm lib && pnpm run build:esm && pnpm run build:cjs",
71
- "build:tsup": "tsup",
72
- "build:esm": "tsc --project tsconfig.build.json --outDir esm",
73
- "build:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir lib",
74
- "docs:dev": "pnpm docs:watch & pnpm docs:serve",
75
- "docs:watch": "chokidar 'src/**/*.ts' -c 'pnpm run docs:generate'",
76
- "docs:serve": "live-server docs --watch=docs",
77
- "docs:generate": "typedoc",
78
- "docs:parse": "@liberfi.io/typedoc-json-parser",
79
- "test": "jest",
80
- "build": "rimraf -rf dist esm lib && pnpm build:tsup",
81
- "build:swc": "rimraf -rf dist esm lib && pnpm build:swc:esm && pnpm build:swc:cjs",
82
- "build:swc:esm": "pnpm generateType:esm && swc src -d esm --strip-leading-paths --copy-files",
83
- "build:swc:cjs": "pnpm generateType:cjs && swc src -d lib --config module.type=commonjs --strip-leading-paths --copy-files",
84
- "generateType:esm": "tsc --emitDeclarationOnly --project tsconfig.build.json --outDir esm",
85
- "generateType:cjs": "tsc --emitDeclarationOnly --project tsconfig.build.json --module commonjs --outDir lib"
64
+ "build": "tsup",
65
+ "test": "jest"
86
66
  }
87
67
  }