v6.2.1 (2024-05-13)
- Include dist in release
v6.2.0 (2024-05-10)
- Support providing an x.509 certificate for user authentication (#361) View
Updated error handling to use NotFoundError instead of UnknownError in projection operations when the projection doesn't exist
- Previously, the server was returning UnknownError when a projection didn't exist. EventStoreDB now returns NotFoundError. This change updates the client to use NotFoundError instead of UnknownError when a projection doesn't exist. View
⚠️ This only affects users who are using EventStoreDB versions 24.6 and greater.
- EventStoreDB recently configured the ShutdownTimeout to 5s after being set to 30s in recent .NET releases resulting to different error status code returned from the server. The client now expects a CancelledError when the node is terminated. View
️
⚠️ This only affects users who are using EventStoreDB versions 24.4 and greater.
- The tests are now run against Node LTS (v20.12.2 as of this release).
- We are now using tsdoc for documentation comments as eslint-plugin-jsdoc does not support NodeJS versions below 18.
v6.1.0 (2023-12-19)
- Add support for caught up and fell behind subscription message View
- Increase test coverage for reconnection View
- Use dynamic tags instead of hardcoding esdb versions View
- Update TypeScript, ESLint and other dependencies View
- Update grpc-js to 1.9.12 View
🎉 Thanks for @jokesterfr and @Imanghvs for their contributions! 🎉
v6.0.0 (2023-08-25)
Previously, we would throw an UnavailableError when the server was unavailable to take a request, or a stream was cancelled by the server. This release now throws a CancelledError when the stream is cancelled, allowing users to distinguish between them.
If users are catching UnavailableError on a stream for this situation, they should now be looking for a CancelledError. View
Before:
try {
for await (const event of client.readStream("my_stream")) {
// do something
}
} catch (error) {
if (isCommandError(error)) {
if (error.type === ErrorType.UNAVAILABLE) {
// Server is unavailable to take request
// _OR_
// Stream was cancelled by server
}
}
}After:
try {
for await (const event of client.readStream("my_stream")) {
// do something
}
} catch (error) {
if (isCommandError(error)) {
if (error.type === ErrorType.CANCELLED) {
// Stream was cancelled by server
}
if (error.type === ErrorType.UNAVAILABLE) {
// Server is unavailable to take request
}
}
}- fix out of bounds value for stream revision View
v5.0.1 (2023-02-16)
🎉 Thanks for @coffemakingtoaster for their contributions! 🎉
v5.0.0 (2022-11-04)
Previously, a recorded event's created property was being returned in ticks, a 64bit integer in 100ns precision. As well as being an unusual format, this was being parsed into a Number, so was unsafe. This release changes the property to be represented by a Date.
created was an unsafe "ticks" since epoch:
for await (const { event } of client.readStream(STREAM_NAME)) {
// 16675621600650000 (greater than Number.MAX_SAFE_INTEGER)
console.log(event?.created);
}created is a Date:
for await (const { event } of client.readStream(STREAM_NAME)) {
// 2022-11-04T11:42:40.065Z
console.log(event?.created);
}v4.0.0 (2022-09-02)
Due to a bug on the server, previously, the trackEmittedStreams option was setting emitEnabled, and not trackEmittedStreams. This release adds the emitEnabled option and corrects the behaviour of trackEmittedStreams, with a polyfill for earlier server versions. View
Setting trackEmittedStreams would enable emitting, but not track streams.
await client.createProjection(PROJECTION_NAME, projectionQuery, {
trackEmittedStreams: true,
});Setting emitEnabled works as expected:
await client.createProjection(PROJECTION_NAME, projectionQuery, {
emitEnabled: true,
});Setting both emitEnabled and trackEmittedStreams works as expected:
await client.createProjection(PROJECTION_NAME, projectionQuery, {
emitEnabled: true,
trackEmittedStreams: true,
});Setting only trackEmittedStreams will be rejected by the server:
// incorrect
await client.createProjection(PROJECTION_NAME, projectionQuery, {
trackEmittedStreams: true,
});When connected to a server that supports it (>22.6), events read from a stream will include their commit and prepare position. View
- Prevent multiple appends within the same event loop creating many batches, and improve backpressure. View
- Destroy read stream if stream is not found. View
- Only swallow unimplemented errors when creating server-features. View
- Remove deprecated consumer strategy names. View
- Remove deprecated persistent subscription methods. View
- Remove deprecated
getProjectionStatisticsmethod. View
v3.4.0 (2022-07-14)
Adds retryCount property to events from subscribeToPersistentSubscriptionToStream and subscribeToPersistentSubscriptionToAll View
const subscription = client.subscribeToPersistentSubscriptionToStream(
STREAM_NAME,
GROUP_NAME
);
for await (const event of subscription) {
try {
console.log(
`handling event ${event.event?.type} with retryCount ${event.retryCount}`
);
await handleEvent(event);
await subscription.ack(event);
} catch (error) {
await subscription.nack(PARK, error.toString(), event);
}
}v3.3.1 (2022-04-06)
- Close channels when they fail to prevent memory leak. View
v3.3.0 (2022-03-30)
- Added
disposemethod to dispose all currently running streaming calls. View
v3.2.0 (2022-02-23)
New methods for persistent subscription control have been added.
| Method Name | Description | |
|---|---|---|
getPersistendSubscriptionToAllInfo |
Gets information and statistics on the specified persistent subscription to $all and its connections. | View |
getPersistentSubscriptionToStreamInfo |
Gets information and statistics on the specified persistent subscription and its connections. | View |
listAllPersistentSubscriptions |
Lists all persistent subscriptions. | View |
listPersistentSubscriptionsToAll |
Lists persistent subscriptions to the $all stream. | View |
listPersistentSubscriptionsToStream |
Lists persistent subscriptions to a specified stream. | View |
replayParkedMessagesToAll |
Replays the parked messages of a persistent subscription to $all. | View |
replayParkedMessagesToStream |
Replays the parked messages of a persistent subscription. | View |
restartPersistentSubscriptionSubsystem |
Restarts the persistent subscription subsystem. | View |
The connectionName option has been added allowing you to name the connection in logs and persistent subscription info. View
- Defaults to a UUID.
- Adds
connectionNameoption to constructor. - Adds
connectionName=<name>param to connection string - Adds
connectionNamegetter to client for reading the name of the client.
Previously, to use JSONEventType or BinaryEventType you would have to provide a metadata key, even if you typed it as unknown or never. View
type MyEvent = JSONEventType<"my-event", { some: string }>;
// Property 'metadata' is missing in type '{ type: "my-event"; data: { some: string; }; }' but required in type 'JSONEventType<"my-event", { some: string; }, unknown>'.ts(2741)
const myEventData: MyEvent = {
type: "my-event",
{ some: "data" }
}type MyEvent = JSONEventType<"my-event", { some: string }>;
const myEventData: MyEvent = {
type: "my-event",
{ some: "data" }
}Previously, if you had a union of event types, you would lose the ability it descriminate them after converting them to EventData or a RecordedEvent due to typescript combining them into an intersection of the types. View
type MyFirstEvent = JSONEventType<
"my-first-type",
{ some: string; other: string }
>;
type MySecondEvent = JSONEventType<
"my-second-event",
{ other: string; another: boolean }
>;
type MyEvents = MyFirstEvent | MySecondEvent;We can descriminate based on the type key.
const descriminateType = (eventData: MyEvents) => {
if (eventData.type === "my-first-type") {
// { some: string; other: string; }
eventData.data;
} else {
// { other: string; another: boolean }
eventData.data;
}
};However, this breaks down when MyEvents is passed directly to JSONEventData or a JSONRecordedEvent.
const descriminateType = (eventData: JSONRecordedEvent<MyEvents>) => {
if (eventData.type === "my-first-type") {
// { some: string; other: string; } | { other: string; another: boolean }
eventData.data;
} else {
// { some: string; other: string; } | { other: string; another: boolean }
eventData.data;
}
};You would have to use the helper type EventTypeToRecordedEvent to retain correct descrimination.
const descriminateType = (eventData: EventTypeToRecordedEvent<MyEvents>) => {
if (eventData.type === "my-first-type") {
// { some: string; other: string; }
eventData.data;
} else {
// { other: string; another: boolean }
eventData.data;
}
};You can now pass your union directly to JSONRecordedEvent, BinaryRecordedEvent or the now generic RecordedEvent without losing the ability to descriminate the union:
const descriminateType = (eventData: RecordedEvent<MyEvents>) => {
if (eventData.type === "my-first-type") {
// { some: string; other: string; }
eventData.data;
} else {
// { other: string; another: boolean }
eventData.data;
}
};All converter types (EventTypeToRecordedEvent, RecordedEventToEventType, EventTypeToEventData, EventDataToEventType, RecordedEventToEventData, EventDataToRecordedEvent) are still available.
You can now enforce the types you append to a stream. View
await client.appendToStream<MyEvents>(`my_stream`, jsonEvents);All method option types are not exported. View
- Fix doc comment for persistent subscription
startFromView - Ensure rediscovery is not run when the server returns a timeout View
- Consumer strategy names have been matched with server counterparts. View
DISPATCH_TO_SINGLE:dispatch_to_single->DispatchToSingle;ROUND_ROBIN:round_robin->RoundRobin;PINNED:pinned->Pinned;- Only affects users who pass the strings directly. Constants have changed to match.
- Previous strings will log a warning.
- Will be removed in
v4.0.0
- Persistent subscription methods, helpers and types relating to streams have been renamed to align with other method names. View
- Methods:
createPersistentSubscription->createPersistentSubscriptionToStreamdeletePersistentSubscription->deletePersistentSubscriptionToStreamsubscribeToPersistentSubscription->subscribeToPersistentSubscriptionToStreamupdatePersistentSubscription->updatePersistentSubscriptionToStream
- Helper Functions:
persistentSubscriptionSettingsFromDefaults->persistentSubscriptionToStreamSettingsFromDefaults
- Types:
PersistentSubscriptionSettings->PersistentSubscriptionToStreamSettingsPersistentSubscription->PersistentSubscriptionToStream
- Will be removed in
v4.0.0
- Methods:
v3.1.0 (2022-02-04)
getProjectionStatisticshas been renamed togetProjectionStatusto align with other clients. View
- Increase maximum readable event size to match maximum event size that can be written internally. View
getProjectionStatisticsis now deprecated View- Will be removed in
v4.0.0 - Use
getProjectionStatus
- Will be removed in
v3.0.0 (2022-01-27)
- The default node preference is now
LEADER. This applies when connecting with a connection string, and via the client constructor. View
The persistent subscriptions api has been updated to align with other eventstore clients, and the new persistent subscriptions to all api.
connectToPersistentSubscriptionhas been renamed tosubscribeToPersistentSubscriptionViewpersistentSubscriptionSettingskeys and default values have been changed. View
| Key | Default | Description |
|---|---|---|
- fromRevision
+ startFrom |
- START
+ END |
The exclusive position in the stream or transaction file the subscription should start from. |
- extraStats
+ extraStatistics |
false |
Enables if depth latency statistics should be tracked on subscription. |
- checkpointAfter
+ checkPointAfter |
2_000 |
The amount of time to try checkpoint after in milliseconds. |
- minCheckpointCount
+ checkPointLowerBound |
10 |
The minimum number of messages to process before a checkpoint may be written. |
- maxCheckpointCount
+ checkPointUpperBound |
1_000 |
The maximum number of messages to process before a checkpoint may be written. |
maxSubscriberCount |
- UNLIMITED
+ UNBOUNDED |
The maximum number of subscribers allowed.. |
- strategy
+ consumerStrategyName |
ROUND_ROBIN |
The strategy to use for distributing events to client consumers. |
| -- The following options remain unchanged. -- | ||
resolveLinkTos |
false |
Also return events targeted by the links. |
messageTimeout |
30_000 |
The amount of time in milliseconds after which a message should be considered to be timeout and retried. |
maxRetryCount |
10 |
The maximum number of retries (due to timeout) before a message is considered to be parked. |
liveBufferSize |
500 |
The size of the buffer listening to live messages as they happen. |
readBatchSize |
20 |
The number of events read at a time when paging in history. |
historyBufferSize |
500 |
The number of events to cache when paging through history. |
- Constant
UNLIMITEDhas been renamed toUNBOUNDED. View
The projections api has been completely overhauled, removing one time and transient projections. View
createProjection:createContinuousProjectionhas been renamed tocreateProjection.createOneTimeProjectionhas been removed.createTransientProjectionhas been removed.
listProjections:listContinuousProjectionshas been renamed tolistProjections.listOneTimeProjectionshas been removed.listTransientProjectionshas been removed.modehas been removed fromProjectionDetails, onlyCONTINUOUSprojections are returned.CONTINUOUSONE_TIME&TRANSIENTconstants have been removed.
resetProjection:writeCheckpointoption has been removed. (It previously had no effect ).
disableProjection:writeCheckpointoption has been removed. UseabortProjectionif wishing to set this tofalse.
abortProjection:abortProjectionmethod has been added.
deleteProjection:deleteEmittedStreamsoption now defaults tofalse.deleteStateStreamoption now defaults tofalse.deleteCheckpointStreamoption now defaults tofalse.
getProjectionState&getProjectionResult:fromPartitionoption has been renamed topartitionView
The client now supports setting deadlines for non-streaming gRPC requests, with a default deadline of 10 seconds (formerly Infinity). View
defaultDeadlineglobal setting has been added to the constructor options and connection string.deadlineoption has been added to all methods, to allow setting the deadline per request.DeadlineExceedederror will now be thrown if a deadline has been exceeded.
The client now supports persistent subscriptions to the all stream, for server version 21.10 and greater.
- Added
createPersistentSubscriptionToAllmethod. View
const groupName = "my_persistent_subscription";
const settings = persistentSubscriptionToAllSettingsFromDefaults({
// start from the beginning of the all stream
startFrom: START,
});
// Filter only events with type matching regex
const filter = eventTypeFilter({
regex: "^[0-9]*_regex_filter_eventType_[A-z]*$",
});
// Create a persistent subscrition to the all stream
await client.createPersistentSubscriptionToAll(groupName, settings, { filter });- Added
subscribeToPersistentSubscriptionToAllmethod. View
// Connect to the created persistent subscription to all stream
const psToAll = client.subscribeToPersistentSubscriptionToAll(groupName);
for await (const event of psToAll) {
doSomethingWithEvent(event);
// Acknowledge that the event has been handled
await psToAll.ack(event);
}- Added
updatePersistentSubscriptionToAllmethod. View
const updatedSettings = persistentSubscriptionToAllSettingsFromDefaults({
// Ensure that our previous settings are persisted
...settings,
// Enable extra statistics
extraStatistics: true,
});
// Update the persistent subscription to use new settings.
await client.updatePersistentSubscriptionToAll(groupName, updatedSettings)l- Added
deletePersistentSubscriptionToAllmethod. View
// delete the unwanted persistent subscription to all
await client.deletePersistentSubscriptionToAll(groupName);- When connected to server version
21.10and greater, the client will now send appended events over a single duplex stream, resulting in much faster append times. View - Client now internally checks if the server supports an api before sending a request. View
fromPartitionoption added togetProjectionStateView- Improved
tlsVerifyCertnot supported message View
- Fixed incorrect log message where http was logged as https and vice versa. View
updateProjectionoptiontrackEmittedStreamsname has been corrected asemitEnabled. View- Prevent
WRITE_AFTER_ENDfrom still being uncaught in rare cases. View
- Remove ack and nack via event id View
v2.1.1 (2021-09-29)
- Ack and nack take a resolved event, rather than an event id View
- Prevent
appendToStreamfrom writing after the stream has closed View
- Ack and nack via event id View
- Will be removed in
v3.0.0. - Pass entire resolved event
- Will be removed in
v2.1.0 (2021-08-05)
checkpointReachedcallback added to filter to allow checkpointing filtered reads to all ViewLinkEventtype added to event types ViewresolveLinkTosoption added toreadAllView
parseConnectionStringallows different casings ofnodePreferenceView
v2.0.0 (2021-07-28)
readStreamandreadAllreturn a stream of events View
To allow for reading large numbers of events without running out of memory, readSteam and readAll now return a readable stream rather than a promise of an array.
Before v1.x:
const events = await client.readStream<MyEventTypes>(streamName);
for (const event of events) {
doSomething(event);
}After v2.x:
const eventStream = client.readStream<MyEventTypes>(streamName);
for await (const event of eventStream) {
doSomething(event);
}- Ensure member is in a connectable state during discovery View
ConnectionTypeOptionsView
v1.2.2 (2021-06-18)
DNSClusterOptionsGossipClusterOptionsSingleNodeOptionstypes individually exported. View
ConnectionTypeOptionsView- Will be removed in
v2.0.0. - Use newly exported members directly.
- Will be removed in
v1.2.1 (2021-04-30)
ChannelCredentialOptionsinterface exported. View
v1.2.0 (2021-04-22)
- Pass path to Certificate File in Connection String View
v1.1.2 (2021-04-12)
- Allow setting END for create persistent subscription
fromRevisionView
v1.1.1 (2021-04-06)
- Remove
console.loginTwoWaySubscriptionView
v1.1.0 (2021-03-29)
- Add stream metadata methods View
setStreamMetadatagetStreamMetadata
v1.0.2 (2021-03-23)
- Replace all buffer encoding and decoding from
binary(latin1) toutf8View
v1.0.1 (2021-02-25)
- Improved JSdoc comments View
- Allow whitespace between tokens in connection string View
v1.0.0 (2021-02-17)
- Keep alives View
- Keep server connection alive when network traffic is low.
v0.0.0-alpha.17 (2021-02-11)
- Event types View
- Strongly type your events in
readEvents,subscribeToEventsandconnectToPersistantSubscription.
- Strongly type your events in
v0.0.0-alpha.16 (2021-02-04)
countrenamed tomaxCountand made optional View- Do not send credentials over insecure connection View
v0.0.0-alpha.15 (2021-01-27)
- Apply workaround for http2 assertion failure View
v0.0.0-alpha.14 (2021-01-25)
v0.0.0-alpha.13 (2021-01-14)
- Discovery options View
throwOnAppendFailureView- Correct naming
nextExpectedVersiontonextExpectedRevisionView
- Case-insensitive keys in connection string (#109) View
- Don't assume that metadata matches the event type View
- Prevent possible Channel race condition, that could allow a client to send requests to separate nodes. View
v0.0.0-alpha.12 (2020-12-30)
- Add generics to event types View
v0.0.0-alpha.11 (2020-12-22)
- Fix streams for node version 12.x View
v0.0.0-alpha.10 (2020-12-21)
- Subscriptions return
ReadableStreamsView
- .NET Client naming alignment View
v0.0.0-alpha.9 (2020-12-08)
- large internal refactor
- Update DNS discovery to work properly with EventStore Cloud. View
v0.0.0-alpha.8 (2020-11-19)
- Don't assume that events with content type
application/jsoncontain valid JSON View
v0.0.0-alpha.7 (2020-11-04)
- Test utilities accidentally being included in package View
v0.0.0-alpha.6 (2020-10-30)
v0.0.0-alpha.5 (2020-10-30)
- Projections API View
- Use secure by default View
v0.0.0-alpha.4 (2020-10-21)
-
debugging View
- Set the
DEBUGenvironment variable toesdb:*to enable debug logs
- Set the
streamNameis correctly converted to as string inStreamNotFoundErrorView