Namespaces allow you to filter events so your listeners only respond to specific events within defined scopes.
Basic Usage
// Global listener - responds to all events
listener.on("space:created", event => { ... });
// Namespaced listener - only responds to events in the 'green' space
listener.namespace(['space:green'], (green) => {
green.on("space:created", event => { ... });
});
Namespace Patterns
Event Type Prefixes
space:
- Space-level events (e.g., space:configure
, space:created
, space:updated
)
workbook:
- Workbook-level events (e.g., workbook:created
, workbook:submitAction
)
sheet:
- Sheet-level events (e.g., sheet:created
, sheet:updated
, sheet:deleted
)
*:
- Wildcard pattern to match any event type
Custom Suffixes
Create custom namespaces using the pattern eventType:customSuffix
:
// Listen to ALL event types in the 'red' namespace
listener.namespace(['*:red'], (red) => {
red.filter({ job: 'space:configure' }, (configure) => {
// Handle space configuration for red namespace
})
})
// Listen to events in the 'green' space
listener.namespace(['space:green'], (green) => {
green.filter({ job: 'space:configure' }, (configure) => {
// Handle space configuration for green space
})
})
Setting Namespaces
In Spaces
When creating a space via the API, you can assign a namespace:
const space = await api.spaces.create({
name: "My Space",
namespace: "my-namespace",
workbook: {
// workbook config
}
});
In Workbooks and Sheets
Workbooks and spaces use namespace
, while sheets use slug
as their identifier:
const workbook = new Workbook({
name: 'My Workbook',
namespace: 'team1', // Workbook namespace - affects all events from this workbook
sheets: [
{
name: "Contacts",
slug: "contacts", // Sheet slug (not namespace) - unique identifier for this sheet
fields: [
// your fields here
]
}
]
})
Common Naming Patterns
:red
, :green
- Color-based organization
:team1
, :team2
- Team-based organization
:feature1
, :feature2
- Feature-based organization
:xdk-test
, :my-namespace
- Project-based organization
Complete Example
Here’s a complete example that sets up a namespaced listener for space configuration:
import api from "@flatfile/api";
export default function flatfileEventListener(listener) {
listener.namespace(["space:red"], (red) => {
red.on(
"job:ready",
{ job: "space:configure" },
async ({ context: { spaceId, jobId } }) => {
try {
await api.jobs.ack(jobId, {
info: "Configuring red space...",
progress: 10,
});
await api.documents.create(spaceId, {
title: "Welcome to Red Space",
body: "# Welcome to your Red Space\n---\n",
});
await api.spaces.update(spaceId, {
metadata: {
theme: {
root: { primaryColor: "red" },
sidebar: {
backgroundColor: "red",
textColor: "white",
},
},
},
});
await api.jobs.complete(jobId, {
outcome: { message: "Space configured successfully." },
});
} catch (error) {
await api.jobs.fail(jobId, {
outcome: { message: "Configuration failed." },
});
}
}
);
});
}