@foresightjs/react 0.1.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.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/index.d.mts +19 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Bart Spaans
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @foresightjs/react
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@foresightjs/react)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](http://www.typescriptlang.org/)
|
|
6
|
+
|
|
7
|
+
Official React bindings for [ForesightJS](https://foresightjs.com/), a lightweight library that predicts user intent (mouse trajectory, keyboard navigation, scroll, touch) to trigger callbacks like prefetching _before_ the user interacts.
|
|
8
|
+
|
|
9
|
+
- **Docs:** [foresightjs.com/docs/react/installation](https://foresightjs.com/docs/react/installation)
|
|
10
|
+
- **Core library:** [`js.foresight`](https://www.npmjs.com/package/js.foresight)
|
|
11
|
+
- **Playground:** [foresightjs.com](https://foresightjs.com/#playground)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add @foresightjs/react js.foresight
|
|
17
|
+
# or
|
|
18
|
+
npm install @foresightjs/react js.foresight
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Requires React 18+
|
|
22
|
+
|
|
23
|
+
## What's included
|
|
24
|
+
|
|
25
|
+
- `useForesight` -> register a single element and get its live state plus a callback ref to bind it
|
|
26
|
+
- `useForesights` -> register a dynamic list of elements from one hook call
|
|
27
|
+
- `useForesightEvent` -> subscribe to a ForesightManager event for the lifetime of the component
|
|
28
|
+
|
|
29
|
+
For usage and examples, see the [React documentation](https://foresightjs.com/docs/react/installation), including guides for [Next.js](https://foresightjs.com/docs/react/nextjs) and [React Router](https://foresightjs.com/docs/react/react-router).
|
|
30
|
+
|
|
31
|
+
## Contributing
|
|
32
|
+
|
|
33
|
+
Please see the [contributing guidelines](https://github.com/spaansba/ForesightJS/blob/main/CONTRIBUTING.md).
|
|
34
|
+
|
|
35
|
+
## License
|
|
36
|
+
|
|
37
|
+
[MIT](./LICENSE)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CallbackCompletedEvent, CallbackHitType, CallbackHits, CallbackInvokedEvent, DeviceStrategyChangedEvent, ElementRegisteredEvent, ElementUnregisteredEvent, ForesightCallback, ForesightElementState, ForesightElementState as ForesightElementState$1, ForesightEvent, ForesightEvent as ForesightEvent$1, ForesightEventMap, ForesightEventMap as ForesightEventMap$1, ForesightManager, ForesightManagerSettings, ForesightRegisterOptionsWithoutElement, ForesightRegisterOptionsWithoutElement as ForesightRegisterOptionsWithoutElement$1, HitSlop, ManagerSettingsChangedEvent, MinimumConnectionType, MouseTrajectoryUpdateEvent, ScrollTrajectoryUpdateEvent, TouchDeviceStrategy, UpdateForsightManagerSettings } from "js.foresight";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
type UseForesightOptions = ForesightRegisterOptionsWithoutElement$1;
|
|
5
|
+
type UseForesightResult<T extends HTMLElement> = ForesightElementState$1 & {
|
|
6
|
+
elementRef: (node: T | null) => void;
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/hooks/useForesight.d.ts
|
|
10
|
+
declare const useForesight: <T extends HTMLElement = HTMLElement>(options: UseForesightOptions) => UseForesightResult<T>;
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/hooks/useForesights.d.ts
|
|
13
|
+
declare const useForesights: <T extends HTMLElement = HTMLElement>(optionsArray: UseForesightOptions[]) => UseForesightResult<T>[];
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/hooks/useForesightEvent.d.ts
|
|
16
|
+
declare const useForesightEvent: <K extends ForesightEvent$1>(eventType: K, listener: (event: ForesightEventMap$1[K]) => void) => void;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { type CallbackCompletedEvent, type CallbackHitType, type CallbackHits, type CallbackInvokedEvent, type DeviceStrategyChangedEvent, type ElementRegisteredEvent, type ElementUnregisteredEvent, type ForesightCallback, type ForesightElementState, type ForesightEvent, type ForesightEventMap, ForesightManager, type ForesightManagerSettings, type ForesightRegisterOptionsWithoutElement, type HitSlop, type ManagerSettingsChangedEvent, type MinimumConnectionType, type MouseTrajectoryUpdateEvent, type ScrollTrajectoryUpdateEvent, type TouchDeviceStrategy, type UpdateForsightManagerSettings, type UseForesightOptions, type UseForesightResult, useForesight, useForesightEvent, useForesights };
|
|
19
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/hooks/useForesight.ts","../src/hooks/useForesights.ts","../src/hooks/useForesightEvent.ts"],"mappings":";;;KAEY,mBAAA,GAAsB,wCAAA;AAAA,KAEtB,kBAAA,WAA6B,WAAA,IAAe,uBAAA;EACtD,UAAA,GAAa,IAAA,EAAM,CAAA;AAAA;;;cCSR,YAAA,aAA0B,WAAA,GAAc,WAAA,EACnD,OAAA,EAAS,mBAAA,KACR,kBAAA,CAAmB,CAAA;;;cCGT,aAAA,aAA2B,WAAA,GAAc,WAAA,EACpD,YAAA,EAAc,mBAAA,OACb,kBAAA,CAAmB,CAAA;;;cClBT,iBAAA,aAA+B,gBAAA,EAC1C,SAAA,EAAW,CAAA,EACX,QAAA,GAAW,KAAA,EAAO,mBAAA,CAAkB,CAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{ForesightManager as e,ForesightManager as t,createUnregisteredSnapshot as n}from"js.foresight";import{useCallback as r,useEffect as i,useRef as a,useState as o,useSyncExternalStore as s}from"react";const c=e=>{if(e==null)return``;try{return JSON.stringify(e)}catch{return String(e)}},l=()=>()=>{},u=n(!1),d=()=>u,f=e=>{let n=a(e);n.current=e;let[u,f]=o(null),[p,m]=o(null),h=r(e=>{f(e)},[]);i(()=>{if(!u)return;let e=t.instance.register({...n.current,element:u,callback:e=>n.current.callback(e)});return m(e),()=>{e.unregister(),m(null)}},[u]);let g=c(e.meta),_=c(e.hitSlop);return i(()=>{!p||!u||t.instance.updateElementOptions(u,{...n.current,callback:e=>n.current.callback(e)})},[e.reactivateAfter,e.name,g,e.enabled,_,u,p]),{elementRef:h,...s(p?.subscribe??l,p?.getSnapshot??d,d)}},p=n(!1),m=()=>()=>{},h=[],g=e=>{let n=a(e);n.current=e;let l=a(new Map),u=a(new Map),d=a(h),f=a(new Map),[g,_]=o(new Map),[v,y]=o(new Map),b=r(e=>{let t=u.current.get(e);return t||(t=t=>{(l.current.get(e)??null)!==t&&(t?l.current.set(e,t):l.current.delete(e),_(new Map(l.current)))},u.current.set(e,t)),t},[]);i(()=>{let r=new Map(f.current),i=new Map;for(let a=0;a<e.length;a++){let e=g.get(a);if(!e)continue;let o=r.get(a);if(o&&o.element===e){i.set(a,o),r.delete(a);continue}let s=t.instance.register({...n.current[a],element:e,callback:e=>n.current[a]?.callback(e)});i.set(a,{element:e,result:s})}for(let[,e]of r)e.result.unregister();return f.current=i,y(new Map(Array.from(i.entries()).map(([e,t])=>[e,t.result]))),()=>{for(let[,e]of f.current)e.result.unregister();f.current=new Map}},[e.length,g]);let x=e.map(e=>`${e.reactivateAfter??``},${e.name??``},${c(e.meta)},${e.enabled??``},${c(e.hitSlop)}`).join(`|`);i(()=>{for(let r=0;r<e.length;r++){let e=f.current.get(r);e&&t.instance.updateElementOptions(e.element,{...n.current[r],callback:e=>n.current[r]?.callback(e)})}},[e.length,x]);let S=s(r(e=>{if(v.size===0)return m();let t=[];for(let[,n]of v)t.push(n.subscribe(e));return()=>t.forEach(e=>e())},[v]),r(()=>{let e=n.current.length,t=d.current,r=t.length!==e;if(!r){for(let n=0;n<e;n++)if((v.get(n)?.getSnapshot()??p)!==t[n]){r=!0;break}}if(!r)return t;let i=[];for(let t=0;t<e;t++){let e=v.get(t);i.push(e?.getSnapshot()??p)}return d.current=i,i},[v]),r(()=>n.current.map(()=>p),[]));return e.map((e,t)=>({elementRef:b(t),...S[t]??p}))},_=(e,n)=>{let r=a(n);r.current=n,i(()=>{let n=new AbortController;return t.instance.addEventListener(e,e=>r.current(e),{signal:n.signal}),()=>n.abort()},[e])};export{e as ForesightManager,f as useForesight,_ as useForesightEvent,g as useForesights};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["NOOP_SUBSCRIBE","INITIAL_SNAPSHOT","ForesightManager","ForesightManager"],"sources":["../src/hooks/serializeOption.ts","../src/hooks/useForesight.ts","../src/hooks/useForesights.ts","../src/hooks/useForesightEvent.ts"],"sourcesContent":["/**\n * Serialize an object option (`meta`, `hitSlop`) for use as an effect\n * dependency / patch key so a change to its contents re-triggers the patch\n * effect. Depending on the object itself would compare by identity, re-firing\n * the effect for every inline `meta={{...}}` even when its contents are\n * unchanged. Falls back to String() when the object can't be serialized\n * (e.g. circular references).\n */\nexport const serializeOption = (value: unknown): string => {\n if (value === undefined || value === null) {\n return \"\"\n }\n\n try {\n return JSON.stringify(value)\n } catch {\n return String(value)\n }\n}\n","import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\"\nimport {\n ForesightManager,\n createUnregisteredSnapshot,\n type ForesightElementState,\n type ForesightRegisterResult,\n} from \"js.foresight\"\nimport type { UseForesightOptions, UseForesightResult } from \"../types\"\nimport { serializeOption } from \"./serializeOption\"\n\nconst NOOP_SUBSCRIBE = () => () => {}\nconst INITIAL_SNAPSHOT = createUnregisteredSnapshot(false)\nconst GET_INITIAL_SNAPSHOT = () => INITIAL_SNAPSHOT\n\nexport const useForesight = <T extends HTMLElement = HTMLElement>(\n options: UseForesightOptions\n): UseForesightResult<T> => {\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n const [element, setElement] = useState<T | null>(null)\n const [registerResults, setRegisterResults] = useState<ForesightRegisterResult | null>(null)\n\n const elementRef = useCallback((node: T | null) => {\n setElement(node)\n }, [])\n\n // Register/unregister when the DOM node attaches or swaps.\n useEffect(() => {\n if (!element) {\n return\n }\n\n const result = ForesightManager.instance.register({\n ...optionsRef.current,\n element,\n callback: (state: ForesightElementState) => optionsRef.current.callback(state),\n })\n setRegisterResults(result)\n\n return () => {\n result.unregister()\n setRegisterResults(null)\n }\n }, [element])\n\n // Patch options on the existing registration without tearing it down.\n // meta and hitSlop are compared by content, not identity - an inline\n // `meta={{...}}` object would otherwise re-fire this effect every render and\n // loop with the useSyncExternalStore re-render it triggers.\n const metaKey = serializeOption(options.meta)\n const hitSlopKey = serializeOption(options.hitSlop)\n useEffect(() => {\n if (!registerResults || !element) {\n return\n }\n\n ForesightManager.instance.updateElementOptions(element, {\n ...optionsRef.current,\n callback: (state: ForesightElementState) => optionsRef.current.callback(state),\n })\n }, [\n options.reactivateAfter,\n options.name,\n metaKey,\n options.enabled,\n hitSlopKey,\n element,\n registerResults,\n ])\n\n const state = useSyncExternalStore<ForesightElementState>(\n registerResults?.subscribe ?? NOOP_SUBSCRIBE,\n registerResults?.getSnapshot ?? GET_INITIAL_SNAPSHOT,\n GET_INITIAL_SNAPSHOT\n )\n\n return { elementRef, ...state }\n}\n","import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\"\nimport {\n ForesightManager,\n createUnregisteredSnapshot,\n type ForesightElementState,\n type ForesightRegisterResult,\n} from \"js.foresight\"\nimport type { UseForesightOptions, UseForesightResult } from \"../types\"\nimport { serializeOption } from \"./serializeOption\"\n\nconst INITIAL_SNAPSHOT = createUnregisteredSnapshot(false)\nconst NOOP_SUBSCRIBE = () => () => {}\nconst EMPTY_SNAPSHOTS: ForesightElementState[] = []\n\ntype SlotEntry = {\n element: Element\n result: ForesightRegisterResult\n}\n\nexport const useForesights = <T extends HTMLElement = HTMLElement>(\n optionsArray: UseForesightOptions[]\n): UseForesightResult<T>[] => {\n const optionsRef = useRef(optionsArray)\n optionsRef.current = optionsArray\n\n const elementsRef = useRef(new Map<number, T>())\n const elementRefCallbacksRef = useRef(new Map<number, (node: T | null) => void>())\n const cachedSnapshotsRef = useRef<ForesightElementState[]>(EMPTY_SNAPSHOTS)\n const slotsRef = useRef(new Map<number, SlotEntry>())\n\n const [elements, setElements] = useState<ReadonlyMap<number, T>>(new Map())\n const [resultsList, setResultsList] = useState<ReadonlyMap<number, ForesightRegisterResult>>(\n new Map()\n )\n\n // Stable elementRef factory - one callback per index, reused across renders\n const getElementRef = useCallback((index: number): ((node: T | null) => void) => {\n let existing = elementRefCallbacksRef.current.get(index)\n if (!existing) {\n existing = (node: T | null) => {\n const prev = elementsRef.current.get(index) ?? null\n if (prev === node) {\n return\n }\n\n if (node) {\n elementsRef.current.set(index, node)\n } else {\n elementsRef.current.delete(index)\n }\n\n setElements(new Map(elementsRef.current))\n }\n elementRefCallbacksRef.current.set(index, existing)\n }\n\n return existing\n }, [])\n\n // Register/unregister when elements change or the array length changes\n useEffect(() => {\n const prevResults = new Map(slotsRef.current)\n const nextSlots = new Map<number, SlotEntry>()\n\n // Register each slot that has an element\n for (let i = 0; i < optionsArray.length; i++) {\n const el = elements.get(i)\n if (!el) {\n continue\n }\n\n const prev = prevResults.get(i)\n\n // If same element is already registered, keep the existing result\n if (prev && prev.element === el) {\n nextSlots.set(i, prev)\n prevResults.delete(i)\n continue\n }\n\n // New or swapped element - register it\n const result = ForesightManager.instance.register({\n ...optionsRef.current[i],\n element: el,\n callback: (state: ForesightElementState) => optionsRef.current[i]?.callback(state),\n })\n nextSlots.set(i, { element: el, result })\n }\n\n // Unregister everything that's no longer needed\n for (const [, slot] of prevResults) {\n slot.result.unregister()\n }\n\n slotsRef.current = nextSlots\n setResultsList(new Map(Array.from(nextSlots.entries()).map(([k, v]) => [k, v.result])))\n\n return () => {\n for (const [, slot] of slotsRef.current) {\n slot.result.unregister()\n }\n slotsRef.current = new Map()\n }\n }, [optionsArray.length, elements])\n\n // Patch options on existing registrations without tearing them down\n const patchKey = optionsArray\n .map(\n o =>\n `${o.reactivateAfter ?? \"\"},${o.name ?? \"\"},${serializeOption(o.meta)},${o.enabled ?? \"\"},${serializeOption(o.hitSlop)}`\n )\n .join(\"|\")\n\n useEffect(() => {\n for (let i = 0; i < optionsArray.length; i++) {\n const slot = slotsRef.current.get(i)\n if (!slot) {\n continue\n }\n\n ForesightManager.instance.updateElementOptions(slot.element, {\n ...optionsRef.current[i],\n callback: (state: ForesightElementState) => optionsRef.current[i]?.callback(state),\n })\n }\n }, [optionsArray.length, patchKey])\n\n // Subscribe to all active registrations. Re-subscribes when the set of results changes.\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (resultsList.size === 0) {\n return NOOP_SUBSCRIBE()\n }\n\n const unsubs: (() => void)[] = []\n for (const [, result] of resultsList) {\n unsubs.push(result.subscribe(onStoreChange))\n }\n\n return () => unsubs.forEach(u => u())\n },\n [resultsList]\n )\n\n // getSnapshot must return a referentially stable value when nothing changed.\n const getSnapshot = useCallback((): ForesightElementState[] => {\n const length = optionsRef.current.length\n const cached = cachedSnapshotsRef.current\n\n let changed = cached.length !== length\n if (!changed) {\n for (let i = 0; i < length; i++) {\n const result = resultsList.get(i)\n const current = result?.getSnapshot() ?? INITIAL_SNAPSHOT\n if (current !== cached[i]) {\n changed = true\n break\n }\n }\n }\n\n if (!changed) {\n return cached\n }\n\n const next: ForesightElementState[] = []\n for (let i = 0; i < length; i++) {\n const result = resultsList.get(i)\n next.push(result?.getSnapshot() ?? INITIAL_SNAPSHOT)\n }\n cachedSnapshotsRef.current = next\n\n return next\n }, [resultsList])\n\n const getServerSnapshot = useCallback(\n (): ForesightElementState[] => optionsRef.current.map(() => INITIAL_SNAPSHOT),\n []\n )\n\n const states = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n\n return optionsArray.map((_, i) => ({\n elementRef: getElementRef(i),\n ...(states[i] ?? INITIAL_SNAPSHOT),\n }))\n}\n","import { useEffect, useRef } from \"react\"\nimport { ForesightManager, type ForesightEvent, type ForesightEventMap } from \"js.foresight\"\n\nexport const useForesightEvent = <K extends ForesightEvent>(\n eventType: K,\n listener: (event: ForesightEventMap[K]) => void\n): void => {\n const listenerRef = useRef(listener)\n listenerRef.current = listener\n\n useEffect(() => {\n const controller = new AbortController()\n const stableListener = (event: ForesightEventMap[K]) => listenerRef.current(event)\n\n ForesightManager.instance.addEventListener(eventType, stableListener, {\n signal: controller.signal,\n })\n\n return () => controller.abort()\n }, [eventType])\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@foresightjs/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React bindings for ForesightJS - hooks and helpers to register elements with the ForesightManager from React components.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.mjs",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.mts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.mts",
|
|
13
|
+
"default": "./dist/index.mjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://foresightjs.com/",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/spaansba/ForesightJS",
|
|
20
|
+
"directory": "packages/foresightjs-react"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"keywords": [
|
|
31
|
+
"react",
|
|
32
|
+
"foresight",
|
|
33
|
+
"js.foresight",
|
|
34
|
+
"foresightjs",
|
|
35
|
+
"react-hooks",
|
|
36
|
+
"prefetch",
|
|
37
|
+
"interaction-prediction",
|
|
38
|
+
"mouse-trajectory",
|
|
39
|
+
"useForesight"
|
|
40
|
+
],
|
|
41
|
+
"author": "Bart Spaans",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"llms": "https://foresightjs.com/llms.txt",
|
|
44
|
+
"llmsFull": "https://foresightjs.com/llms-full.txt",
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"js.foresight": "^4.0.0",
|
|
47
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@testing-library/react": "^16.1.0",
|
|
51
|
+
"@types/react": "^19.2.14",
|
|
52
|
+
"@types/react-dom": "^19.2.0",
|
|
53
|
+
"jsdom": "^29.0.1",
|
|
54
|
+
"react": "^19.2.4",
|
|
55
|
+
"react-dom": "^19.2.4",
|
|
56
|
+
"tsdown": "^0.21.7",
|
|
57
|
+
"typescript": "^6.0.2",
|
|
58
|
+
"vitest": "^4.1.2",
|
|
59
|
+
"js.foresight": "4.0.0"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsdown --sourcemap",
|
|
63
|
+
"build:prod": "tsdown",
|
|
64
|
+
"dev": "tsdown --sourcemap --watch",
|
|
65
|
+
"lint": "eslint . --fix",
|
|
66
|
+
"test": "vitest",
|
|
67
|
+
"test:run": "vitest run",
|
|
68
|
+
"test:watch": "vitest --watch"
|
|
69
|
+
}
|
|
70
|
+
}
|