EdgeStream
Getting Started
From zero to your first typed subscription in five steps — create an EdgeStream instance, register a server, add hooks, start the stream, and subscribe.
Step 1 — Add Dependencies
EdgeStream packages are workspace-local. Reference them from your package.json using the pnpm workspace protocol:
{
"dependencies": {
"edge-stream-js": "workspace:*",
"edge-stream-js-react": "workspace:*"
}
}
pnpm install
Step 2 — Create an EdgeStream Instance
Use the createEdgeStream() factory function. Pass optional config for log level and devtools:
import { createEdgeStream } from 'edge-stream-js';
export const edgeStream = createEdgeStream({
logLevel: 'info', // 'debug' | 'info' | 'warn' | 'error'
enableDevtools: true, // enable React devtools integration
});
Step 3 — Register a Server
A server connects EdgeStream to a backend hub. Use SignalR transport for browser apps:
import { createEdgeStream } from 'edge-stream-js';
const edgeStream = createEdgeStream({ logLevel: 'info' });
edgeStream.registerServer({
id: 'bas', // your server identifier
type: 'bas', // 'bas' or 'chat'
name: 'BizFirst Application Server',
url: '/edge-stream-hub', // hub path (relative or absolute)
transportConfig: {
type: 'signalr',
url: '/edge-stream-hub',
accessToken: () => authService.getToken(), // async token factory
reconnect: {
maxAttempts: 0, // 0 = infinite reconnect attempts
initialDelayMs: 1000,
maxDelayMs: 30000,
backoffMultiplier: 2,
},
},
});
Step 4 — Add Hooks (Optional)
Register hooks to add logging, normalization, or custom validation. The HookActivityLogger is strongly recommended during development:
import { NormalizationHook } from 'edge-stream-js';
import { HookActivityLogger } from 'observability-hooks-js';
const server = edgeStream.server('bas')!;
// Priority 5 — runs first, captures timing for all hooks
server.incomingPipeline.addHook(new HookActivityLogger());
// Priority 110 — CloudEvents normalization
server.incomingPipeline.addHook(new NormalizationHook(true));
Step 5 — Start and Subscribe
// Start all registered servers (connect transports)
await edgeStream.start();
// Subscribe to a topic
const sub = edgeStream.subscribe(
'bas',
'workflow.execution.*',
(envelope) => {
console.log('Received:', envelope.body);
console.log('Topic:', envelope.meta.topic);
console.log('At:', envelope.meta.receivedAt);
}
);
// Later — clean up when done
sub.unsubscribe();
Complete Minimal Example
import { createEdgeStream, NormalizationHook } from 'edge-stream-js';
// 1. Create instance
const edgeStream = createEdgeStream({ logLevel: 'debug' });
// 2. Register server with SignalR transport
edgeStream.registerServer({
id: 'bas',
type: 'bas',
url: '/hubs/edge-stream',
transportConfig: {
type: 'signalr',
url: '/hubs/edge-stream',
reconnect: { maxAttempts: 10, initialDelayMs: 1000, maxDelayMs: 30000, backoffMultiplier: 2 },
},
});
// 3. Add normalization hook
edgeStream.server('bas')!.incomingPipeline.addHook(new NormalizationHook());
// 4. Subscribe to lifecycle events
edgeStream.on('stream:started', () => console.log('EdgeStream ready'));
edgeStream.on('server:error', (e) => console.error('Connection error', e.data?.error));
// 5. Start
await edgeStream.start();
// 6. Subscribe to workflow events
const sub = edgeStream.subscribe('bas', 'workflow.*', (env) => {
console.log('Workflow event:', env.meta.topic, env.body);
});
// 7. Send a message
await edgeStream.send('bas', 'workflow.ping', { timestamp: new Date() });
// 8. Cleanup
sub.unsubscribe();
await edgeStream.stop();
React Quick Start
Wrap your app with EdgeStreamProvider and use hooks in components:
// main.tsx
import React from 'react';
import { EdgeStreamProvider } from 'edge-stream-js-react';
import { edgeStream } from './edge-stream-instance';
function App() {
return (
<EdgeStreamProvider
edgeStreamClient={edgeStream}
onError={(err) => console.error('EdgeStream error:', err)}
onConnectionStatusChange={(status) => console.log('Status:', status)}
>
<YourApp />
</EdgeStreamProvider>
);
}
// WorkflowStatus.tsx
import { useSubscription, useEdgeStream } from 'edge-stream-js-react';
function WorkflowStatus({ workflowId }: { workflowId: string }) {
const { isSubscribed, error } = useSubscription(
'bas',
`workflow.${workflowId}.*`,
(envelope) => {
console.log('Status update:', envelope.body);
}
);
if (error) return <div>Connection error: {error.message}</div>;
if (!isSubscribed) return <div>Connecting...</div>;
return <div>Listening for workflow events</div>;
}
Next Steps
Now that you have a working EdgeStream instance, explore the Architecture page for a deeper look at how the pipeline works, then move on to Guide 2: Message Pipeline for the full pipeline breakdown.