Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import { EventStoresClient, NamespacesClient } from '@cratis/chronicle.contracts
async function readAvailableNamespaces(eventStores: EventStoresClient, namespaces: NamespacesClient): Promise<string[]> {
await eventStores.ensureEventStore({ Name: 'shopping' });

// Queries stream results so they can also be observed; one-shot callers take the first result.
for await (const result of namespaces.allNamespaces({ EventStore: 'shopping' })) {
return result.Data;
}

return [];
const result = await namespaces.allNamespaces({ EventStore: 'shopping' });
return result.Data.map(namespace => namespace.Name);
}
```
6 changes: 3 additions & 3 deletions Source/ChronicleClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { diag } from '@opentelemetry/api';
import { SpanStatusCode } from '@opentelemetry/api';
import { ChronicleOptions } from './ChronicleOptions';
import { ChronicleConnection } from './connection';
import { ensureCommandSuccess, ensureQuerySuccess, firstQueryResult } from './connection/callResults';
import { ensureCommandSuccess, ensureQuerySuccess } from './connection/callResults';
import { ConnectionLifecycle } from './connection/ConnectionLifecycle';
import { KernelKeepAlive } from './connection/KernelKeepAlive';
import { EventStore } from './EventStore';
Expand Down Expand Up @@ -168,9 +168,9 @@ export class ChronicleClient implements IChronicleClient {
try {
const response = await this.withReconnect('get_event_stores', async () => {
await this.ensureConnected();
return firstQueryResult('get event stores', this._connection.eventStores.allEventStores({}));
return this._connection.eventStores.allEventStores({});
});
const result = ensureQuerySuccess('get event stores', response).map((name: string) => new EventStoreName(name));
const result = ensureQuerySuccess('get event stores', response).map(eventStore => new EventStoreName(eventStore.Name));
this._logger.verbose('Retrieved event stores from kernel', {
count: result.length
});
Expand Down
6 changes: 3 additions & 3 deletions Source/EventStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { diag } from '@opentelemetry/api';
import { SpanStatusCode } from '@opentelemetry/api';
import { ChronicleConnection } from './connection';
import { ConnectionLifecycle } from './connection/ConnectionLifecycle';
import { ensureQuerySuccess, firstQueryResult } from './connection/callResults';
import { ensureQuerySuccess } from './connection/callResults';
import { EventLog } from './eventSequences/EventLog';
import { EventSequence } from './eventSequences/EventSequence';
import { EventSequenceId } from './eventSequences/EventSequenceId';
Expand Down Expand Up @@ -164,8 +164,8 @@ export class EventStore implements IEventStore {
return ChronicleTracer.startActiveSpan('chronicle.event_store.get_namespaces', async span => {
span.setAttribute('chronicle.event_store', this.name.value);
try {
const response = await firstQueryResult('get namespaces', this._connection.namespaces.allNamespaces({ EventStore: this.name.value }));
const result = ensureQuerySuccess('get namespaces', response).map((namespace: string) => new EventStoreNamespaceName(namespace));
const response = await this._connection.namespaces.allNamespaces({ EventStore: this.name.value });
const result = ensureQuerySuccess('get namespaces', response).map(namespace => new EventStoreNamespaceName(namespace.Name));
span.setStatus({ code: SpanStatusCode.OK });
return result;
} catch (error) {
Expand Down
6 changes: 6 additions & 0 deletions Source/connection/ChronicleConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ObserversDefinition,
ProjectionsDefinition,
ReactorsDefinition,
ReadModelExplorerDefinition,
ReadModelsDefinition,
RecommendationsDefinition,
ReducersDefinition,
Expand Down Expand Up @@ -184,6 +185,10 @@ export class ChronicleConnection implements ChronicleServices {
return this._services.readModels;
}

get readModelExplorer() {
return this._services.readModelExplorer;
}

get materializedReadModels() {
return this._services.materializedReadModels;
}
Expand Down Expand Up @@ -286,6 +291,7 @@ export class ChronicleConnection implements ChronicleServices {
reducers: factory.create(ReducersDefinition, this._channel),
projections: factory.create(ProjectionsDefinition, this._channel),
readModels: factory.create(ReadModelsDefinition, this._channel),
readModelExplorer: factory.create(ReadModelExplorerDefinition, this._channel),
materializedReadModels: factory.create(MaterializedReadModelsDefinition, this._channel),
jobs: factory.create(JobsDefinition, this._channel),
webhooks: factory.create(WebhooksDefinition, this._channel),
Expand Down
2 changes: 2 additions & 0 deletions Source/connection/ChronicleServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
ObserversClient,
ProjectionsClient,
ReactorsClient,
ReadModelExplorerClient,
ReadModelsClient,
RecommendationsClient,
ReducersClient,
Expand Down Expand Up @@ -43,6 +44,7 @@ export interface ChronicleServices {
reducers: ReducersClient;
projections: ProjectionsClient;
readModels: ReadModelsClient;
readModelExplorer: ReadModelExplorerClient;
materializedReadModels: MaterializedReadModelsClient;
jobs: JobsClient;
webhooks: WebhooksClient;
Expand Down
23 changes: 23 additions & 0 deletions Source/connection/callResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ export interface QueryResultLike<TData> extends CallResultLike {
Data: TData;
}

/**
* Structural shape shared by every Chronicle command result envelope that carries a response payload.
*/
export interface CommandResultLike<TResponse> extends CallResultLike {
Response: TResponse | undefined;
}

/**
* Error thrown when a Chronicle command or query did not succeed.
*/
Expand Down Expand Up @@ -81,6 +88,22 @@ export function ensureCommandSuccess(operation: string, result: CallResultLike):
}
}

/**
* Ensures a Chronicle command executed successfully, returning its response or throwing when it did not.
* @param operation - The operation the result belongs to, used for error reporting.
* @param result - The command result envelope returned by the kernel.
* @returns The response produced by the command.
*/
export function ensureCommandResponse<TResponse>(operation: string, result: CommandResultLike<TResponse>): TResponse {
if (!isCallSuccess(result)) {
throw new ChronicleCallFailed(operation, result);
}

// A successful command result always carries its response; the wire type marks it optional
// only because protobuf gives every singular message field a technically-absent state.
return result.Response!;
}

/**
* Ensures a Chronicle query executed successfully, returning its data or throwing when it did not.
* @param operation - The operation the result belongs to, used for error reporting.
Expand Down
Loading
Loading