Middleware Cookbook
Common middleware patterns. All examples work on both the Emitter (server) and Collector (client) unless noted.
Resolve image placeholders
The model emits {{img:filename}} — resolve to a presigned S3 URL before the client sees it.
Server-side only.
Python
def resolve_images(patch, next_fn):
if patch.op == 'add' and isinstance(patch.value, str):
if patch.value.startswith('{{img:'):
filename = patch.value[6:-2]
patch = patch.replace(value=get_presigned_url(filename))
next_fn(patch)
emitter.use(resolve_images)Strip restricted fields
Drop patches for fields the current user has no permission to see. Server-side only.
Python
RESTRICTED = {'internalNotes', 'costBasis', 'margin'}
def strip_restricted(patch, next_fn):
field = patch.path.split('.')[-1]
if field not in RESTRICTED:
next_fn(patch)
emitter.use(strip_restricted)Mirror a field
Copy values from one path to another as they stream. Useful for maintaining a derived field. Client-side.
// Mirror term → originalTerm as it streams
collector.use((patch, next) => {
next(patch)
if (patch.path.endsWith('.term')) {
next({ ...patch, path: patch.path.replace('.term', '.originalTerm') })
}
})Transform a value
Normalise a date string to a Date object before it reaches state. Client-side.
collector.use((patch, next) => {
if (patch.op === 'complete' && patch.path === 'publishedAt') {
next({ ...patch, value: new Date(patch.value as string) })
return
}
next(patch)
})Log all patches
Debug helper — log every patch passing through. Works on either side.
Python
def log_patches(patch, next_fn):
print(f"[{patch.op}] {patch.path}")
next_fn(patch)
emitter.use(log_patches)Suppress pathcomplete for a path
Drop complete patches for a specific path to prevent pathcomplete from firing on the
client. Client-side.
collector.use((patch, next) => {
if (patch.op === 'complete' && patch.path === 'metadata') return
next(patch)
})Compose multiple middleware
Register in order — runs top to bottom:
Python
emitter.use(resolve_images)
emitter.use(strip_restricted)
emitter.use(log_patches)Last updated on