Angular — examples
Beyond the minimal binding snippet — the patterns examples/angular is built on: composing a data layer, slicing shared fields, and driving the UI off task state.
Component wiring — DI client + signals
injectAtollPool returns the provideAtoll-registered client; taskState/sharedValue release their subscriptions on destroy. effect() re-runs the latest-wins query once seeded.
private readonly incidents = injectAtollPool<IncidentsClient>('incidents');
private readonly seedTask = taskState(initIncidents);
private readonly pageTask = taskState(this.incidents.queryIncidents);
private readonly metricsValue = sharedValue(incidentsMemory, 'state.metrics');
protected readonly metrics = computed(() => this.metricsValue() ?? null);
protected readonly isFetching = computed(() => this.pageTask.state().pending);
constructor() {
this.seedTask.runOnce(); // ignores repeats while pending/settled
effect(() => {
const q = this.query();
if (this.seedTask.state().settled) this.pageTask.run(q);
});
}NgModule apps — AtollModule
The NgModule equivalent of provideAtoll — same pool declarations and lifecycle, plus constructor-parameter injection via @InjectAtollPool.
@NgModule({
imports: [
AtollModule.forRoot({
pools: [{ name: 'incidents', client: incidents }],
}),
],
})
export class AppModule {}
@Injectable()
export class ReportsService {
constructor(
@InjectAtollPool('incidents') private readonly pool: WorkerPool,
) {}
}Inline worker pools
Declarations can build the pool directly — the bundler-detectable new Worker(new URL(...)) stays inline so the worker entry is emitted as its own chunk.
provideAtoll({
pools: [{
name: 'digest',
worker: () => new Worker(
new URL('./digest.worker.ts', import.meta.url),
{ type: 'module' },
),
sharedMemory: digestMemory,
poolSize: 2,
tasks: { hash: HashDigest },
}],
})