Skip to content

Commit 0e5844f

Browse files
authored
Merge pull request #53 from interscript/feat/imf-cache-api
fix: node-20-safe browser-host simulation in the Cache API test
2 parents a64d168 + 8e1a6b5 commit 0e5844f

1 file changed

Lines changed: 24 additions & 12 deletions

File tree

test/imf.test.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,18 @@ describe("registry", () => {
195195
const indexUrl = `http://127.0.0.1:${port}/index.yaml`
196196
indexBody = `version: 1\nmodels:\n tiny-1.0:\n filename: tiny.zip\n url: http://127.0.0.1:${port}/tiny.zip\n sha256: ${sha}\n`
197197

198-
const store = new Map<string, Response>()
198+
// store raw bytes: Response.clone() stream semantics differ across
199+
// undici versions (node 20 vs 24) and are irrelevant to the contract
200+
const store = new Map<string, Uint8Array>()
199201
const fakeCache = {
200202
async match(req: RequestInfo) {
201203
const key = String(req instanceof Request ? req.url : req)
202-
return store.get(key)?.clone()
204+
const bytes = store.get(key)
205+
return bytes === undefined ? undefined : new Response(bytes)
203206
},
204207
async put(req: RequestInfo, res: Response) {
205208
const key = String(req instanceof Request ? req.url : req)
206-
store.set(key, res.clone())
209+
store.set(key, new Uint8Array(await res.arrayBuffer()))
207210
},
208211
async delete(req: RequestInfo) {
209212
const key = String(req instanceof Request ? req.url : req)
@@ -212,29 +215,38 @@ describe("registry", () => {
212215
}
213216
const g = globalThis as Record<string, unknown>
214217
g["caches"] = { open: async () => fakeCache }
215-
// simulate a browser host: no Node fs, so the Cache API path runs
216-
const versions = process.versions as { node?: string }
217-
const realNode = versions.node
218-
delete versions.node
218+
// Simulate a browser host by swapping the globalThis.process
219+
// reference (the registry detects Node via globalThis). Deleting
220+
// process.versions.node instead breaks node 20's bundled undici,
221+
// which splits it inside fetch().
222+
const realProcess = globalThis.process
223+
const withBrowserHost = async <T>(fn: () => Promise<T>): Promise<T> => {
224+
const gg = globalThis as { process?: unknown }
225+
gg.process = { env: {}, versions: {} }
226+
try {
227+
return await fn()
228+
} finally {
229+
gg.process = realProcess
230+
}
231+
}
219232
try {
220233
process.env["SECRYST_CACHE"] = undefined
221-
const first = await resolve("tiny-1.0", indexUrl)
234+
const first = await withBrowserHost(() => resolve("tiny-1.0", indexUrl))
222235
expect([...first.bytes]).toEqual([...fixtureZip])
223236
expect(store.size).toBe(1)
224237

225238
// channel dies; the cached copy serves, still sha-verified
226239
channelUp = false
227-
const second = await resolve("tiny-1.0", indexUrl)
240+
const second = await withBrowserHost(() => resolve("tiny-1.0", indexUrl))
228241
expect([...second.bytes]).toEqual([...fixtureZip])
229242

230243
// a corrupted cache entry falls through to a fresh download
231244
channelUp = true
232245
const key = store.keys().next().value as string
233-
store.set(key, new Response(new Uint8Array([1, 2, 3])))
234-
const third = await resolve("tiny-1.0", indexUrl)
246+
store.set(key, new Uint8Array([1, 2, 3]))
247+
const third = await withBrowserHost(() => resolve("tiny-1.0", indexUrl))
235248
expect([...third.bytes]).toEqual([...fixtureZip])
236249
} finally {
237-
if (realNode !== undefined) versions.node = realNode
238250
delete g["caches"]
239251
delete process.env["SECRYST_CACHE"]
240252
await new Promise<void>((r) => server.close(() => r()))

0 commit comments

Comments
 (0)