houdini-react 2.0.0-next.2 → 2.0.0-next.23

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 (171) hide show
  1. package/bin/houdini-react +88 -0
  2. package/package.json +43 -22
  3. package/postInstall.js +353 -0
  4. package/runtime/client.ts +5 -0
  5. package/runtime/clientPlugin.ts +17 -0
  6. package/runtime/componentFields.ts +79 -0
  7. package/runtime/hooks/index.ts +9 -0
  8. package/runtime/hooks/useDeepCompareEffect.ts +91 -0
  9. package/runtime/hooks/useDocumentHandle.ts +232 -0
  10. package/runtime/hooks/useDocumentStore.ts +76 -0
  11. package/runtime/hooks/useDocumentSubscription.ts +62 -0
  12. package/runtime/hooks/useFragment.ts +93 -0
  13. package/runtime/hooks/useFragmentHandle.ts +46 -0
  14. package/runtime/hooks/useIsMounted.ts +14 -0
  15. package/runtime/hooks/useMutation.ts +70 -0
  16. package/runtime/hooks/useQuery.ts +12 -0
  17. package/runtime/hooks/useQueryHandle.ts +185 -0
  18. package/runtime/hooks/useSubscription.ts +12 -0
  19. package/runtime/hooks/useSubscriptionHandle.ts +33 -0
  20. package/runtime/hydration.tsx +155 -0
  21. package/runtime/index.tsx +49 -0
  22. package/runtime/manifest.ts +6 -0
  23. package/runtime/package.json +1 -0
  24. package/runtime/routing/Router.tsx +885 -0
  25. package/runtime/routing/cache.ts +54 -0
  26. package/runtime/routing/index.ts +2 -0
  27. package/server/index.d.ts +1 -0
  28. package/server/index.js +4 -0
  29. package/server/react-streaming.d.js +0 -0
  30. package/vite/index.d.ts +3 -0
  31. package/vite/index.js +284 -0
  32. package/vite/transform.d.ts +11 -0
  33. package/vite/transform.js +92 -0
  34. package/README.md +0 -36
  35. package/build/plugin/codegen/entries/documentWrappers.d.ts +0 -6
  36. package/build/plugin/codegen/entries/fallbacks.d.ts +0 -5
  37. package/build/plugin/codegen/entries/index.d.ts +0 -16
  38. package/build/plugin/codegen/entries/pages.d.ts +0 -2
  39. package/build/plugin/codegen/index.d.ts +0 -17
  40. package/build/plugin/codegen/manifest.d.ts +0 -5
  41. package/build/plugin/codegen/render.d.ts +0 -7
  42. package/build/plugin/codegen/router.d.ts +0 -7
  43. package/build/plugin/codegen/typeRoot.d.ts +0 -5
  44. package/build/plugin/config.d.ts +0 -4
  45. package/build/plugin/dedent.d.ts +0 -1
  46. package/build/plugin/extract.d.ts +0 -6
  47. package/build/plugin/index.d.ts +0 -5
  48. package/build/plugin/state.d.ts +0 -3
  49. package/build/plugin/transform.d.ts +0 -6
  50. package/build/plugin/vite.d.ts +0 -27
  51. package/build/plugin-cjs/index.js +0 -90119
  52. package/build/plugin-cjs/package.json +0 -1
  53. package/build/plugin-esm/index.js +0 -90115
  54. package/build/runtime/client.d.ts +0 -3
  55. package/build/runtime/clientPlugin.d.ts +0 -3
  56. package/build/runtime/componentFields.d.ts +0 -9
  57. package/build/runtime/hooks/index.d.ts +0 -8
  58. package/build/runtime/hooks/useDeepCompareEffect.d.ts +0 -35
  59. package/build/runtime/hooks/useDocumentHandle.d.ts +0 -36
  60. package/build/runtime/hooks/useDocumentStore.d.ts +0 -11
  61. package/build/runtime/hooks/useDocumentSubscription.d.ts +0 -11
  62. package/build/runtime/hooks/useFragment.d.ts +0 -16
  63. package/build/runtime/hooks/useFragmentHandle.d.ts +0 -8
  64. package/build/runtime/hooks/useIsMounted.d.ts +0 -3
  65. package/build/runtime/hooks/useMutation.d.ts +0 -14
  66. package/build/runtime/hooks/useQuery.d.ts +0 -5
  67. package/build/runtime/hooks/useQueryHandle.d.ts +0 -10
  68. package/build/runtime/hooks/useSubscription.d.ts +0 -4
  69. package/build/runtime/hooks/useSubscriptionHandle.d.ts +0 -25
  70. package/build/runtime/index.d.ts +0 -14
  71. package/build/runtime/manifest.d.ts +0 -3
  72. package/build/runtime/routing/Router.d.ts +0 -62
  73. package/build/runtime/routing/cache.d.ts +0 -7
  74. package/build/runtime/routing/hooks.d.ts +0 -40
  75. package/build/runtime/routing/index.d.ts +0 -3
  76. package/build/runtime-cjs/client.d.ts +0 -3
  77. package/build/runtime-cjs/client.js +0 -25
  78. package/build/runtime-cjs/clientPlugin.d.ts +0 -3
  79. package/build/runtime-cjs/clientPlugin.js +0 -37
  80. package/build/runtime-cjs/componentFields.d.ts +0 -9
  81. package/build/runtime-cjs/componentFields.js +0 -83
  82. package/build/runtime-cjs/hooks/index.d.ts +0 -8
  83. package/build/runtime-cjs/hooks/index.js +0 -45
  84. package/build/runtime-cjs/hooks/useDeepCompareEffect.d.ts +0 -35
  85. package/build/runtime-cjs/hooks/useDeepCompareEffect.js +0 -76
  86. package/build/runtime-cjs/hooks/useDocumentHandle.d.ts +0 -36
  87. package/build/runtime-cjs/hooks/useDocumentHandle.js +0 -177
  88. package/build/runtime-cjs/hooks/useDocumentStore.d.ts +0 -11
  89. package/build/runtime-cjs/hooks/useDocumentStore.js +0 -76
  90. package/build/runtime-cjs/hooks/useDocumentSubscription.d.ts +0 -11
  91. package/build/runtime-cjs/hooks/useDocumentSubscription.js +0 -76
  92. package/build/runtime-cjs/hooks/useFragment.d.ts +0 -16
  93. package/build/runtime-cjs/hooks/useFragment.js +0 -102
  94. package/build/runtime-cjs/hooks/useFragmentHandle.d.ts +0 -8
  95. package/build/runtime-cjs/hooks/useFragmentHandle.js +0 -47
  96. package/build/runtime-cjs/hooks/useIsMounted.d.ts +0 -3
  97. package/build/runtime-cjs/hooks/useIsMounted.js +0 -38
  98. package/build/runtime-cjs/hooks/useMutation.d.ts +0 -14
  99. package/build/runtime-cjs/hooks/useMutation.js +0 -67
  100. package/build/runtime-cjs/hooks/useQuery.d.ts +0 -5
  101. package/build/runtime-cjs/hooks/useQuery.js +0 -32
  102. package/build/runtime-cjs/hooks/useQueryHandle.d.ts +0 -10
  103. package/build/runtime-cjs/hooks/useQueryHandle.js +0 -131
  104. package/build/runtime-cjs/hooks/useSubscription.d.ts +0 -4
  105. package/build/runtime-cjs/hooks/useSubscription.js +0 -32
  106. package/build/runtime-cjs/hooks/useSubscriptionHandle.d.ts +0 -25
  107. package/build/runtime-cjs/hooks/useSubscriptionHandle.js +0 -42
  108. package/build/runtime-cjs/index.d.ts +0 -14
  109. package/build/runtime-cjs/index.js +0 -88
  110. package/build/runtime-cjs/manifest.d.ts +0 -3
  111. package/build/runtime-cjs/manifest.js +0 -25
  112. package/build/runtime-cjs/package.json +0 -1
  113. package/build/runtime-cjs/routing/Router.d.ts +0 -62
  114. package/build/runtime-cjs/routing/Router.js +0 -540
  115. package/build/runtime-cjs/routing/cache.d.ts +0 -7
  116. package/build/runtime-cjs/routing/cache.js +0 -61
  117. package/build/runtime-cjs/routing/hooks.d.ts +0 -40
  118. package/build/runtime-cjs/routing/hooks.js +0 -93
  119. package/build/runtime-cjs/routing/index.d.ts +0 -3
  120. package/build/runtime-cjs/routing/index.js +0 -33
  121. package/build/runtime-esm/client.d.ts +0 -3
  122. package/build/runtime-esm/client.js +0 -5
  123. package/build/runtime-esm/clientPlugin.d.ts +0 -3
  124. package/build/runtime-esm/clientPlugin.js +0 -17
  125. package/build/runtime-esm/componentFields.d.ts +0 -9
  126. package/build/runtime-esm/componentFields.js +0 -59
  127. package/build/runtime-esm/hooks/index.d.ts +0 -8
  128. package/build/runtime-esm/hooks/index.js +0 -15
  129. package/build/runtime-esm/hooks/useDeepCompareEffect.d.ts +0 -35
  130. package/build/runtime-esm/hooks/useDeepCompareEffect.js +0 -41
  131. package/build/runtime-esm/hooks/useDocumentHandle.d.ts +0 -36
  132. package/build/runtime-esm/hooks/useDocumentHandle.js +0 -143
  133. package/build/runtime-esm/hooks/useDocumentStore.d.ts +0 -11
  134. package/build/runtime-esm/hooks/useDocumentStore.js +0 -42
  135. package/build/runtime-esm/hooks/useDocumentSubscription.d.ts +0 -11
  136. package/build/runtime-esm/hooks/useDocumentSubscription.js +0 -42
  137. package/build/runtime-esm/hooks/useFragment.d.ts +0 -16
  138. package/build/runtime-esm/hooks/useFragment.js +0 -67
  139. package/build/runtime-esm/hooks/useFragmentHandle.d.ts +0 -8
  140. package/build/runtime-esm/hooks/useFragmentHandle.js +0 -23
  141. package/build/runtime-esm/hooks/useIsMounted.d.ts +0 -3
  142. package/build/runtime-esm/hooks/useIsMounted.js +0 -14
  143. package/build/runtime-esm/hooks/useMutation.d.ts +0 -14
  144. package/build/runtime-esm/hooks/useMutation.js +0 -42
  145. package/build/runtime-esm/hooks/useQuery.d.ts +0 -5
  146. package/build/runtime-esm/hooks/useQuery.js +0 -8
  147. package/build/runtime-esm/hooks/useQueryHandle.d.ts +0 -10
  148. package/build/runtime-esm/hooks/useQueryHandle.js +0 -97
  149. package/build/runtime-esm/hooks/useSubscription.d.ts +0 -4
  150. package/build/runtime-esm/hooks/useSubscription.js +0 -8
  151. package/build/runtime-esm/hooks/useSubscriptionHandle.d.ts +0 -25
  152. package/build/runtime-esm/hooks/useSubscriptionHandle.js +0 -18
  153. package/build/runtime-esm/index.d.ts +0 -14
  154. package/build/runtime-esm/index.js +0 -48
  155. package/build/runtime-esm/manifest.d.ts +0 -3
  156. package/build/runtime-esm/manifest.js +0 -5
  157. package/build/runtime-esm/routing/Router.d.ts +0 -62
  158. package/build/runtime-esm/routing/Router.js +0 -499
  159. package/build/runtime-esm/routing/cache.d.ts +0 -7
  160. package/build/runtime-esm/routing/cache.js +0 -36
  161. package/build/runtime-esm/routing/hooks.d.ts +0 -40
  162. package/build/runtime-esm/routing/hooks.js +0 -53
  163. package/build/runtime-esm/routing/index.d.ts +0 -3
  164. package/build/runtime-esm/routing/index.js +0 -6
  165. package/build/server/index.d.ts +0 -1
  166. package/build/server-cjs/index.js +0 -28
  167. package/build/server-cjs/package.json +0 -1
  168. package/build/server-esm/index.js +0 -4
  169. package/build/server-esm/package.json +0 -1
  170. /package/{build/plugin-esm → server}/package.json +0 -0
  171. /package/{build/runtime-esm → vite}/package.json +0 -0
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Simple shim that can be replaced with the actual binary for optimal performance
4
+ // This follows esbuild's approach: the postInstall script will replace this entire file
5
+ // with the native binary when possible, eliminating Node.js startup overhead
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { execFileSync } = require('child_process');
10
+
11
+ // Manual binary path override support
12
+ const MANUAL_BINARY_PATH = process.env.HOUDINI_BINARY_PATH || process.env.HOUDINI_REACT_BINARY_PATH;
13
+
14
+ function getBinaryPath() {
15
+ // Check for manual override first
16
+ if (MANUAL_BINARY_PATH && fs.existsSync(MANUAL_BINARY_PATH)) {
17
+ return MANUAL_BINARY_PATH;
18
+ }
19
+
20
+ // Platform-specific package lookup
21
+ const BINARY_DISTRIBUTION_PACKAGES = {
22
+ 'linux-x64': 'houdini-react-linux-x64',
23
+ 'linux-arm64': 'houdini-react-linux-arm64',
24
+ 'win32-x64': 'houdini-react-win32-x64',
25
+ 'win32-arm64': 'houdini-react-win32-arm64',
26
+ 'darwin-x64': 'houdini-react-darwin-x64',
27
+ 'darwin-arm64': 'houdini-react-darwin-arm64',
28
+ }
29
+
30
+ const binaryName = process.platform === 'win32' ? 'houdini-react.exe' : 'houdini-react'
31
+ const platformSpecificPackageName = BINARY_DISTRIBUTION_PACKAGES[`${process.platform}-${process.arch}`]
32
+
33
+ if (!platformSpecificPackageName) {
34
+ // Fallback to downloaded binary if platform not supported
35
+ return path.join(__dirname, binaryName)
36
+ }
37
+
38
+ try {
39
+ // Method 1: Use require.resolve to find the platform-specific package
40
+ const platformPackagePath = require.resolve(`${platformSpecificPackageName}/package.json`)
41
+ const platformPackageDir = path.dirname(platformPackagePath)
42
+ return path.join(platformPackageDir, 'bin', binaryName)
43
+ } catch (error) {
44
+ // Method 2: Check sibling directory (npm structure)
45
+ const siblingPath = path.join(__dirname, '..', platformSpecificPackageName)
46
+ const siblingBinaryPath = path.join(siblingPath, 'bin', binaryName)
47
+
48
+ if (fs.existsSync(siblingBinaryPath)) {
49
+ return siblingBinaryPath
50
+ }
51
+
52
+ // Method 3: Check pnpm structure
53
+ const pnpmMatch = __dirname.match(/(.+\/node_modules\/)\.pnpm\/([^\/]+)\/node_modules\//)
54
+ if (pnpmMatch) {
55
+ const [, nodeModulesRoot] = pnpmMatch
56
+ const pnpmDir = path.join(nodeModulesRoot, '.pnpm')
57
+
58
+ try {
59
+ const pnpmEntries = fs.readdirSync(pnpmDir)
60
+ // Get the expected version from the main package
61
+ const packageJSON = require(path.join(__dirname, '..', 'package.json'))
62
+ const expectedVersion = packageJSON.version
63
+ const expectedPnpmEntry = `${platformSpecificPackageName}@${expectedVersion}`
64
+ const platformEntry = pnpmEntries.find(entry => entry === expectedPnpmEntry)
65
+
66
+ if (platformEntry) {
67
+ const pnpmBinaryPath = path.join(pnpmDir, platformEntry, 'node_modules', platformSpecificPackageName, 'bin', binaryName)
68
+ if (fs.existsSync(pnpmBinaryPath)) {
69
+ return pnpmBinaryPath
70
+ }
71
+ }
72
+ } catch (err) {
73
+ // Ignore pnpm detection errors
74
+ }
75
+ }
76
+
77
+ // Method 4: Fallback to downloaded binary in main package
78
+ return path.join(__dirname, binaryName)
79
+ }
80
+ }
81
+
82
+ // Execute the binary directly (this entire file may be replaced with the actual binary)
83
+ try {
84
+ execFileSync(getBinaryPath(), process.argv.slice(2), { stdio: 'inherit' });
85
+ } catch (error) {
86
+ // If execFileSync fails, exit with the same code
87
+ process.exit(error.status || 1);
88
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "houdini-react",
3
- "version": "2.0.0-next.2",
3
+ "version": "2.0.0-next.23",
4
4
  "description": "The React plugin for houdini",
5
5
  "keywords": [
6
6
  "typescript",
@@ -22,8 +22,7 @@
22
22
  "@types/estraverse": "^5.1.2",
23
23
  "@types/express": "^4.17.17",
24
24
  "@types/react": "^19.0.7",
25
- "@types/react-dom": "^19.0.3",
26
- "scripts": "^1.0.0"
25
+ "@types/react-dom": "^19.0.3"
27
26
  },
28
27
  "dependencies": {
29
28
  "@babel/parser": "^7.24.6",
@@ -34,43 +33,65 @@
34
33
  "cookies": "^0.8.0",
35
34
  "estraverse": "^5.3.0",
36
35
  "express": "^4.18.2",
37
- "graphql": "^16.10.0",
38
36
  "graphql-yoga": "^4.0.4",
39
37
  "react": "^19.0.0",
40
38
  "react-dom": "^19.0.0",
41
- "react-streaming-compat": "^0.3.18",
39
+ "react-streaming": "^0.4.17",
42
40
  "recast": "^0.23.1",
43
- "rollup": "^4.39.0",
44
- "use-deep-compare-effect": "^1.8.1",
45
- "houdini": "^2.0.0-next.2"
41
+ "rollup": "^4.28.1",
42
+ "use-deep-compare-effect": "^1.8.1"
43
+ },
44
+ "peerDependencies": {
45
+ "graphql": ">=16"
46
46
  },
47
47
  "files": [
48
- "build"
48
+ "bin",
49
+ "postInstall.js",
50
+ "runtime",
51
+ "server",
52
+ "vite"
49
53
  ],
50
54
  "exports": {
51
55
  "./package.json": "./package.json",
52
- ".": {
53
- "types": "./build/plugin/index.d.ts",
54
- "import": "./build/plugin-esm/index.js",
55
- "require": "./build/plugin-cjs/index.js"
56
- },
57
56
  "./server": {
58
- "types": "./build/server/index.d.ts",
59
- "import": "./build/server-esm/index.js",
60
- "require": "./build/server-cjs/index.js"
57
+ "types": "./server/index.d.ts",
58
+ "import": "./server/index.js"
59
+ },
60
+ "./server/*": {
61
+ "types": "./server/*.d.ts",
62
+ "import": "./server/*.js"
63
+ },
64
+ "./vite": {
65
+ "types": "./vite/index.d.ts",
66
+ "import": "./vite/index.js"
67
+ },
68
+ "./vite/*": {
69
+ "types": "./vite/*.d.ts",
70
+ "import": "./vite/*.js"
61
71
  }
62
72
  },
63
73
  "typesVersions": {
64
74
  "*": {
65
75
  "server": [
66
- "build/server/index.d.ts"
76
+ "./server/index.d.ts"
77
+ ],
78
+ "vite": [
79
+ "./vite/index.d.ts"
67
80
  ]
68
81
  }
69
82
  },
70
- "main": "./build/plugin-cjs/index.js",
71
- "types": "./build/plugin/index.d.ts",
83
+ "optionalDependencies": {
84
+ "houdini-react-darwin-x64": "2.0.0-next.23",
85
+ "houdini-react-darwin-arm64": "2.0.0-next.23",
86
+ "houdini-react-linux-x64": "2.0.0-next.23",
87
+ "houdini-react-linux-arm64": "2.0.0-next.23",
88
+ "houdini-react-win32-x64": "2.0.0-next.23",
89
+ "houdini-react-win32-arm64": "2.0.0-next.23"
90
+ },
91
+ "bin": "bin/houdini-react",
72
92
  "scripts": {
73
- "compile": "scripts build --plugin",
74
- "typedefs": "scripts typedefs --plugin"
93
+ "compile": "scripts build-go",
94
+ "typedefs": "scripts typedefs --plugin --go-package",
95
+ "postinstall": "node postInstall.js"
75
96
  }
76
97
  }
package/postInstall.js ADDED
@@ -0,0 +1,353 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const zlib = require('zlib')
4
+ const https = require('https')
5
+ const child_process = require('child_process')
6
+
7
+ // Adjust the version you want to install. You can also make this dynamic.
8
+ const BINARY_DISTRIBUTION_VERSION = '2.0.0-next.23'
9
+
10
+ // Windows binaries end with .exe so we need to special case them.
11
+ const binaryName = process.platform === 'win32' ? 'houdini-react.exe' : 'houdini-react'
12
+
13
+ // Determine package name for this platform
14
+ const platformSpecificPackageName = `houdini-react-${process.platform}-${process.arch}`
15
+
16
+ // Compute the path we want to emit the fallback binary to
17
+ const fallbackBinaryPath = path.join(__dirname, binaryName)
18
+
19
+ // Manual binary path override support
20
+ const MANUAL_BINARY_PATH = process.env.HOUDINI_BINARY_PATH || process.env.HOUDINI_REACT_BINARY_PATH
21
+
22
+ // Package version for validation
23
+ const packageJSON = require(path.join(__dirname, 'package.json'))
24
+ const expectedVersion = packageJSON.version
25
+
26
+ // Track if shim is still JavaScript
27
+ let isShimJS = true
28
+
29
+ function makeRequest(url) {
30
+ return new Promise((resolve, reject) => {
31
+ https
32
+ .get(url, (response) => {
33
+ if (response.statusCode >= 200 && response.statusCode < 300) {
34
+ const chunks = []
35
+ response.on('data', (chunk) => chunks.push(chunk))
36
+ response.on('end', () => {
37
+ resolve(Buffer.concat(chunks))
38
+ })
39
+ } else if (
40
+ response.statusCode >= 300 &&
41
+ response.statusCode < 400 &&
42
+ response.headers.location
43
+ ) {
44
+ // Follow redirects
45
+ makeRequest(response.headers.location).then(resolve, reject)
46
+ } else {
47
+ reject(
48
+ new Error(
49
+ `npm responded with status code ${response.statusCode} when downloading the package!`
50
+ )
51
+ )
52
+ }
53
+ })
54
+ .on('error', (error) => {
55
+ reject(error)
56
+ })
57
+ })
58
+ }
59
+
60
+ function extractFileFromTarball(tarballBuffer, filepath) {
61
+ // Tar archives are organized in 512 byte blocks.
62
+ // Blocks can either be header blocks or data blocks.
63
+ // Header blocks contain file names of the archive in the first 100 bytes, terminated by a null byte.
64
+ // The size of a file is contained in bytes 124-135 of a header block and in octal format.
65
+ // The following blocks will be data blocks containing the file.
66
+ let offset = 0
67
+ while (offset < tarballBuffer.length) {
68
+ const header = tarballBuffer.subarray(offset, offset + 512)
69
+ offset += 512
70
+
71
+ const fileName = header.toString('utf-8', 0, 100).replace(/\0.*/g, '')
72
+ const fileSize = parseInt(header.toString('utf-8', 124, 136).replace(/\0.*/g, ''), 8)
73
+
74
+ if (fileName === filepath) {
75
+ return tarballBuffer.subarray(offset, offset + fileSize)
76
+ }
77
+
78
+ // Clamp offset to the uppoer multiple of 512
79
+ offset = (offset + fileSize + 511) & ~511
80
+ }
81
+ }
82
+
83
+ function installUsingNPM() {
84
+ // Erase "npm_config_global" so that "npm install --global" works.
85
+ // Otherwise this nested "npm install" will also be global, and the install
86
+ // will deadlock waiting for the global installation lock.
87
+ const env = { ...process.env, npm_config_global: undefined };
88
+
89
+ // Create a temporary directory with an empty package.json
90
+ const tempDir = path.join(__dirname, 'npm-install-temp');
91
+
92
+ try {
93
+ fs.mkdirSync(tempDir);
94
+ fs.writeFileSync(path.join(tempDir, 'package.json'), '{}');
95
+
96
+ // Run npm install in the temporary directory
97
+ child_process.execSync(
98
+ `npm install --loglevel=error --prefer-offline --no-audit --progress=false ${platformSpecificPackageName}@${BINARY_DISTRIBUTION_VERSION}`,
99
+ { cwd: tempDir, stdio: 'pipe', env }
100
+ );
101
+
102
+ // Move the downloaded binary to the fallback location
103
+ const installedBinaryPath = path.join(tempDir, 'node_modules', platformSpecificPackageName, 'bin', binaryName);
104
+ fs.renameSync(installedBinaryPath, fallbackBinaryPath);
105
+
106
+ return true;
107
+ } catch (err) {
108
+ console.error(`[${packageJSON.name}] npm install fallback failed: ${err.message}`);
109
+ return false;
110
+ } finally {
111
+ // Clean up temporary directory
112
+ try {
113
+ removeRecursive(tempDir);
114
+ } catch {
115
+ // Ignore cleanup errors
116
+ }
117
+ }
118
+ }
119
+
120
+ function removeRecursive(dir) {
121
+ if (!fs.existsSync(dir)) return;
122
+
123
+ for (const entry of fs.readdirSync(dir)) {
124
+ const entryPath = path.join(dir, entry);
125
+ const stats = fs.lstatSync(entryPath);
126
+
127
+ if (stats.isDirectory()) {
128
+ removeRecursive(entryPath);
129
+ } else {
130
+ fs.unlinkSync(entryPath);
131
+ }
132
+ }
133
+
134
+ fs.rmdirSync(dir);
135
+ }
136
+
137
+ async function downloadBinaryFromNpm() {
138
+ // First try nested npm install (like esbuild does)
139
+ if (installUsingNPM()) {
140
+ console.log(`[${packageJSON.name}] Downloaded binary via npm install`);
141
+ return;
142
+ }
143
+
144
+ // Fallback to direct HTTP download
145
+ console.log(`[${packageJSON.name}] Trying direct download from npm registry...`);
146
+
147
+ // Download the tarball of the right binary distribution package
148
+ const tarballDownloadBuffer = await makeRequest(
149
+ `https://registry.npmjs.org/${platformSpecificPackageName}/-/${platformSpecificPackageName}-${BINARY_DISTRIBUTION_VERSION}.tgz`
150
+ )
151
+
152
+ const tarballBuffer = zlib.unzipSync(tarballDownloadBuffer)
153
+
154
+ // Extract binary from package and write to disk
155
+ fs.writeFileSync(
156
+ fallbackBinaryPath,
157
+ extractFileFromTarball(tarballBuffer, `package/bin/${binaryName}`),
158
+ { mode: 0o755 } // Make binary file executable
159
+ )
160
+
161
+ console.log(`[${packageJSON.name}] Downloaded binary via direct download`);
162
+ }
163
+
164
+ function isPlatformSpecificPackageInstalled() {
165
+ try {
166
+ // Try to resolve the platform package itself
167
+ require.resolve(`${platformSpecificPackageName}/package.json`)
168
+ return true
169
+ } catch (e) {
170
+ // Also check if it exists as a sibling directory
171
+ const siblingPath = path.join(__dirname, '..', platformSpecificPackageName)
172
+ const siblingBinaryPath = path.join(siblingPath, 'bin', binaryName)
173
+ return fs.existsSync(siblingBinaryPath)
174
+ }
175
+ }
176
+
177
+ if (!platformSpecificPackageName) {
178
+ throw new Error('Platform not supported!')
179
+ }
180
+
181
+ // Replace the JavaScript shim with the actual binary for optimal performance (skip Node.js overhead)
182
+ // This is inspired by esbuild's approach: https://github.com/evanw/esbuild/blob/main/lib/npm/node-install.ts
183
+ function maybeOptimizePackage() {
184
+ // This optimization doesn't work on Windows because the binary must be called with .exe extension
185
+ // It also doesn't work with Yarn due to various compatibility issues
186
+ if (process.platform === 'win32' || isYarn()) {
187
+ return
188
+ }
189
+
190
+ let binaryPath = null
191
+
192
+ try {
193
+ // Method 1: Use require.resolve to find the platform-specific package
194
+ const platformPackagePath = require.resolve(`${platformSpecificPackageName}/package.json`)
195
+ const platformPackageDir = path.dirname(platformPackagePath)
196
+ binaryPath = path.join(platformPackageDir, 'bin', binaryName)
197
+ } catch (error) {
198
+ // Method 2: Check if platform package is installed as a sibling directory
199
+ const siblingPath = path.join(__dirname, '..', platformSpecificPackageName)
200
+ binaryPath = path.join(siblingPath, 'bin', binaryName)
201
+
202
+ if (!fs.existsSync(binaryPath)) {
203
+ // Method 3: pnpm-specific structure
204
+ const pnpmMatch = __dirname.match(/(.+\/node_modules\/)\.pnpm\/([^\/]+)\/node_modules\//)
205
+ if (pnpmMatch) {
206
+ const [, nodeModulesRoot] = pnpmMatch
207
+ const pnpmDir = path.join(nodeModulesRoot, '.pnpm')
208
+
209
+ try {
210
+ const pnpmEntries = fs.readdirSync(pnpmDir)
211
+ // Look for the specific version that matches BINARY_DISTRIBUTION_VERSION
212
+ const expectedPnpmEntry = `${platformSpecificPackageName}@${BINARY_DISTRIBUTION_VERSION}`
213
+ const platformEntry = pnpmEntries.find(entry => entry === expectedPnpmEntry)
214
+
215
+ if (platformEntry) {
216
+ binaryPath = path.join(pnpmDir, platformEntry, 'node_modules', platformSpecificPackageName, 'bin', binaryName)
217
+ }
218
+ } catch (err) {
219
+ // Ignore errors
220
+ }
221
+ }
222
+ }
223
+ }
224
+
225
+ // If we found the binary, try to replace the shim with it
226
+ if (binaryPath && fs.existsSync(binaryPath)) {
227
+ // First validate the binary works correctly
228
+ if (!validateBinaryVersion(binaryPath)) {
229
+ console.error(`[${packageJSON.name}] Binary validation failed, keeping JavaScript shim`);
230
+ return;
231
+ }
232
+
233
+ const shimPath = path.join(__dirname, 'bin', packageJSON.name)
234
+ const tempPath = path.join(__dirname, 'bin', `${packageJSON.name}-temp`)
235
+
236
+ try {
237
+ // First create a hard link to avoid taking up additional disk space
238
+ fs.linkSync(binaryPath, tempPath)
239
+
240
+ // Then atomically replace the shim with the binary
241
+ fs.renameSync(tempPath, shimPath)
242
+
243
+ // Make sure it's executable
244
+ fs.chmodSync(shimPath, 0o755)
245
+
246
+ // Update state tracking
247
+ isShimJS = false
248
+
249
+ console.log(`[${packageJSON.name}] Binary optimization successful`);
250
+ } catch (err) {
251
+ console.error(`[${packageJSON.name}] Binary optimization failed: ${err.message}`);
252
+ // If optimization fails, clean up and continue with the shim
253
+ try {
254
+ fs.unlinkSync(tempPath)
255
+ } catch {}
256
+ }
257
+ }
258
+ }
259
+
260
+ function validateBinaryVersion(binaryPath) {
261
+ try {
262
+ // For our Go binaries, we just check if they execute without crashing
263
+ // We use -h flag which should work and exit cleanly
264
+ child_process.execFileSync(binaryPath, ['-h'], {
265
+ stdio: 'pipe',
266
+ timeout: 5000,
267
+ encoding: 'utf8'
268
+ });
269
+ return true;
270
+ } catch (err) {
271
+ // If the binary exits with code 0 or 2 (help), that's fine
272
+ if (err.status === 0 || err.status === 2) {
273
+ return true;
274
+ }
275
+ console.error(`[${packageJSON.name}] Binary validation failed: ${err.message}`);
276
+ return false;
277
+ }
278
+ }
279
+
280
+ function applyManualBinaryPathOverride(overridePath) {
281
+ console.log(`[${packageJSON.name}] Using manual binary path: ${overridePath}`);
282
+
283
+ const shimPath = path.join(__dirname, 'bin', packageJSON.name);
284
+ const shimContent = `#!/usr/bin/env node
285
+ require('child_process').execFileSync(${JSON.stringify(overridePath)}, process.argv.slice(2), { stdio: 'inherit' });
286
+ `;
287
+
288
+ try {
289
+ fs.writeFileSync(shimPath, shimContent, { mode: 0o755 });
290
+ isShimJS = true; // Keep as JS since it's a wrapper
291
+ return true;
292
+ } catch (err) {
293
+ console.error(`[${packageJSON.name}] Failed to apply manual binary override: ${err.message}`);
294
+ return false;
295
+ }
296
+ }
297
+
298
+ function isYarn() {
299
+ const { npm_config_user_agent } = process.env
300
+ if (npm_config_user_agent) {
301
+ return /\byarn\//.test(npm_config_user_agent)
302
+ }
303
+ return false
304
+ }
305
+
306
+ // Check for manual binary path override first
307
+ if (MANUAL_BINARY_PATH) {
308
+ if (fs.existsSync(MANUAL_BINARY_PATH)) {
309
+ console.log(`[${packageJSON.name}] Using manual binary path override`);
310
+ if (applyManualBinaryPathOverride(MANUAL_BINARY_PATH)) {
311
+ process.exit(0);
312
+ }
313
+ } else {
314
+ console.warn(`[${packageJSON.name}] Ignoring invalid manual binary path: ${MANUAL_BINARY_PATH}`);
315
+ }
316
+ }
317
+
318
+ // Skip downloading the binary if it was already installed via optionalDependencies
319
+ if (!isPlatformSpecificPackageInstalled()) {
320
+ console.log(`[${packageJSON.name}] Platform package not found, downloading binary...`);
321
+ downloadBinaryFromNpm().then(() => {
322
+ maybeOptimizePackage();
323
+
324
+ // Final validation
325
+ const shimPath = path.join(__dirname, 'bin', packageJSON.name);
326
+ if (isShimJS) {
327
+ // Validate the JavaScript shim can find and run the binary
328
+ if (!validateBinaryVersion(shimPath)) {
329
+ console.error(`[${packageJSON.name}] Installation may be incomplete`);
330
+ }
331
+ }
332
+ }).catch(err => {
333
+ console.error(`[${packageJSON.name}] Failed to download binary: ${err.message}`);
334
+ process.exit(1);
335
+ });
336
+ } else {
337
+ console.log(`[${packageJSON.name}] Platform package found, optimizing...`);
338
+ maybeOptimizePackage();
339
+
340
+ // Final validation
341
+ const shimPath = path.join(__dirname, 'bin', packageJSON.name);
342
+ if (isShimJS) {
343
+ // Validate the JavaScript shim can find and run the binary
344
+ if (!validateBinaryVersion(shimPath)) {
345
+ console.error(`[${packageJSON.name}] Installation may be incomplete`);
346
+ }
347
+ } else {
348
+ // Binary was optimized, validate it directly
349
+ if (!validateBinaryVersion(shimPath)) {
350
+ console.error(`[${packageJSON.name}] Binary optimization may have failed`);
351
+ }
352
+ }
353
+ }
@@ -0,0 +1,5 @@
1
+ import type { HoudiniClient } from '$houdini/runtime/client'
2
+
3
+ // this file will be replaced by the code generation process
4
+
5
+ export default (() => {}) as () => HoudiniClient
@@ -0,0 +1,17 @@
1
+ import type { ClientPlugin } from 'houdini/runtime/client'
2
+
3
+ const plugin: () => ClientPlugin = () => () => {
4
+ return {
5
+ start(ctx, { next }) {
6
+ next({
7
+ ...ctx,
8
+ cacheParams: {
9
+ ...ctx.cacheParams,
10
+ serverSideFallback: false,
11
+ },
12
+ })
13
+ },
14
+ }
15
+ }
16
+
17
+ export default plugin
@@ -0,0 +1,79 @@
1
+ import { getFieldsForType } from 'houdini/runtime'
2
+ import type { DocumentArtifact, GraphQLObject, GraphQLValue } from 'houdini/runtime'
3
+ import { defaultComponentField, type Cache } from 'houdini/runtime/cache'
4
+
5
+ export function injectComponents({
6
+ cache,
7
+ selection,
8
+ data,
9
+ variables,
10
+ parentType = 'Query',
11
+ }: {
12
+ cache: Cache
13
+ selection: DocumentArtifact['selection']
14
+ data: GraphQLValue | null
15
+ variables: Record<string, GraphQLValue> | undefined | null
16
+ parentType?: string
17
+ }) {
18
+ // if the value is null, we're done
19
+ if (data === null) {
20
+ return
21
+ }
22
+
23
+ // if the value is not an object (ie its a scalar) we're done
24
+ if (typeof data !== 'object') {
25
+ return
26
+ }
27
+ data = data as GraphQLObject
28
+
29
+ // if the value is an array we need to instantiate each item
30
+ if (Array.isArray(data)) {
31
+ data.forEach((item) => {
32
+ injectComponents({
33
+ cache,
34
+ selection,
35
+ data: item,
36
+ variables,
37
+ parentType,
38
+ })
39
+ })
40
+ return
41
+ }
42
+
43
+ // if the object has a subselection we need to walk down
44
+ const typename = '__typename' in data ? (data.__typename as string) : ''
45
+ const fields = getFieldsForType(selection, typename, false)
46
+ if (!fields) {
47
+ return
48
+ }
49
+
50
+ // walk down each field
51
+ for (const [field, subSelection] of Object.entries(fields)) {
52
+ // if the field is a component then we need to assign the value to the target
53
+ if (subSelection.component) {
54
+ // if the component is already in the cache, we're done
55
+ if (!cache._internal_unstable.componentCache[subSelection.component.key]) {
56
+ continue
57
+ }
58
+
59
+ data[field] = defaultComponentField({
60
+ variables,
61
+ parent: cache._internal_unstable.id(parentType, data) ?? '',
62
+ cache,
63
+ component: subSelection.component,
64
+ }) as any as GraphQLValue
65
+ }
66
+
67
+ // if there is a selection, we need to walk down
68
+ const dataValue = data[field]
69
+ if (subSelection.selection) {
70
+ injectComponents({
71
+ cache,
72
+ selection: subSelection.selection,
73
+ data: dataValue,
74
+ variables,
75
+ parentType: subSelection.type,
76
+ })
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,9 @@
1
+ export { useQuery } from './useQuery'
2
+ export { useQueryHandle } from './useQueryHandle'
3
+ export { useFragment } from './useFragment'
4
+ export { useFragmentHandle } from './useFragmentHandle'
5
+ export { useMutation } from './useMutation'
6
+ export { useSubscription } from './useSubscription'
7
+
8
+ export type { DocumentHandle } from './useDocumentHandle'
9
+ export type { UseQueryConfig } from './useQueryHandle'