This commit is contained in:
@@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
import { Route as rootRoute } from './routes/__root'
|
import { Route as rootRoute } from './routes/__root'
|
||||||
import { Route as TimeImport } from './routes/time'
|
import { Route as TimeImport } from './routes/time'
|
||||||
|
import { Route as TestsImport } from './routes/tests'
|
||||||
import { Route as CountImport } from './routes/count'
|
import { Route as CountImport } from './routes/count'
|
||||||
|
import { Route as BlankImport } from './routes/blank'
|
||||||
import { Route as IndexImport } from './routes/index'
|
import { Route as IndexImport } from './routes/index'
|
||||||
|
|
||||||
// Create/Update Routes
|
// Create/Update Routes
|
||||||
@@ -23,12 +25,24 @@ const TimeRoute = TimeImport.update({
|
|||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
|
const TestsRoute = TestsImport.update({
|
||||||
|
id: '/tests',
|
||||||
|
path: '/tests',
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
} as any)
|
||||||
|
|
||||||
const CountRoute = CountImport.update({
|
const CountRoute = CountImport.update({
|
||||||
id: '/count',
|
id: '/count',
|
||||||
path: '/count',
|
path: '/count',
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
|
const BlankRoute = BlankImport.update({
|
||||||
|
id: '/blank',
|
||||||
|
path: '/blank',
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
} as any)
|
||||||
|
|
||||||
const IndexRoute = IndexImport.update({
|
const IndexRoute = IndexImport.update({
|
||||||
id: '/',
|
id: '/',
|
||||||
path: '/',
|
path: '/',
|
||||||
@@ -46,6 +60,13 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof IndexImport
|
preLoaderRoute: typeof IndexImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
}
|
}
|
||||||
|
'/blank': {
|
||||||
|
id: '/blank'
|
||||||
|
path: '/blank'
|
||||||
|
fullPath: '/blank'
|
||||||
|
preLoaderRoute: typeof BlankImport
|
||||||
|
parentRoute: typeof rootRoute
|
||||||
|
}
|
||||||
'/count': {
|
'/count': {
|
||||||
id: '/count'
|
id: '/count'
|
||||||
path: '/count'
|
path: '/count'
|
||||||
@@ -53,6 +74,13 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof CountImport
|
preLoaderRoute: typeof CountImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
}
|
}
|
||||||
|
'/tests': {
|
||||||
|
id: '/tests'
|
||||||
|
path: '/tests'
|
||||||
|
fullPath: '/tests'
|
||||||
|
preLoaderRoute: typeof TestsImport
|
||||||
|
parentRoute: typeof rootRoute
|
||||||
|
}
|
||||||
'/time': {
|
'/time': {
|
||||||
id: '/time'
|
id: '/time'
|
||||||
path: '/time'
|
path: '/time'
|
||||||
@@ -67,41 +95,51 @@ declare module '@tanstack/react-router' {
|
|||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
|
'/blank': typeof BlankRoute
|
||||||
'/count': typeof CountRoute
|
'/count': typeof CountRoute
|
||||||
|
'/tests': typeof TestsRoute
|
||||||
'/time': typeof TimeRoute
|
'/time': typeof TimeRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
|
'/blank': typeof BlankRoute
|
||||||
'/count': typeof CountRoute
|
'/count': typeof CountRoute
|
||||||
|
'/tests': typeof TestsRoute
|
||||||
'/time': typeof TimeRoute
|
'/time': typeof TimeRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileRoutesById {
|
export interface FileRoutesById {
|
||||||
__root__: typeof rootRoute
|
__root__: typeof rootRoute
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
|
'/blank': typeof BlankRoute
|
||||||
'/count': typeof CountRoute
|
'/count': typeof CountRoute
|
||||||
|
'/tests': typeof TestsRoute
|
||||||
'/time': typeof TimeRoute
|
'/time': typeof TimeRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileRouteTypes {
|
export interface FileRouteTypes {
|
||||||
fileRoutesByFullPath: FileRoutesByFullPath
|
fileRoutesByFullPath: FileRoutesByFullPath
|
||||||
fullPaths: '/' | '/count' | '/time'
|
fullPaths: '/' | '/blank' | '/count' | '/tests' | '/time'
|
||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to: '/' | '/count' | '/time'
|
to: '/' | '/blank' | '/count' | '/tests' | '/time'
|
||||||
id: '__root__' | '/' | '/count' | '/time'
|
id: '__root__' | '/' | '/blank' | '/count' | '/tests' | '/time'
|
||||||
fileRoutesById: FileRoutesById
|
fileRoutesById: FileRoutesById
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RootRouteChildren {
|
export interface RootRouteChildren {
|
||||||
IndexRoute: typeof IndexRoute
|
IndexRoute: typeof IndexRoute
|
||||||
|
BlankRoute: typeof BlankRoute
|
||||||
CountRoute: typeof CountRoute
|
CountRoute: typeof CountRoute
|
||||||
|
TestsRoute: typeof TestsRoute
|
||||||
TimeRoute: typeof TimeRoute
|
TimeRoute: typeof TimeRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootRouteChildren: RootRouteChildren = {
|
const rootRouteChildren: RootRouteChildren = {
|
||||||
IndexRoute: IndexRoute,
|
IndexRoute: IndexRoute,
|
||||||
|
BlankRoute: BlankRoute,
|
||||||
CountRoute: CountRoute,
|
CountRoute: CountRoute,
|
||||||
|
TestsRoute: TestsRoute,
|
||||||
TimeRoute: TimeRoute,
|
TimeRoute: TimeRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,16 +154,24 @@ export const routeTree = rootRoute
|
|||||||
"filePath": "__root.tsx",
|
"filePath": "__root.tsx",
|
||||||
"children": [
|
"children": [
|
||||||
"/",
|
"/",
|
||||||
|
"/blank",
|
||||||
"/count",
|
"/count",
|
||||||
|
"/tests",
|
||||||
"/time"
|
"/time"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"/": {
|
"/": {
|
||||||
"filePath": "index.tsx"
|
"filePath": "index.tsx"
|
||||||
},
|
},
|
||||||
|
"/blank": {
|
||||||
|
"filePath": "blank.tsx"
|
||||||
|
},
|
||||||
"/count": {
|
"/count": {
|
||||||
"filePath": "count.tsx"
|
"filePath": "count.tsx"
|
||||||
},
|
},
|
||||||
|
"/tests": {
|
||||||
|
"filePath": "tests.tsx"
|
||||||
|
},
|
||||||
"/time": {
|
"/time": {
|
||||||
"filePath": "time.tsx"
|
"filePath": "time.tsx"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ function Root() {
|
|||||||
<Link to="/">Index</Link>
|
<Link to="/">Index</Link>
|
||||||
<Link to="/time">Time</Link>
|
<Link to="/time">Time</Link>
|
||||||
<Link to="/count">Count</Link>
|
<Link to="/count">Count</Link>
|
||||||
|
<Link to="/tests">Tests</Link>
|
||||||
|
<Link to="/blank">Blank</Link>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
|
|||||||
9
packages/example/src/routes/blank.tsx
Normal file
9
packages/example/src/routes/blank.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { createFileRoute } from '@tanstack/react-router'
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/blank')({
|
||||||
|
component: RouteComponent,
|
||||||
|
})
|
||||||
|
|
||||||
|
function RouteComponent() {
|
||||||
|
return <div>Hello "/blank"!</div>
|
||||||
|
}
|
||||||
16
packages/example/src/routes/tests.tsx
Normal file
16
packages/example/src/routes/tests.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { R } from "@/reffuse"
|
||||||
|
import { createFileRoute } from "@tanstack/react-router"
|
||||||
|
import { Console, Effect } from "effect"
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/tests")({
|
||||||
|
component: RouteComponent
|
||||||
|
})
|
||||||
|
|
||||||
|
function RouteComponent() {
|
||||||
|
R.useMemo(Effect.addFinalizer(() => Console.log("Cleanup!")).pipe(
|
||||||
|
Effect.map(() => "test")
|
||||||
|
))
|
||||||
|
|
||||||
|
return <div>Hello "/tests"!</div>
|
||||||
|
}
|
||||||
@@ -66,6 +66,43 @@ export class Reffuse<R> {
|
|||||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||||
*/
|
*/
|
||||||
useMemo<A, E>(
|
useMemo<A, E>(
|
||||||
|
effect: Effect.Effect<A, E, R | Scope.Scope>,
|
||||||
|
deps?: React.DependencyList,
|
||||||
|
options?: RenderOptions & ScopeOptions,
|
||||||
|
): A {
|
||||||
|
const runSync = this.useRunSync()
|
||||||
|
|
||||||
|
const [value, scope] = React.useMemo(() => Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||||
|
Effect.flatMap(scope =>
|
||||||
|
Effect.provideService(effect, Scope.Scope, scope).pipe(
|
||||||
|
Effect.map(value => [value, scope] as const)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
runSync,
|
||||||
|
), [
|
||||||
|
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||||
|
...(deps ?? []),
|
||||||
|
])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
console.log("effect", value, scope)
|
||||||
|
// return () => { console.log("cleanup", value, scope); runSync(Scope.close(scope, Exit.void)) }
|
||||||
|
}, [scope])
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reffuse equivalent to `React.useMemo`.
|
||||||
|
*
|
||||||
|
* `useMemo` will only recompute the memoized value by running the given synchronous effect when one of the deps has changed. \
|
||||||
|
* Trying to run an asynchronous effect will throw.
|
||||||
|
*
|
||||||
|
* Changes to the Reffuse runtime or context will recompute the value in addition to the deps.
|
||||||
|
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||||
|
*/
|
||||||
|
useMemoUnscoped<A, E>(
|
||||||
effect: Effect.Effect<A, E, R>,
|
effect: Effect.Effect<A, E, R>,
|
||||||
deps?: React.DependencyList,
|
deps?: React.DependencyList,
|
||||||
options?: RenderOptions,
|
options?: RenderOptions,
|
||||||
@@ -238,14 +275,14 @@ export class Reffuse<R> {
|
|||||||
|
|
||||||
|
|
||||||
useRef<A>(value: A): SubscriptionRef.SubscriptionRef<A> {
|
useRef<A>(value: A): SubscriptionRef.SubscriptionRef<A> {
|
||||||
return this.useMemo(
|
return this.useMemoUnscoped(
|
||||||
SubscriptionRef.make(value),
|
SubscriptionRef.make(value),
|
||||||
[],
|
[],
|
||||||
{ doNotReExecuteOnRuntimeOrContextChange: false }, // Do not recreate the ref when the context changes
|
{ doNotReExecuteOnRuntimeOrContextChange: false }, // Do not recreate the ref when the context changes
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
useRefFromEffect<A, E>(effect: Effect.Effect<A, E, R>): SubscriptionRef.SubscriptionRef<A> {
|
useRefFromEffect<A, E>(effect: Effect.Effect<A, E, R | Scope.Scope>): SubscriptionRef.SubscriptionRef<A> {
|
||||||
return this.useMemo(
|
return this.useMemo(
|
||||||
effect.pipe(Effect.flatMap(SubscriptionRef.make)),
|
effect.pipe(Effect.flatMap(SubscriptionRef.make)),
|
||||||
[],
|
[],
|
||||||
|
|||||||
Reference in New Issue
Block a user