houdini-react 2.0.0-next.3 → 2.0.0-next.31
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/bin/houdini-react +173 -0
- package/package.json +63 -39
- package/postInstall.js +360 -0
- package/runtime/client.ts +5 -0
- package/runtime/clientPlugin.ts +17 -0
- package/runtime/componentFields.ts +79 -0
- package/runtime/hooks/index.ts +9 -0
- package/runtime/hooks/useDeepCompareEffect.ts +91 -0
- package/runtime/hooks/useDocumentHandle.ts +232 -0
- package/runtime/hooks/useDocumentStore.ts +76 -0
- package/runtime/hooks/useDocumentSubscription.ts +62 -0
- package/runtime/hooks/useFragment.ts +93 -0
- package/runtime/hooks/useFragmentHandle.ts +46 -0
- package/runtime/hooks/useIsMounted.ts +14 -0
- package/runtime/hooks/useMutation.ts +70 -0
- package/runtime/hooks/useQuery.ts +12 -0
- package/runtime/hooks/useQueryHandle.ts +186 -0
- package/runtime/hooks/useSubscription.ts +12 -0
- package/runtime/hooks/useSubscriptionHandle.ts +33 -0
- package/runtime/hydration.tsx +155 -0
- package/runtime/index.tsx +49 -0
- package/runtime/manifest.ts +6 -0
- package/runtime/package.json +1 -0
- package/runtime/routing/Router.tsx +885 -0
- package/runtime/routing/cache.ts +54 -0
- package/runtime/routing/index.ts +2 -0
- package/server/index.d.ts +1 -0
- package/server/index.js +4 -0
- package/server/react-streaming.d.js +0 -0
- package/vite/index.d.ts +3 -0
- package/vite/index.js +286 -0
- package/vite/transform.d.ts +11 -0
- package/vite/transform.js +90 -0
- package/README.md +0 -36
- package/build/plugin/codegen/entries/documentWrappers.d.ts +0 -6
- package/build/plugin/codegen/entries/fallbacks.d.ts +0 -5
- package/build/plugin/codegen/entries/index.d.ts +0 -16
- package/build/plugin/codegen/entries/pages.d.ts +0 -2
- package/build/plugin/codegen/index.d.ts +0 -17
- package/build/plugin/codegen/manifest.d.ts +0 -5
- package/build/plugin/codegen/render.d.ts +0 -7
- package/build/plugin/codegen/router.d.ts +0 -7
- package/build/plugin/codegen/typeRoot.d.ts +0 -5
- package/build/plugin/config.d.ts +0 -4
- package/build/plugin/dedent.d.ts +0 -1
- package/build/plugin/extract.d.ts +0 -6
- package/build/plugin/index.d.ts +0 -5
- package/build/plugin/state.d.ts +0 -3
- package/build/plugin/transform.d.ts +0 -6
- package/build/plugin/vite.d.ts +0 -27
- package/build/plugin-cjs/index.js +0 -90119
- package/build/plugin-cjs/package.json +0 -1
- package/build/plugin-esm/index.js +0 -90115
- package/build/runtime/client.d.ts +0 -3
- package/build/runtime/clientPlugin.d.ts +0 -3
- package/build/runtime/componentFields.d.ts +0 -9
- package/build/runtime/hooks/index.d.ts +0 -8
- package/build/runtime/hooks/useDeepCompareEffect.d.ts +0 -35
- package/build/runtime/hooks/useDocumentHandle.d.ts +0 -36
- package/build/runtime/hooks/useDocumentStore.d.ts +0 -11
- package/build/runtime/hooks/useDocumentSubscription.d.ts +0 -11
- package/build/runtime/hooks/useFragment.d.ts +0 -16
- package/build/runtime/hooks/useFragmentHandle.d.ts +0 -8
- package/build/runtime/hooks/useIsMounted.d.ts +0 -3
- package/build/runtime/hooks/useMutation.d.ts +0 -14
- package/build/runtime/hooks/useQuery.d.ts +0 -5
- package/build/runtime/hooks/useQueryHandle.d.ts +0 -10
- package/build/runtime/hooks/useSubscription.d.ts +0 -4
- package/build/runtime/hooks/useSubscriptionHandle.d.ts +0 -25
- package/build/runtime/index.d.ts +0 -14
- package/build/runtime/manifest.d.ts +0 -3
- package/build/runtime/routing/Router.d.ts +0 -62
- package/build/runtime/routing/cache.d.ts +0 -7
- package/build/runtime/routing/hooks.d.ts +0 -40
- package/build/runtime/routing/index.d.ts +0 -3
- package/build/runtime-cjs/client.d.ts +0 -3
- package/build/runtime-cjs/client.js +0 -25
- package/build/runtime-cjs/clientPlugin.d.ts +0 -3
- package/build/runtime-cjs/clientPlugin.js +0 -37
- package/build/runtime-cjs/componentFields.d.ts +0 -9
- package/build/runtime-cjs/componentFields.js +0 -83
- package/build/runtime-cjs/hooks/index.d.ts +0 -8
- package/build/runtime-cjs/hooks/index.js +0 -45
- package/build/runtime-cjs/hooks/useDeepCompareEffect.d.ts +0 -35
- package/build/runtime-cjs/hooks/useDeepCompareEffect.js +0 -76
- package/build/runtime-cjs/hooks/useDocumentHandle.d.ts +0 -36
- package/build/runtime-cjs/hooks/useDocumentHandle.js +0 -177
- package/build/runtime-cjs/hooks/useDocumentStore.d.ts +0 -11
- package/build/runtime-cjs/hooks/useDocumentStore.js +0 -76
- package/build/runtime-cjs/hooks/useDocumentSubscription.d.ts +0 -11
- package/build/runtime-cjs/hooks/useDocumentSubscription.js +0 -76
- package/build/runtime-cjs/hooks/useFragment.d.ts +0 -16
- package/build/runtime-cjs/hooks/useFragment.js +0 -102
- package/build/runtime-cjs/hooks/useFragmentHandle.d.ts +0 -8
- package/build/runtime-cjs/hooks/useFragmentHandle.js +0 -47
- package/build/runtime-cjs/hooks/useIsMounted.d.ts +0 -3
- package/build/runtime-cjs/hooks/useIsMounted.js +0 -38
- package/build/runtime-cjs/hooks/useMutation.d.ts +0 -14
- package/build/runtime-cjs/hooks/useMutation.js +0 -67
- package/build/runtime-cjs/hooks/useQuery.d.ts +0 -5
- package/build/runtime-cjs/hooks/useQuery.js +0 -32
- package/build/runtime-cjs/hooks/useQueryHandle.d.ts +0 -10
- package/build/runtime-cjs/hooks/useQueryHandle.js +0 -131
- package/build/runtime-cjs/hooks/useSubscription.d.ts +0 -4
- package/build/runtime-cjs/hooks/useSubscription.js +0 -32
- package/build/runtime-cjs/hooks/useSubscriptionHandle.d.ts +0 -25
- package/build/runtime-cjs/hooks/useSubscriptionHandle.js +0 -42
- package/build/runtime-cjs/index.d.ts +0 -14
- package/build/runtime-cjs/index.js +0 -88
- package/build/runtime-cjs/manifest.d.ts +0 -3
- package/build/runtime-cjs/manifest.js +0 -25
- package/build/runtime-cjs/package.json +0 -1
- package/build/runtime-cjs/routing/Router.d.ts +0 -62
- package/build/runtime-cjs/routing/Router.js +0 -540
- package/build/runtime-cjs/routing/cache.d.ts +0 -7
- package/build/runtime-cjs/routing/cache.js +0 -61
- package/build/runtime-cjs/routing/hooks.d.ts +0 -40
- package/build/runtime-cjs/routing/hooks.js +0 -93
- package/build/runtime-cjs/routing/index.d.ts +0 -3
- package/build/runtime-cjs/routing/index.js +0 -33
- package/build/runtime-esm/client.d.ts +0 -3
- package/build/runtime-esm/client.js +0 -5
- package/build/runtime-esm/clientPlugin.d.ts +0 -3
- package/build/runtime-esm/clientPlugin.js +0 -17
- package/build/runtime-esm/componentFields.d.ts +0 -9
- package/build/runtime-esm/componentFields.js +0 -59
- package/build/runtime-esm/hooks/index.d.ts +0 -8
- package/build/runtime-esm/hooks/index.js +0 -15
- package/build/runtime-esm/hooks/useDeepCompareEffect.d.ts +0 -35
- package/build/runtime-esm/hooks/useDeepCompareEffect.js +0 -41
- package/build/runtime-esm/hooks/useDocumentHandle.d.ts +0 -36
- package/build/runtime-esm/hooks/useDocumentHandle.js +0 -143
- package/build/runtime-esm/hooks/useDocumentStore.d.ts +0 -11
- package/build/runtime-esm/hooks/useDocumentStore.js +0 -42
- package/build/runtime-esm/hooks/useDocumentSubscription.d.ts +0 -11
- package/build/runtime-esm/hooks/useDocumentSubscription.js +0 -42
- package/build/runtime-esm/hooks/useFragment.d.ts +0 -16
- package/build/runtime-esm/hooks/useFragment.js +0 -67
- package/build/runtime-esm/hooks/useFragmentHandle.d.ts +0 -8
- package/build/runtime-esm/hooks/useFragmentHandle.js +0 -23
- package/build/runtime-esm/hooks/useIsMounted.d.ts +0 -3
- package/build/runtime-esm/hooks/useIsMounted.js +0 -14
- package/build/runtime-esm/hooks/useMutation.d.ts +0 -14
- package/build/runtime-esm/hooks/useMutation.js +0 -42
- package/build/runtime-esm/hooks/useQuery.d.ts +0 -5
- package/build/runtime-esm/hooks/useQuery.js +0 -8
- package/build/runtime-esm/hooks/useQueryHandle.d.ts +0 -10
- package/build/runtime-esm/hooks/useQueryHandle.js +0 -97
- package/build/runtime-esm/hooks/useSubscription.d.ts +0 -4
- package/build/runtime-esm/hooks/useSubscription.js +0 -8
- package/build/runtime-esm/hooks/useSubscriptionHandle.d.ts +0 -25
- package/build/runtime-esm/hooks/useSubscriptionHandle.js +0 -18
- package/build/runtime-esm/index.d.ts +0 -14
- package/build/runtime-esm/index.js +0 -48
- package/build/runtime-esm/manifest.d.ts +0 -3
- package/build/runtime-esm/manifest.js +0 -5
- package/build/runtime-esm/routing/Router.d.ts +0 -62
- package/build/runtime-esm/routing/Router.js +0 -499
- package/build/runtime-esm/routing/cache.d.ts +0 -7
- package/build/runtime-esm/routing/cache.js +0 -36
- package/build/runtime-esm/routing/hooks.d.ts +0 -40
- package/build/runtime-esm/routing/hooks.js +0 -53
- package/build/runtime-esm/routing/index.d.ts +0 -3
- package/build/runtime-esm/routing/index.js +0 -6
- package/build/server/index.d.ts +0 -1
- package/build/server-cjs/index.js +0 -28
- package/build/server-cjs/package.json +0 -1
- package/build/server-esm/index.js +0 -4
- package/build/server-esm/package.json +0 -1
- /package/{build/plugin-esm → server}/package.json +0 -0
- /package/{build/runtime-esm → vite}/package.json +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execFileSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const binaryName = process.platform === 'win32' ? 'houdini-react.exe' : 'houdini-react';
|
|
8
|
+
|
|
9
|
+
const BINARY_DISTRIBUTION_PACKAGES = {
|
|
10
|
+
'linux-x64': 'houdini-react-linux-x64',
|
|
11
|
+
'linux-arm64': 'houdini-react-linux-arm64',
|
|
12
|
+
'win32-x64': 'houdini-react-win32-x64',
|
|
13
|
+
'win32-arm64': 'houdini-react-win32-arm64',
|
|
14
|
+
'darwin-x64': 'houdini-react-darwin-x64',
|
|
15
|
+
'darwin-arm64':'houdini-react-darwin-arm64',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const PLATFORM_OVERRIDE = process.env.HOUDINI_PLATFORM;
|
|
19
|
+
const MANUAL_BINARY_PATH = process.env.HOUDINI_REACT_BINARY_PATH || process.env.HOUDINI_BINARY_PATH;
|
|
20
|
+
|
|
21
|
+
// --- WASM path ---
|
|
22
|
+
if (PLATFORM_OVERRIDE === 'wasm') {
|
|
23
|
+
const wasmPackage = 'houdini-react-wasm';
|
|
24
|
+
const wasmBinaryName = 'houdini-react.wasm';
|
|
25
|
+
let wasmBin = null;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const pkgPath = require.resolve(`${wasmPackage}/package.json`);
|
|
29
|
+
wasmBin = path.join(path.dirname(pkgPath), 'bin', wasmBinaryName);
|
|
30
|
+
} catch {
|
|
31
|
+
const sibling = path.join(__dirname, '..', wasmPackage, 'bin', wasmBinaryName);
|
|
32
|
+
if (fs.existsSync(sibling)) wasmBin = sibling;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!wasmBin || !fs.existsSync(wasmBin)) {
|
|
36
|
+
process.stderr.write(`[houdini-react] WASM package not installed. Try: npm install ${wasmPackage}\n`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// In WebContainers, fs.readSync on a pipe fd is not supported in any thread
|
|
41
|
+
// (the child gets EBADF). Instead:
|
|
42
|
+
// Main thread — async process.stdin.on('data') works fine (event loop)
|
|
43
|
+
// Worker thread — Atomics.wait + receiveMessageOnPort provides real blocking
|
|
44
|
+
// A custom fd_read override feeds WASM stdin from the message channel so WASI
|
|
45
|
+
// never touches fd 0 directly.
|
|
46
|
+
const { Worker, isMainThread, workerData, MessageChannel, receiveMessageOnPort } = require('worker_threads');
|
|
47
|
+
|
|
48
|
+
if (isMainThread) {
|
|
49
|
+
const { port1: stdinMain, port2: stdinWorker } = new MessageChannel();
|
|
50
|
+
// Counter: main increments (Atomics.add) per message so rapid bursts
|
|
51
|
+
// (two frames in the same tick) produce two distinct wakeups.
|
|
52
|
+
const syncBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
53
|
+
|
|
54
|
+
process.stdin.on('error', () => {});
|
|
55
|
+
process.stdin.on('data', data => {
|
|
56
|
+
stdinMain.postMessage(data);
|
|
57
|
+
Atomics.add(syncBuf, 0, 1);
|
|
58
|
+
Atomics.notify(syncBuf, 0);
|
|
59
|
+
});
|
|
60
|
+
process.stdin.on('end', () => {
|
|
61
|
+
stdinMain.postMessage(null); // EOF sentinel
|
|
62
|
+
Atomics.add(syncBuf, 0, 1);
|
|
63
|
+
Atomics.notify(syncBuf, 0);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const worker = new Worker(__filename, {
|
|
67
|
+
workerData: { wasmBin, args: process.argv.slice(2), stdinPort: stdinWorker, syncBuf },
|
|
68
|
+
transferList: [stdinWorker],
|
|
69
|
+
});
|
|
70
|
+
worker.on('exit', code => process.exit(code ?? 0));
|
|
71
|
+
return; // prevent fallthrough to native binary path
|
|
72
|
+
} else {
|
|
73
|
+
const { wasmBin: wb, args, stdinPort, syncBuf } = workerData;
|
|
74
|
+
const { WASI } = require('node:wasi');
|
|
75
|
+
|
|
76
|
+
const wasi = new WASI({
|
|
77
|
+
args: [wb, ...args],
|
|
78
|
+
env: process.env,
|
|
79
|
+
preopens: { '/': '/' },
|
|
80
|
+
version: 'preview1',
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
let wasmMem = null;
|
|
84
|
+
const importObj = wasi.getImportObject();
|
|
85
|
+
const realFdRead = importObj.wasi_snapshot_preview1.fd_read;
|
|
86
|
+
|
|
87
|
+
// Override fd_read for stdin (fd 0) only: block via Atomics until the main
|
|
88
|
+
// thread delivers a chunk, then copy it into WASM memory via iov buffers.
|
|
89
|
+
importObj.wasi_snapshot_preview1.fd_read = (fd, iovs, iovsLen, nread) => {
|
|
90
|
+
if (fd !== 0 || !wasmMem) return realFdRead(fd, iovs, iovsLen, nread);
|
|
91
|
+
|
|
92
|
+
while (Atomics.load(syncBuf, 0) === 0) {
|
|
93
|
+
Atomics.wait(syncBuf, 0, 0);
|
|
94
|
+
}
|
|
95
|
+
const msg = receiveMessageOnPort(stdinPort);
|
|
96
|
+
Atomics.sub(syncBuf, 0, 1);
|
|
97
|
+
|
|
98
|
+
const view = new DataView(wasmMem.buffer);
|
|
99
|
+
if (!msg || msg.message === null) {
|
|
100
|
+
view.setUint32(nread, 0, true); // EOF
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const chunk = msg.message;
|
|
105
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
106
|
+
let written = 0;
|
|
107
|
+
for (let i = 0; i < iovsLen; i++) {
|
|
108
|
+
const ptr = view.getUint32(iovs + i * 8, true);
|
|
109
|
+
const len = view.getUint32(iovs + i * 8 + 4, true);
|
|
110
|
+
const n = Math.min(len, buf.length - written);
|
|
111
|
+
if (n <= 0) break;
|
|
112
|
+
new Uint8Array(wasmMem.buffer, ptr, n).set(buf.subarray(written, written + n));
|
|
113
|
+
written += n;
|
|
114
|
+
}
|
|
115
|
+
view.setUint32(nread, written, true);
|
|
116
|
+
return 0;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const mod = new WebAssembly.Module(fs.readFileSync(wb));
|
|
120
|
+
const inst = new WebAssembly.Instance(mod, importObj);
|
|
121
|
+
wasmMem = inst.exports.memory;
|
|
122
|
+
wasi.start(inst);
|
|
123
|
+
process.exit(0);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// --- Native binary path ---
|
|
128
|
+
function getBinaryPath() {
|
|
129
|
+
if (MANUAL_BINARY_PATH && fs.existsSync(MANUAL_BINARY_PATH)) {
|
|
130
|
+
return MANUAL_BINARY_PATH;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const platformKey = PLATFORM_OVERRIDE || `${process.platform}-${process.arch}`;
|
|
134
|
+
const platformSpecificPackageName = BINARY_DISTRIBUTION_PACKAGES[platformKey];
|
|
135
|
+
|
|
136
|
+
if (!platformSpecificPackageName) {
|
|
137
|
+
if (PLATFORM_OVERRIDE) {
|
|
138
|
+
process.stderr.write(`[houdini-react] Unknown platform "${PLATFORM_OVERRIDE}". Valid values: ${Object.keys(BINARY_DISTRIBUTION_PACKAGES).join(', ')}, wasm\n`);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
return path.join(__dirname, binaryName);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
const platformPackagePath = require.resolve(`${platformSpecificPackageName}/package.json`);
|
|
146
|
+
return path.join(path.dirname(platformPackagePath), 'bin', binaryName);
|
|
147
|
+
} catch {
|
|
148
|
+
const siblingPath = path.join(__dirname, '..', platformSpecificPackageName, 'bin', binaryName);
|
|
149
|
+
if (fs.existsSync(siblingPath)) return siblingPath;
|
|
150
|
+
|
|
151
|
+
const pnpmMatch = __dirname.match(/(.+\/node_modules\/)\.pnpm\/[^/]+\/node_modules\//);
|
|
152
|
+
if (pnpmMatch) {
|
|
153
|
+
const pnpmDir = path.join(pnpmMatch[1], '.pnpm');
|
|
154
|
+
try {
|
|
155
|
+
const packageJSON = require(path.join(__dirname, '..', 'package.json'));
|
|
156
|
+
const entry = `${platformSpecificPackageName}@${packageJSON.version}`;
|
|
157
|
+
const found = fs.readdirSync(pnpmDir).find(e => e === entry);
|
|
158
|
+
if (found) {
|
|
159
|
+
const p = path.join(pnpmDir, found, 'node_modules', platformSpecificPackageName, 'bin', binaryName);
|
|
160
|
+
if (fs.existsSync(p)) return p;
|
|
161
|
+
}
|
|
162
|
+
} catch {}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return path.join(__dirname, binaryName);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
execFileSync(getBinaryPath(), process.argv.slice(2), { stdio: 'inherit' });
|
|
171
|
+
} catch (error) {
|
|
172
|
+
process.exit(error.status || 1);
|
|
173
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "houdini-react",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.31",
|
|
4
4
|
"description": "The React plugin for houdini",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -16,61 +16,85 @@
|
|
|
16
16
|
},
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@types/cookie-parser": "^1.4.
|
|
20
|
-
"@types/cookie-session": "^2.0.
|
|
21
|
-
"@types/cookies": "^0.
|
|
22
|
-
"@types/estraverse": "^5.1.
|
|
23
|
-
"@types/express": "^
|
|
24
|
-
"@types/react": "^19.
|
|
25
|
-
"@types/react-dom": "^19.
|
|
26
|
-
"scripts": "^1.0.0"
|
|
19
|
+
"@types/cookie-parser": "^1.4.10",
|
|
20
|
+
"@types/cookie-session": "^2.0.49",
|
|
21
|
+
"@types/cookies": "^0.9.2",
|
|
22
|
+
"@types/estraverse": "^5.1.7",
|
|
23
|
+
"@types/express": "^5.0.3",
|
|
24
|
+
"@types/react": "^19.2.16",
|
|
25
|
+
"@types/react-dom": "^19.2.3"
|
|
27
26
|
},
|
|
28
27
|
"dependencies": {
|
|
29
|
-
"@babel/parser": "^7.
|
|
30
|
-
"@babel/types": "^7.
|
|
31
|
-
"@whatwg-node/server": "^0.
|
|
32
|
-
"cookie-parser": "^1.4.
|
|
33
|
-
"cookie-session": "^2.
|
|
34
|
-
"cookies": "^0.
|
|
28
|
+
"@babel/parser": "^7.29.7",
|
|
29
|
+
"@babel/types": "^7.29.7",
|
|
30
|
+
"@whatwg-node/server": "^0.11.0",
|
|
31
|
+
"cookie-parser": "^1.4.7",
|
|
32
|
+
"cookie-session": "^2.1.1",
|
|
33
|
+
"cookies": "^0.9.1",
|
|
35
34
|
"estraverse": "^5.3.0",
|
|
36
|
-
"express": "^
|
|
37
|
-
"graphql": "^
|
|
38
|
-
"
|
|
39
|
-
"react": "^19.
|
|
40
|
-
"react-
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
"express": "^5.1.0",
|
|
36
|
+
"graphql-yoga": "^5.21.1",
|
|
37
|
+
"react": "^19.2.7",
|
|
38
|
+
"react-dom": "^19.2.7",
|
|
39
|
+
"react-streaming": "^0.4.17",
|
|
40
|
+
"recast": "^0.23.11",
|
|
41
|
+
"rollup": "^4.61.1",
|
|
42
|
+
"use-deep-compare-effect": "^1.8.1"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"graphql": ">=16"
|
|
46
46
|
},
|
|
47
47
|
"files": [
|
|
48
|
-
"
|
|
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": "./
|
|
59
|
-
"import": "./
|
|
60
|
-
|
|
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
|
-
"
|
|
76
|
+
"./server/index.d.ts"
|
|
77
|
+
],
|
|
78
|
+
"vite": [
|
|
79
|
+
"./vite/index.d.ts"
|
|
67
80
|
]
|
|
68
81
|
}
|
|
69
82
|
},
|
|
70
|
-
"
|
|
71
|
-
|
|
83
|
+
"optionalDependencies": {
|
|
84
|
+
"houdini-react-darwin-x64": "2.0.0-next.31",
|
|
85
|
+
"houdini-react-darwin-arm64": "2.0.0-next.31",
|
|
86
|
+
"houdini-react-linux-x64": "2.0.0-next.31",
|
|
87
|
+
"houdini-react-linux-arm64": "2.0.0-next.31",
|
|
88
|
+
"houdini-react-win32-x64": "2.0.0-next.31",
|
|
89
|
+
"houdini-react-win32-arm64": "2.0.0-next.31",
|
|
90
|
+
"houdini-react-wasm": "2.0.0-next.31"
|
|
91
|
+
},
|
|
72
92
|
"scripts": {
|
|
73
|
-
"compile": "scripts build
|
|
74
|
-
"typedefs": "scripts typedefs --plugin"
|
|
93
|
+
"compile": "scripts build-go",
|
|
94
|
+
"typedefs": "scripts typedefs --plugin --go-package",
|
|
95
|
+
"postinstall": "node postInstall.js"
|
|
96
|
+
},
|
|
97
|
+
"bin": {
|
|
98
|
+
"houdini-react": "bin/houdini-react"
|
|
75
99
|
}
|
|
76
100
|
}
|
package/postInstall.js
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
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.31'
|
|
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
|
+
// Allow callers to opt out of the optimization (e.g. when building a snapshot
|
|
185
|
+
// for an environment that can't run native binaries, like WebContainers).
|
|
186
|
+
if (process.env.HOUDINI_SKIP_SHIM_INSTALL) {
|
|
187
|
+
console.log(`[${packageJSON.name}] HOUDINI_SKIP_SHIM_INSTALL set, keeping JavaScript shim`)
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// This optimization doesn't work on Windows because the binary must be called with .exe extension
|
|
192
|
+
// It also doesn't work with Yarn due to various compatibility issues
|
|
193
|
+
if (process.platform === 'win32' || isYarn()) {
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let binaryPath = null
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
// Method 1: Use require.resolve to find the platform-specific package
|
|
201
|
+
const platformPackagePath = require.resolve(`${platformSpecificPackageName}/package.json`)
|
|
202
|
+
const platformPackageDir = path.dirname(platformPackagePath)
|
|
203
|
+
binaryPath = path.join(platformPackageDir, 'bin', binaryName)
|
|
204
|
+
} catch (error) {
|
|
205
|
+
// Method 2: Check if platform package is installed as a sibling directory
|
|
206
|
+
const siblingPath = path.join(__dirname, '..', platformSpecificPackageName)
|
|
207
|
+
binaryPath = path.join(siblingPath, 'bin', binaryName)
|
|
208
|
+
|
|
209
|
+
if (!fs.existsSync(binaryPath)) {
|
|
210
|
+
// Method 3: pnpm-specific structure
|
|
211
|
+
const pnpmMatch = __dirname.match(/(.+\/node_modules\/)\.pnpm\/([^\/]+)\/node_modules\//)
|
|
212
|
+
if (pnpmMatch) {
|
|
213
|
+
const [, nodeModulesRoot] = pnpmMatch
|
|
214
|
+
const pnpmDir = path.join(nodeModulesRoot, '.pnpm')
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
const pnpmEntries = fs.readdirSync(pnpmDir)
|
|
218
|
+
// Look for the specific version that matches BINARY_DISTRIBUTION_VERSION
|
|
219
|
+
const expectedPnpmEntry = `${platformSpecificPackageName}@${BINARY_DISTRIBUTION_VERSION}`
|
|
220
|
+
const platformEntry = pnpmEntries.find(entry => entry === expectedPnpmEntry)
|
|
221
|
+
|
|
222
|
+
if (platformEntry) {
|
|
223
|
+
binaryPath = path.join(pnpmDir, platformEntry, 'node_modules', platformSpecificPackageName, 'bin', binaryName)
|
|
224
|
+
}
|
|
225
|
+
} catch (err) {
|
|
226
|
+
// Ignore errors
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// If we found the binary, try to replace the shim with it
|
|
233
|
+
if (binaryPath && fs.existsSync(binaryPath)) {
|
|
234
|
+
// First validate the binary works correctly
|
|
235
|
+
if (!validateBinaryVersion(binaryPath)) {
|
|
236
|
+
console.error(`[${packageJSON.name}] Binary validation failed, keeping JavaScript shim`);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const shimPath = path.join(__dirname, 'bin', packageJSON.name)
|
|
241
|
+
const tempPath = path.join(__dirname, 'bin', `${packageJSON.name}-temp`)
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
// First create a hard link to avoid taking up additional disk space
|
|
245
|
+
fs.linkSync(binaryPath, tempPath)
|
|
246
|
+
|
|
247
|
+
// Then atomically replace the shim with the binary
|
|
248
|
+
fs.renameSync(tempPath, shimPath)
|
|
249
|
+
|
|
250
|
+
// Make sure it's executable
|
|
251
|
+
fs.chmodSync(shimPath, 0o755)
|
|
252
|
+
|
|
253
|
+
// Update state tracking
|
|
254
|
+
isShimJS = false
|
|
255
|
+
|
|
256
|
+
console.log(`[${packageJSON.name}] Binary optimization successful`);
|
|
257
|
+
} catch (err) {
|
|
258
|
+
console.error(`[${packageJSON.name}] Binary optimization failed: ${err.message}`);
|
|
259
|
+
// If optimization fails, clean up and continue with the shim
|
|
260
|
+
try {
|
|
261
|
+
fs.unlinkSync(tempPath)
|
|
262
|
+
} catch {}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function validateBinaryVersion(binaryPath) {
|
|
268
|
+
try {
|
|
269
|
+
// For our Go binaries, we just check if they execute without crashing
|
|
270
|
+
// We use -h flag which should work and exit cleanly
|
|
271
|
+
child_process.execFileSync(binaryPath, ['-h'], {
|
|
272
|
+
stdio: 'pipe',
|
|
273
|
+
timeout: 5000,
|
|
274
|
+
encoding: 'utf8'
|
|
275
|
+
});
|
|
276
|
+
return true;
|
|
277
|
+
} catch (err) {
|
|
278
|
+
// If the binary exits with code 0 or 2 (help), that's fine
|
|
279
|
+
if (err.status === 0 || err.status === 2) {
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
console.error(`[${packageJSON.name}] Binary validation failed: ${err.message}`);
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function applyManualBinaryPathOverride(overridePath) {
|
|
288
|
+
console.log(`[${packageJSON.name}] Using manual binary path: ${overridePath}`);
|
|
289
|
+
|
|
290
|
+
const shimPath = path.join(__dirname, 'bin', packageJSON.name);
|
|
291
|
+
const shimContent = `#!/usr/bin/env node
|
|
292
|
+
require('child_process').execFileSync(${JSON.stringify(overridePath)}, process.argv.slice(2), { stdio: 'inherit' });
|
|
293
|
+
`;
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
fs.writeFileSync(shimPath, shimContent, { mode: 0o755 });
|
|
297
|
+
isShimJS = true; // Keep as JS since it's a wrapper
|
|
298
|
+
return true;
|
|
299
|
+
} catch (err) {
|
|
300
|
+
console.error(`[${packageJSON.name}] Failed to apply manual binary override: ${err.message}`);
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function isYarn() {
|
|
306
|
+
const { npm_config_user_agent } = process.env
|
|
307
|
+
if (npm_config_user_agent) {
|
|
308
|
+
return /\byarn\//.test(npm_config_user_agent)
|
|
309
|
+
}
|
|
310
|
+
return false
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Check for manual binary path override first
|
|
314
|
+
if (MANUAL_BINARY_PATH) {
|
|
315
|
+
if (fs.existsSync(MANUAL_BINARY_PATH)) {
|
|
316
|
+
console.log(`[${packageJSON.name}] Using manual binary path override`);
|
|
317
|
+
if (applyManualBinaryPathOverride(MANUAL_BINARY_PATH)) {
|
|
318
|
+
process.exit(0);
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
console.warn(`[${packageJSON.name}] Ignoring invalid manual binary path: ${MANUAL_BINARY_PATH}`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Skip downloading the binary if it was already installed via optionalDependencies
|
|
326
|
+
if (!isPlatformSpecificPackageInstalled()) {
|
|
327
|
+
console.log(`[${packageJSON.name}] Platform package not found, downloading binary...`);
|
|
328
|
+
downloadBinaryFromNpm().then(() => {
|
|
329
|
+
maybeOptimizePackage();
|
|
330
|
+
|
|
331
|
+
// Final validation
|
|
332
|
+
const shimPath = path.join(__dirname, 'bin', packageJSON.name);
|
|
333
|
+
if (isShimJS) {
|
|
334
|
+
// Validate the JavaScript shim can find and run the binary
|
|
335
|
+
if (!validateBinaryVersion(shimPath)) {
|
|
336
|
+
console.error(`[${packageJSON.name}] Installation may be incomplete`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}).catch(err => {
|
|
340
|
+
console.error(`[${packageJSON.name}] Failed to download binary: ${err.message}`);
|
|
341
|
+
process.exit(1);
|
|
342
|
+
});
|
|
343
|
+
} else {
|
|
344
|
+
console.log(`[${packageJSON.name}] Platform package found, optimizing...`);
|
|
345
|
+
maybeOptimizePackage();
|
|
346
|
+
|
|
347
|
+
// Final validation
|
|
348
|
+
const shimPath = path.join(__dirname, 'bin', packageJSON.name);
|
|
349
|
+
if (isShimJS) {
|
|
350
|
+
// Validate the JavaScript shim can find and run the binary
|
|
351
|
+
if (!validateBinaryVersion(shimPath)) {
|
|
352
|
+
console.error(`[${packageJSON.name}] Installation may be incomplete`);
|
|
353
|
+
}
|
|
354
|
+
} else {
|
|
355
|
+
// Binary was optimized, validate it directly
|
|
356
|
+
if (!validateBinaryVersion(shimPath)) {
|
|
357
|
+
console.error(`[${packageJSON.name}] Binary optimization may have failed`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
@@ -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
|