Skip to content
Documentation
1.0.0-beta.9 · exact release

Fetching and composing data

Source fda16de1b352 · Published v1.0.0-beta.9

ctx.fetch is the primary host effect for data workflows.

import { Pulse } from '@pulse-compute/pulse'
interface User {
id: number
name: string
}
interface Stats {
score: number
}
interface Flags {
enabled: boolean
}
const app = new Pulse({ auto: true })
// One structured origin.
app.get('/user', async (ctx) => {
const user = await ctx
.fetch('https://users.example.test/users/123')
.json<User>()
return ctx.json({ found: true, user })
})
// Multiple origins with explicit sequential awaits.
app.get('/user-summary', async (ctx) => {
const user = await ctx
.fetch('https://users.example.test/users/123')
.json<User>()
const stats = await ctx
.fetch('https://stats.example.test/users/123')
.json<Stats>()
const flags = await ctx
.fetch('https://flags.example.test/users/123')
.json<Flags>()
return ctx.json({
id: user.id,
name: user.name,
score: stats.score,
enabled: flags.enabled,
})
})
// Multiple origins with explicit portable concurrency.
app.get('/user-summary-parallel', async (ctx) => {
const { user, stats, flags } = await ctx.parallel({
user: ctx.fetch('https://users.example.test/users/123').json<User>(),
stats: ctx.fetch('https://stats.example.test/users/123').json<Stats>(),
flags: ctx.fetch('https://flags.example.test/users/123').json<Flags>(),
})
return ctx.json({
id: user.id,
name: user.name,
score: stats.score,
enabled: flags.enabled,
})
})
export default app

The comments separate one structured origin, explicit sequential composition, and ctx.parallel. Separate awaits retain sequential JavaScript semantics. The explicit keyed group is the portable concurrency contract across JavaScript and Native targets. Results retain their source keys even when hosts resolve the operations in another order.

HTTP 404 and 500 remain ordinary response data. DNS, connection, timeout, and host failures fail the effect.

A request whose URL or options depend on a previous result lowers to a later continuation point. The compiler does not pretend that dependent effects are an independent group.

import { Pulse } from '@pulse-compute/pulse'
const app = new Pulse({ auto: true })
app.get('/archive', async (ctx) => {
return ctx.fetch('https://assets.example.com/archive.bin')
})
export default app

The direct response path preserves status, headers, repeated headers, and the host-owned body. User code cannot inspect or transform the opaque body.