houdini-react 2.0.0-next.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/bin/houdini-react +173 -0
  2. package/package.json +63 -39
  3. package/postInstall.js +360 -0
  4. package/runtime/Link.tsx +50 -0
  5. package/runtime/client.ts +5 -0
  6. package/runtime/clientPlugin.ts +17 -0
  7. package/runtime/componentFields.ts +79 -0
  8. package/runtime/escape.ts +15 -0
  9. package/runtime/hooks/index.ts +17 -0
  10. package/runtime/hooks/recycleNodesInto.ts +60 -0
  11. package/runtime/hooks/useDeepCompareEffect.ts +93 -0
  12. package/runtime/hooks/useDocumentHandle.ts +243 -0
  13. package/runtime/hooks/useDocumentStore.ts +112 -0
  14. package/runtime/hooks/useDocumentSubscription.ts +65 -0
  15. package/runtime/hooks/useFragment.ts +269 -0
  16. package/runtime/hooks/useFragmentHandle.ts +274 -0
  17. package/runtime/hooks/useIsMounted.ts +14 -0
  18. package/runtime/hooks/useLogoutForm.tsx +60 -0
  19. package/runtime/hooks/useMutation.ts +80 -0
  20. package/runtime/hooks/useMutationForm.tsx +163 -0
  21. package/runtime/hooks/useQuery.ts +12 -0
  22. package/runtime/hooks/useQueryHandle.ts +194 -0
  23. package/runtime/hooks/useSubscription.ts +12 -0
  24. package/runtime/hooks/useSubscriptionHandle.ts +42 -0
  25. package/runtime/hydration.tsx +186 -0
  26. package/runtime/index.tsx +77 -0
  27. package/runtime/login.ts +22 -0
  28. package/runtime/manifest.ts +6 -0
  29. package/runtime/mock.ts +9 -0
  30. package/runtime/package.json +1 -0
  31. package/runtime/resolve-href.ts +151 -0
  32. package/runtime/routes.ts +93 -0
  33. package/runtime/routing/Router.tsx +1101 -0
  34. package/runtime/routing/cache.ts +57 -0
  35. package/runtime/routing/errors.tsx +145 -0
  36. package/runtime/routing/index.ts +17 -0
  37. package/runtime/testing.tsx +163 -0
  38. package/runtime/tsconfig.json +39 -0
  39. package/server/index.d.ts +1 -0
  40. package/server/index.js +4 -0
  41. package/server/react-streaming.d.js +0 -0
  42. package/vite/index.d.ts +3 -0
  43. package/vite/index.js +397 -0
  44. package/vite/strip-headers.d.ts +1 -0
  45. package/vite/strip-headers.js +35 -0
  46. package/vite/transform.d.ts +13 -0
  47. package/vite/transform.js +105 -0
  48. package/README.md +0 -36
  49. package/build/plugin/codegen/entries/documentWrappers.d.ts +0 -6
  50. package/build/plugin/codegen/entries/fallbacks.d.ts +0 -5
  51. package/build/plugin/codegen/entries/index.d.ts +0 -16
  52. package/build/plugin/codegen/entries/pages.d.ts +0 -2
  53. package/build/plugin/codegen/index.d.ts +0 -17
  54. package/build/plugin/codegen/manifest.d.ts +0 -5
  55. package/build/plugin/codegen/render.d.ts +0 -7
  56. package/build/plugin/codegen/router.d.ts +0 -7
  57. package/build/plugin/codegen/typeRoot.d.ts +0 -5
  58. package/build/plugin/config.d.ts +0 -4
  59. package/build/plugin/dedent.d.ts +0 -1
  60. package/build/plugin/extract.d.ts +0 -6
  61. package/build/plugin/index.d.ts +0 -5
  62. package/build/plugin/state.d.ts +0 -3
  63. package/build/plugin/transform.d.ts +0 -6
  64. package/build/plugin/vite.d.ts +0 -27
  65. package/build/plugin-cjs/index.js +0 -90125
  66. package/build/plugin-cjs/package.json +0 -1
  67. package/build/plugin-esm/index.js +0 -90121
  68. package/build/runtime/client.d.ts +0 -3
  69. package/build/runtime/clientPlugin.d.ts +0 -3
  70. package/build/runtime/componentFields.d.ts +0 -9
  71. package/build/runtime/hooks/index.d.ts +0 -8
  72. package/build/runtime/hooks/useDeepCompareEffect.d.ts +0 -35
  73. package/build/runtime/hooks/useDocumentHandle.d.ts +0 -36
  74. package/build/runtime/hooks/useDocumentStore.d.ts +0 -11
  75. package/build/runtime/hooks/useDocumentSubscription.d.ts +0 -11
  76. package/build/runtime/hooks/useFragment.d.ts +0 -16
  77. package/build/runtime/hooks/useFragmentHandle.d.ts +0 -8
  78. package/build/runtime/hooks/useIsMounted.d.ts +0 -3
  79. package/build/runtime/hooks/useMutation.d.ts +0 -14
  80. package/build/runtime/hooks/useQuery.d.ts +0 -5
  81. package/build/runtime/hooks/useQueryHandle.d.ts +0 -10
  82. package/build/runtime/hooks/useSubscription.d.ts +0 -4
  83. package/build/runtime/hooks/useSubscriptionHandle.d.ts +0 -25
  84. package/build/runtime/index.d.ts +0 -14
  85. package/build/runtime/manifest.d.ts +0 -3
  86. package/build/runtime/routing/Router.d.ts +0 -62
  87. package/build/runtime/routing/cache.d.ts +0 -7
  88. package/build/runtime/routing/hooks.d.ts +0 -40
  89. package/build/runtime/routing/index.d.ts +0 -3
  90. package/build/runtime-cjs/client.d.ts +0 -3
  91. package/build/runtime-cjs/client.js +0 -25
  92. package/build/runtime-cjs/clientPlugin.d.ts +0 -3
  93. package/build/runtime-cjs/clientPlugin.js +0 -37
  94. package/build/runtime-cjs/componentFields.d.ts +0 -9
  95. package/build/runtime-cjs/componentFields.js +0 -83
  96. package/build/runtime-cjs/hooks/index.d.ts +0 -8
  97. package/build/runtime-cjs/hooks/index.js +0 -45
  98. package/build/runtime-cjs/hooks/useDeepCompareEffect.d.ts +0 -35
  99. package/build/runtime-cjs/hooks/useDeepCompareEffect.js +0 -76
  100. package/build/runtime-cjs/hooks/useDocumentHandle.d.ts +0 -36
  101. package/build/runtime-cjs/hooks/useDocumentHandle.js +0 -177
  102. package/build/runtime-cjs/hooks/useDocumentStore.d.ts +0 -11
  103. package/build/runtime-cjs/hooks/useDocumentStore.js +0 -76
  104. package/build/runtime-cjs/hooks/useDocumentSubscription.d.ts +0 -11
  105. package/build/runtime-cjs/hooks/useDocumentSubscription.js +0 -76
  106. package/build/runtime-cjs/hooks/useFragment.d.ts +0 -16
  107. package/build/runtime-cjs/hooks/useFragment.js +0 -102
  108. package/build/runtime-cjs/hooks/useFragmentHandle.d.ts +0 -8
  109. package/build/runtime-cjs/hooks/useFragmentHandle.js +0 -47
  110. package/build/runtime-cjs/hooks/useIsMounted.d.ts +0 -3
  111. package/build/runtime-cjs/hooks/useIsMounted.js +0 -38
  112. package/build/runtime-cjs/hooks/useMutation.d.ts +0 -14
  113. package/build/runtime-cjs/hooks/useMutation.js +0 -67
  114. package/build/runtime-cjs/hooks/useQuery.d.ts +0 -5
  115. package/build/runtime-cjs/hooks/useQuery.js +0 -32
  116. package/build/runtime-cjs/hooks/useQueryHandle.d.ts +0 -10
  117. package/build/runtime-cjs/hooks/useQueryHandle.js +0 -131
  118. package/build/runtime-cjs/hooks/useSubscription.d.ts +0 -4
  119. package/build/runtime-cjs/hooks/useSubscription.js +0 -32
  120. package/build/runtime-cjs/hooks/useSubscriptionHandle.d.ts +0 -25
  121. package/build/runtime-cjs/hooks/useSubscriptionHandle.js +0 -42
  122. package/build/runtime-cjs/index.d.ts +0 -14
  123. package/build/runtime-cjs/index.js +0 -88
  124. package/build/runtime-cjs/manifest.d.ts +0 -3
  125. package/build/runtime-cjs/manifest.js +0 -25
  126. package/build/runtime-cjs/package.json +0 -1
  127. package/build/runtime-cjs/routing/Router.d.ts +0 -62
  128. package/build/runtime-cjs/routing/Router.js +0 -540
  129. package/build/runtime-cjs/routing/cache.d.ts +0 -7
  130. package/build/runtime-cjs/routing/cache.js +0 -61
  131. package/build/runtime-cjs/routing/hooks.d.ts +0 -40
  132. package/build/runtime-cjs/routing/hooks.js +0 -93
  133. package/build/runtime-cjs/routing/index.d.ts +0 -3
  134. package/build/runtime-cjs/routing/index.js +0 -33
  135. package/build/runtime-esm/client.d.ts +0 -3
  136. package/build/runtime-esm/client.js +0 -5
  137. package/build/runtime-esm/clientPlugin.d.ts +0 -3
  138. package/build/runtime-esm/clientPlugin.js +0 -17
  139. package/build/runtime-esm/componentFields.d.ts +0 -9
  140. package/build/runtime-esm/componentFields.js +0 -59
  141. package/build/runtime-esm/hooks/index.d.ts +0 -8
  142. package/build/runtime-esm/hooks/index.js +0 -15
  143. package/build/runtime-esm/hooks/useDeepCompareEffect.d.ts +0 -35
  144. package/build/runtime-esm/hooks/useDeepCompareEffect.js +0 -41
  145. package/build/runtime-esm/hooks/useDocumentHandle.d.ts +0 -36
  146. package/build/runtime-esm/hooks/useDocumentHandle.js +0 -143
  147. package/build/runtime-esm/hooks/useDocumentStore.d.ts +0 -11
  148. package/build/runtime-esm/hooks/useDocumentStore.js +0 -42
  149. package/build/runtime-esm/hooks/useDocumentSubscription.d.ts +0 -11
  150. package/build/runtime-esm/hooks/useDocumentSubscription.js +0 -42
  151. package/build/runtime-esm/hooks/useFragment.d.ts +0 -16
  152. package/build/runtime-esm/hooks/useFragment.js +0 -67
  153. package/build/runtime-esm/hooks/useFragmentHandle.d.ts +0 -8
  154. package/build/runtime-esm/hooks/useFragmentHandle.js +0 -23
  155. package/build/runtime-esm/hooks/useIsMounted.d.ts +0 -3
  156. package/build/runtime-esm/hooks/useIsMounted.js +0 -14
  157. package/build/runtime-esm/hooks/useMutation.d.ts +0 -14
  158. package/build/runtime-esm/hooks/useMutation.js +0 -42
  159. package/build/runtime-esm/hooks/useQuery.d.ts +0 -5
  160. package/build/runtime-esm/hooks/useQuery.js +0 -8
  161. package/build/runtime-esm/hooks/useQueryHandle.d.ts +0 -10
  162. package/build/runtime-esm/hooks/useQueryHandle.js +0 -97
  163. package/build/runtime-esm/hooks/useSubscription.d.ts +0 -4
  164. package/build/runtime-esm/hooks/useSubscription.js +0 -8
  165. package/build/runtime-esm/hooks/useSubscriptionHandle.d.ts +0 -25
  166. package/build/runtime-esm/hooks/useSubscriptionHandle.js +0 -18
  167. package/build/runtime-esm/index.d.ts +0 -14
  168. package/build/runtime-esm/index.js +0 -48
  169. package/build/runtime-esm/manifest.d.ts +0 -3
  170. package/build/runtime-esm/manifest.js +0 -5
  171. package/build/runtime-esm/routing/Router.d.ts +0 -62
  172. package/build/runtime-esm/routing/Router.js +0 -499
  173. package/build/runtime-esm/routing/cache.d.ts +0 -7
  174. package/build/runtime-esm/routing/cache.js +0 -36
  175. package/build/runtime-esm/routing/hooks.d.ts +0 -40
  176. package/build/runtime-esm/routing/hooks.js +0 -53
  177. package/build/runtime-esm/routing/index.d.ts +0 -3
  178. package/build/runtime-esm/routing/index.js +0 -6
  179. package/build/server/index.d.ts +0 -1
  180. package/build/server-cjs/index.js +0 -28
  181. package/build/server-cjs/package.json +0 -1
  182. package/build/server-esm/index.js +0 -4
  183. package/build/server-esm/package.json +0 -1
  184. /package/{build/plugin-esm → server}/package.json +0 -0
  185. /package/{build/runtime-esm → vite}/package.json +0 -0
@@ -0,0 +1,57 @@
1
+ // a suspense cache is an object that maintains a key-value store of
2
+ // objects. If a value is missing when get() is called, a promise
3
+ // is thrown that resolves when a value is passed to set()
4
+ import { LRUCache } from 'houdini/runtime'
5
+
6
+ export function suspense_cache<T>(initialData?: Record<string, T>): SuspenseCache<T> {
7
+ const cache = new SuspenseCache<T>()
8
+
9
+ for (const [key, value] of Object.entries(initialData ?? {})) {
10
+ cache.set(key, value)
11
+ }
12
+
13
+ return cache
14
+ }
15
+
16
+ export class SuspenseCache<_Data> extends LRUCache<_Data> {
17
+ // if get is called before set, we need to invoke a callback.
18
+ // that means we need a place to put our callbacks
19
+ #callbacks: Map<string, { resolve: () => void; reject: () => void }[]> = new Map()
20
+
21
+ get(key: string): _Data {
22
+ // if there is a value, use that
23
+ if (super.has(key)) {
24
+ return super.get(key)!
25
+ }
26
+
27
+ // we don't have a value, so we need to throw a promise
28
+ // that resolves when a value is passed to set()
29
+ throw new Promise<void>((resolve, reject) => {
30
+ this.#subscribe(key, resolve, reject)
31
+ })
32
+ }
33
+
34
+ override clear() {
35
+ super.clear()
36
+ this.#callbacks.clear()
37
+ }
38
+
39
+ set(key: string, value: _Data) {
40
+ // perform the set like normal
41
+ super.set(key, value)
42
+
43
+ // if there are subscribers, resolve them
44
+ if (this.#callbacks.has(key)) {
45
+ // resolve all of the callbacks
46
+ this.#callbacks.get(key)?.forEach(({ resolve }) => {
47
+ resolve()
48
+ })
49
+ // delete the key
50
+ this.#callbacks.delete(key)
51
+ }
52
+ }
53
+
54
+ #subscribe(key: string, resolve: () => void, reject: () => void) {
55
+ this.#callbacks.set(key, [...(this.#callbacks.get(key) || []), { resolve, reject }])
56
+ }
57
+ }
@@ -0,0 +1,145 @@
1
+ import type { GraphQLError } from 'houdini/runtime'
2
+ import React from 'react'
3
+
4
+ export class GraphQLErrors extends Error {
5
+ graphqlErrors: GraphQLError[]
6
+
7
+ constructor(errors: GraphQLError[]) {
8
+ super(errors.map((e) => e.message).join('\n'))
9
+ this.name = 'GraphQLErrors'
10
+ this.graphqlErrors = errors
11
+ }
12
+ }
13
+
14
+ let _currentSegment: string | undefined
15
+
16
+ export function setCurrentSegment(id: string | undefined): void {
17
+ _currentSegment = id
18
+ }
19
+
20
+ function getCurrentSegment(): string | undefined {
21
+ return _currentSegment
22
+ }
23
+
24
+ export class RoutingError extends Error {
25
+ status: number
26
+ segment: string | undefined
27
+
28
+ constructor(status: number) {
29
+ super(`Routing error: ${status}`)
30
+ this.name = 'RoutingError'
31
+ this.status = status
32
+ this.segment = getCurrentSegment()
33
+ }
34
+ }
35
+
36
+ export class RedirectError extends Error {
37
+ status: number
38
+ location: string
39
+
40
+ constructor(status: number, location: string) {
41
+ super(`Redirect: ${status} ${location}`)
42
+ this.name = 'RedirectError'
43
+ this.status = status
44
+ this.location = location
45
+ }
46
+ }
47
+
48
+ export function isRoutingError(error: unknown): error is RoutingError {
49
+ return error instanceof RoutingError
50
+ }
51
+
52
+ export function isApiError(error: unknown): error is GraphQLErrors {
53
+ return error instanceof GraphQLErrors
54
+ }
55
+
56
+ export function notFound(): never {
57
+ throw new RoutingError(404)
58
+ }
59
+
60
+ export function unauthorized(): never {
61
+ throw new RoutingError(401)
62
+ }
63
+
64
+ export function forbidden(): never {
65
+ throw new RoutingError(403)
66
+ }
67
+
68
+ export function httpError(status: number): never {
69
+ throw new RoutingError(status)
70
+ }
71
+
72
+ export function redirect(status: 300 | 301 | 302 | 303 | 307 | 308, location: string): never {
73
+ throw new RedirectError(status, location)
74
+ }
75
+
76
+ // Mutable ref passed from the server renderer so that a synchronous RoutingError
77
+ // or redirect() can propagate the correct HTTP status/location before streaming.
78
+ export const StatusContext = React.createContext<{ status: number; location?: string } | null>(null)
79
+
80
+ type HoudiniErrorBoundaryProps = {
81
+ errorView: React.ComponentType<{
82
+ errors: Array<Error | GraphQLError>
83
+ children: React.ReactNode
84
+ }>
85
+ children: React.ReactNode
86
+ }
87
+
88
+ type HoudiniErrorBoundaryState = {
89
+ hasError: boolean
90
+ errors: Array<Error | GraphQLError>
91
+ }
92
+
93
+ export class HoudiniErrorBoundary extends React.Component<
94
+ HoudiniErrorBoundaryProps,
95
+ HoudiniErrorBoundaryState
96
+ > {
97
+ static contextType = StatusContext
98
+ declare context: React.ContextType<typeof StatusContext>
99
+
100
+ constructor(
101
+ props: HoudiniErrorBoundaryProps,
102
+ context: React.ContextType<typeof StatusContext>
103
+ ) {
104
+ super(props, context)
105
+ // Second-pass SSR: statusRef is pre-set to an error status by on_render after the first
106
+ // render threw. Start in error state immediately so children never render (and never throw).
107
+ if (typeof window === 'undefined' && context && context.status >= 400) {
108
+ this.state = {
109
+ hasError: true,
110
+ errors: [new RoutingError(context.status)],
111
+ }
112
+ } else {
113
+ this.state = { hasError: false, errors: [] }
114
+ }
115
+ }
116
+
117
+ static getDerivedStateFromError(error: unknown): HoudiniErrorBoundaryState {
118
+ if (error instanceof GraphQLErrors) {
119
+ return { hasError: true, errors: error.graphqlErrors }
120
+ }
121
+ return {
122
+ hasError: true,
123
+ errors: [error instanceof Error ? error : new Error(String(error))],
124
+ }
125
+ }
126
+
127
+ componentDidCatch(error: Error): void {
128
+ if (this.context) {
129
+ if (error instanceof RoutingError) {
130
+ this.context.status = error.status
131
+ } else if (error instanceof RedirectError) {
132
+ this.context.status = error.status
133
+ this.context.location = error.location
134
+ }
135
+ }
136
+ }
137
+
138
+ render() {
139
+ if (this.state.hasError) {
140
+ const ErrorView = this.props.errorView
141
+ return <ErrorView errors={this.state.errors}>{this.props.children}</ErrorView>
142
+ }
143
+ return this.props.children
144
+ }
145
+ }
@@ -0,0 +1,17 @@
1
+ export * from './Router.js'
2
+ export { type SuspenseCache, suspense_cache } from './cache.js'
3
+ export {
4
+ HoudiniErrorBoundary,
5
+ GraphQLErrors,
6
+ RoutingError,
7
+ RedirectError,
8
+ notFound,
9
+ unauthorized,
10
+ forbidden,
11
+ httpError,
12
+ redirect,
13
+ isRoutingError,
14
+ isApiError,
15
+ StatusContext,
16
+ setCurrentSegment,
17
+ } from './errors.js'
@@ -0,0 +1,163 @@
1
+ // @refresh reset
2
+ import { getCurrentConfig } from '$houdini/runtime/config'
3
+ import { Cache } from 'houdini/runtime/cache'
4
+ import { DataSource } from 'houdini/runtime/types'
5
+ import { HoudiniClient } from '$houdini/runtime/client'
6
+ import React from 'react'
7
+
8
+ import { scalarMarshalers, serializeSearch } from './resolve-href.js'
9
+ import { Router as RouterImpl, RouterContextProvider, router_cache } from './routing/index.js'
10
+ import manifest from './manifest.js'
11
+
12
+ type MockValue =
13
+ | Record<string, unknown>
14
+ | ((vars: any) => Record<string, unknown>)
15
+ | AsyncIterable<Record<string, unknown>>
16
+ | ((vars: any) => AsyncIterable<Record<string, unknown>>)
17
+
18
+ // buildMockPath turns a route pattern, its params, and an optional search object into
19
+ // the concrete path a test wants to render. The typed createMock wrapper calls this so
20
+ // that param substitution (and its missing-param error) and search serialization both
21
+ // happen before the path reaches _createMock.
22
+ export function buildMockPath(
23
+ pattern: string,
24
+ params: Record<string, string>,
25
+ search?: Record<string, unknown>
26
+ ): string {
27
+ if (!search) {
28
+ return buildURL(pattern, params)
29
+ }
30
+ // marshal custom-scalar search values the same way <Link> does, so tests exercise
31
+ // the real serialization path
32
+ const m = manifest as any
33
+ const page = m.pages[m.pagesByUrl[pattern]] as
34
+ | { searchParams?: ReadonlyArray<{ name: string; type: string }> }
35
+ | undefined
36
+ const marshalers = scalarMarshalers(page?.searchParams, getCurrentConfig()?.scalars)
37
+ return buildURL(pattern, params) + serializeSearch(search, marshalers)
38
+ }
39
+
40
+ export function _createMock({
41
+ path,
42
+ data: mocks,
43
+ }: {
44
+ path: string
45
+ data: Record<string, MockValue>
46
+ }): React.ComponentType<{}> {
47
+ // the route patterns are anchored to the path, so strip any search string
48
+ // before matching
49
+ const pathname = path.split('?')[0]
50
+
51
+ // Validate required mocks up-front at the call site so the error points
52
+ // directly to the createMock() call rather than surfacing during rendering.
53
+ const pages = manifest.pages as Record<
54
+ string,
55
+ { pattern: RegExp; documents: Record<string, unknown> }
56
+ >
57
+ const page = Object.values(pages).find((p) => p.pattern.test(pathname))
58
+ if (page) {
59
+ const missing = Object.keys(page.documents).filter((name) => !(name in mocks))
60
+ if (missing.length > 0) {
61
+ throw new Error(
62
+ `createMock: missing mock data for ${missing.map((n) => `"${n}"`).join(', ')} on route "${pathname}". Add ${missing.length === 1 ? 'it' : 'them'} to the data object passed to createMock.`
63
+ )
64
+ }
65
+ }
66
+
67
+ const cache = new Cache(getCurrentConfig())
68
+
69
+ const mockPlugin = () => ({
70
+ network(ctx: any, { resolve }: any) {
71
+ const mock = mocks[ctx.artifact.name]
72
+ if (mock === undefined) {
73
+ throw new Error(
74
+ `createMock: "${ctx.artifact.name}" fired but was not in data. Add it to the data object passed to createMock.`
75
+ )
76
+ }
77
+
78
+ if (ctx.artifact.kind === 'HoudiniSubscription') {
79
+ const iterable =
80
+ typeof mock === 'function'
81
+ ? (mock as (v: any) => AsyncIterable<Record<string, unknown>>)(
82
+ ctx.variables ?? {}
83
+ )
84
+ : (mock as AsyncIterable<Record<string, unknown>>)
85
+ const iterator = iterable[Symbol.asyncIterator]()
86
+ ctx.abortController.signal.addEventListener(
87
+ 'abort',
88
+ () => {
89
+ iterator.return?.()
90
+ },
91
+ { once: true }
92
+ )
93
+ ;(async () => {
94
+ for await (const data of { [Symbol.asyncIterator]: () => iterator }) {
95
+ if (ctx.abortController.signal.aborted) break
96
+ resolve(ctx, {
97
+ data,
98
+ errors: null,
99
+ fetching: false,
100
+ variables: null,
101
+ source: DataSource.Network,
102
+ partial: false,
103
+ stale: false,
104
+ })
105
+ }
106
+ })()
107
+ return
108
+ }
109
+
110
+ const data = typeof mock === 'function' ? mock(ctx.variables ?? {}) : mock
111
+ resolve(ctx, {
112
+ data,
113
+ errors: null,
114
+ fetching: false,
115
+ variables: null,
116
+ source: DataSource.Network,
117
+ partial: false,
118
+ stale: false,
119
+ })
120
+ },
121
+ })
122
+
123
+ // Pass the same fresh cache to the client so the cache policy plugin doesn't
124
+ // reach into the global cacheRef singleton and return stale data from previous tests.
125
+ // the mockPlugin intercepts the network, so no url is needed (and the client no longer takes one)
126
+ const mockClient = new HoudiniClient({
127
+ plugins: [mockPlugin as any],
128
+ cache,
129
+ })
130
+
131
+ return function MockApp() {
132
+ const cachesRef = React.useRef<ReturnType<typeof router_cache> | null>(null)
133
+ if (cachesRef.current === null) {
134
+ cachesRef.current = router_cache()
135
+ }
136
+ const caches = cachesRef.current
137
+ return (
138
+ <RouterContextProvider
139
+ client={mockClient}
140
+ cache={cache}
141
+ artifact_cache={caches.artifact_cache}
142
+ component_cache={caches.component_cache}
143
+ data_cache={caches.data_cache}
144
+ ssr_signals={caches.ssr_signals}
145
+ last_variables={caches.last_variables}
146
+ >
147
+ <React.Suspense fallback={null}>
148
+ <RouterImpl manifest={manifest} initialURL={path} assetPrefix="" />
149
+ </React.Suspense>
150
+ </RouterContextProvider>
151
+ )
152
+ }
153
+ }
154
+
155
+ function buildURL(pattern: string, params: Record<string, string>): string {
156
+ return pattern.replace(/\[([^\]]+)\]/g, (_, key) => {
157
+ const value = params[key]
158
+ if (value === undefined) {
159
+ throw new Error(`createMock: missing param "${key}" for pattern "${pattern}"`)
160
+ }
161
+ return String(value)
162
+ })
163
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "paths": {
5
+ "$houdini": ["."],
6
+ "$houdini/*": ["./*"],
7
+ "~": ["../src"],
8
+ "~/*": ["../src/*"]
9
+ },
10
+ "rootDirs": ["..", "./types"],
11
+ "target": "ESNext",
12
+ "useDefineForClassFields": true,
13
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
14
+ "allowJs": true,
15
+ "skipLibCheck": true,
16
+ "esModuleInterop": false,
17
+ "allowSyntheticDefaultImports": true,
18
+ "strict": true,
19
+ "forceConsistentCasingInFileNames": true,
20
+ "module": "ESNext",
21
+ "moduleResolution": "Bundler",
22
+ "allowImportingTsExtensions": true,
23
+ "resolveJsonModule": true,
24
+ "isolatedModules": true,
25
+ "noEmit": true,
26
+ "jsx": "react-jsx"
27
+ },
28
+ "include": [
29
+ "ambient.d.ts",
30
+ "./types/**/$types.d.ts",
31
+ "../vite.config.ts",
32
+ "../src/**/*.js",
33
+ "../src/**/*.ts",
34
+ "../src/**/*.jsx",
35
+ "../src/**/*.tsx",
36
+ "../src/+app.d.ts"
37
+ ],
38
+ "exclude": ["../node_modules/**", "./[!ambient.d.ts]**"]
39
+ }
@@ -0,0 +1 @@
1
+ export { renderToStream } from 'react-streaming/server';
@@ -0,0 +1,4 @@
1
+ import { renderToStream } from "react-streaming/server";
2
+ export {
3
+ renderToStream
4
+ };
File without changes
@@ -0,0 +1,3 @@
1
+ import { VitePluginContext } from 'houdini/vite';
2
+ import { PluginOption } from 'vite';
3
+ export default function (ctx: VitePluginContext): PluginOption;