@@ -3,12 +3,30 @@ defmodule Eventsourcingdb do
33 `Eventsourcingdb` client SDK.
44 """
55
6- alias Eventsourcingdb.ObserveEventsOptions
7- alias Eventsourcingdb.ReadEventsOptions
8- alias Eventsourcingdb.Client
9- alias Eventsourcingdb.EventType
10- alias Eventsourcingdb.ManagementEvent
11- alias Eventsourcingdb.Event
6+ alias Eventsourcingdb . {
7+ ObserveEventsOptions ,
8+ ReadEventsOptions ,
9+ Client ,
10+ Event ,
11+ EventCandidate ,
12+ EventType ,
13+ ManagementEvent
14+ }
15+
16+ alias Eventsourcingdb . {
17+ IsSubjectPristine ,
18+ IsSubjectPopulated ,
19+ IsSubjectOnEventId ,
20+ IsEventQLTrue
21+ }
22+
23+ alias Eventsourcingdb.Errors . {
24+ ApiError ,
25+ DBError ,
26+ InvalidServerHeader ,
27+ InvalidResponseType ,
28+ TransmissionError
29+ }
1230
1331 alias Eventsourcingdb.Requests . {
1432 ObserveEvents ,
@@ -30,28 +48,44 @@ defmodule Eventsourcingdb do
3048 @ typedoc """
3149 The response format for a request
3250 """
33- @ type response ( t ) :: { :ok , t } | { :error , any ( ) }
51+ @ type primitive_response ( ) :: :ok | { :error , Exception . t ( ) }
52+
53+ @ typedoc """
54+ The response format for a request
55+ """
56+ @ type response ( t ) :: { :ok , t } | { :error , Exception . t ( ) }
57+
58+ @ typedoc """
59+ The response format for a force request
60+ """
61+ @ type response! ( t ) :: t
3462
3563 @ typedoc """
3664 The response format for a request returning a stream
3765 """
38- @ type stream_response ( t ) :: { :ok , Enumerable . t ( t ) } | { :error , any ( ) }
66+ @ type stream_response ( t ) :: { :ok , Enumerable . t ( t ) } | { :error , Exception . t ( ) }
3967
4068 @ typedoc """
4169 The response format for a force request returning a stream
4270 """
4371 @ type stream_response! ( t ) :: Enumerable . t ( t )
4472
73+ @ type precondition ( ) ::
74+ IsEventQLTrue . t ( )
75+ | IsSubjectOnEventId . t ( )
76+ | IsSubjectPopulated . t ( )
77+ | IsSubjectPristine . t ( )
78+
4579 @ doc """
4680 Pings the DB instance to check if it is reachable.
4781
4882 ## Examples
4983
50- iex> client = % Eventsourcingdb.Client{ "http://localhost:3000", "secrettoken"}
84+ iex> client = Eventsourcingdb.Client.new( "http://localhost:3000", "secrettoken")
5185 iex> Eventsourcingdb.ping(client)
5286 :ok
5387 """
54- @ spec ping ( Client . t ( ) ) :: :ok | { :error , any ( ) }
88+ @ spec ping ( Client . t ( ) ) :: primitive_response ( )
5589 def ping ( client ) do
5690 request_one_shot ( client , Ping . new ( ) )
5791 end
@@ -61,11 +95,11 @@ defmodule Eventsourcingdb do
6195
6296 ## Examples
6397
64- iex> client = % Eventsourcingdb.Client{ "http://localhost:3000", "secrettoken"}
98+ iex> client = Eventsourcingdb.Client.new( "http://localhost:3000", "secrettoken")
6599 iex> Eventsourcingdb.verify_api_token(client)
66100 :ok
67101 """
68- @ spec verify_api_token ( Client . t ( ) ) :: :ok | { :error , any ( ) }
102+ @ spec verify_api_token ( Client . t ( ) ) :: primitive_response ( )
69103 def verify_api_token ( client ) do
70104 request_one_shot ( client , VerifyApiToken . new ( ) )
71105 end
@@ -174,12 +208,14 @@ defmodule Eventsourcingdb do
174208 end
175209 ```
176210 """
177- @ spec write_events ( Client . t ( ) , maybe_improper_list ( ) , any ( ) ) :: response ( Event . t ( ) )
211+ @ spec write_events ( Client . t ( ) , nonempty_list ( EventCandidate . t ( ) ) , [ precondition ( ) ] ) ::
212+ response ( Event . t ( ) )
178213 def write_events ( client , events , preconditions \\ [ ] ) when is_list ( events ) do
179214 request_one_shot ( client , WriteEvents . new ( events , preconditions ) )
180215 end
181216
182- @ spec write_events! ( Client . t ( ) , maybe_improper_list ( ) , any ( ) ) :: Event . t ( )
217+ @ spec write_events! ( Client . t ( ) , nonempty_list ( EventCandidate . t ( ) ) , [ precondition ( ) ] ) ::
218+ response! ( Event . t ( ) )
183219 def write_events! ( client , events , preconditions \\ [ ] ) when is_list ( events ) do
184220 request_one_shot! ( client , WriteEvents . new ( events , preconditions ) )
185221 end
@@ -297,7 +333,7 @@ defmodule Eventsourcingdb do
297333 The function returns a stream from which you can retrieve one event at a time:
298334
299335 ```elixir
300- result = Eventsourcingdb.observe_events("/books/42")
336+ result = Eventsourcingdb.observe_events(client, "/books/42")
301337
302338 case result do
303339 {:ok, events} -> Enum.to_list(events)
@@ -352,7 +388,7 @@ defmodule Eventsourcingdb do
352388 "/books/42",
353389 %Eventsourcingdb.ObserveEventsOptions{
354390 recursive: false,
355- from_latest_event: %Eventsourcingdb.FromLatestEvevntOptions {
391+ from_latest_event: %Eventsourcingdb.FromLatestEventOptions {
356392 subject: "/books/42",
357393 type: "io.eventsourcingdb.library.book-borrowed",
358394 if_event_is_missing: :read_everything
@@ -429,7 +465,7 @@ defmodule Eventsourcingdb do
429465 request_one_shot ( client , RegisterEventSchema . new ( event_type , schema ) )
430466 end
431467
432- @ spec register_event_schema! ( Client . t ( ) , String . t ( ) , map ( ) ) :: ManagementEvent . t ( )
468+ @ spec register_event_schema! ( Client . t ( ) , String . t ( ) , map ( ) ) :: response! ( ManagementEvent . t ( ) )
433469 def register_event_schema! ( client , event_type , schema ) do
434470 request_one_shot! ( client , RegisterEventSchema . new ( event_type , schema ) )
435471 end
@@ -477,7 +513,7 @@ defmodule Eventsourcingdb do
477513 request_one_shot ( client , ReadEventType . new ( event_type ) )
478514 end
479515
480- @ spec read_event_type! ( Client . t ( ) , String . t ( ) ) :: EventType . t ( )
516+ @ spec read_event_type! ( Client . t ( ) , String . t ( ) ) :: response! ( EventType . t ( ) )
481517 def read_event_type! ( client , event_type ) do
482518 request_one_shot! ( client , ReadEventType . new ( event_type ) )
483519 end
@@ -496,16 +532,17 @@ defmodule Eventsourcingdb do
496532 # region Requests
497533 #
498534
499- @ spec request_stream! ( Client . t ( ) , struct ( ) ) :: any ( )
535+ @ spec request_stream! ( Client . t ( ) , struct ( ) ) :: stream_response! ( any ( ) )
500536 defp request_stream! ( client , request ) do
501537 result = request_stream ( client , request )
502538
503539 case result do
504540 { :ok , stream } -> stream
505- { :error , type , reason } -> raise ( type , reason )
541+ { :error , reason } -> raise ( reason )
506542 end
507543 end
508544
545+ @ spec request_stream ( Client . t ( ) , struct ( ) ) :: stream_response ( any ( ) )
509546 defp request_stream ( client , request ) do
510547 case open_stream ( client , request ) do
511548 { :ok , response } ->
@@ -524,11 +561,12 @@ defmodule Eventsourcingdb do
524561
525562 { :ok , stream }
526563
527- { :error , type , reason } ->
528- { :error , type , reason }
564+ { :error , reason } ->
565+ { :error , reason }
529566 end
530567 end
531568
569+ @ spec open_stream ( Client . t ( ) , struct ( ) ) :: response ( any ( ) )
532570 defp open_stream ( client , request ) do
533571 response =
534572 client
@@ -600,25 +638,24 @@ defmodule Eventsourcingdb do
600638 ^ expected_type ->
601639 { :ok , request_module . process ( payload ) }
602640
603- # Forward Errors from the DB as :db_error
641+ # Forward Errors from the DB as %DBError{}
604642 "error" ->
605- { :error , :db_error , payload }
643+ { :error , % DBError { payload: payload } }
606644
607645 # Ignore heartbeat messages.
608646 "heartbeat" ->
609647 nil
610648
611649 other ->
612- { :error , :invalid_response_type ,
613- "Expected type \" #{ expected_type } \" , but got \" #{ other } \" " }
650+ { :error , % InvalidResponseType { expected: expected_type , actual: other } }
614651 end
615652
616653 { :error , reason } ->
617654 { :error , reason }
618655 end
619656 end
620657
621- @ spec request_one_shot ( Client . t ( ) , struct ( ) ) :: any ( )
658+ @ spec request_one_shot ( Client . t ( ) , struct ( ) ) :: response ( any ( ) )
622659 defp request_one_shot ( client , request ) do
623660 request_module = get_request_module ( request )
624661
@@ -675,7 +712,6 @@ defmodule Eventsourcingdb do
675712 |> Keyword . merge ( client . req_options )
676713
677714 Req . new ( opts )
678- # |> Req.Request.append_request_steps(inspect: &IO.inspect/1)
679715 end
680716
681717 defp implements_protocol? ( protocol , mod ) when is_atom ( protocol ) and is_struct ( mod ) do
@@ -702,19 +738,20 @@ defmodule Eventsourcingdb do
702738 #
703739
704740 defp validate_transmission ( { :error , reason } ) do
705- { :error , :transmission_error , reason }
741+ { :error , % TransmissionError { reason: reason } }
706742 end
707743
708744 defp validate_transmission ( { :ok , _ } ) , do: { :ok }
709745
710746 @ spec validate_server_headers ( { :ok , Req.Response . t ( ) } ) ::
711- { :ok } | { :error , :invalid_server_header }
747+ { :ok } | { :error , InvalidServerHeader . t ( ) }
712748 defp validate_server_headers ( { :ok , response } ) do
713- case response
714- |> Req.Response . get_header ( "Server" )
715- |> Enum . any? ( fn val -> String . starts_with? ( val , "EventSourcingDB/" ) end ) do
716- true -> { :ok }
717- false -> { :error , :invalid_server_header }
749+ if response
750+ |> Req.Response . get_header ( "Server" )
751+ |> Enum . any? ( fn val -> String . starts_with? ( val , "EventSourcingDB/" ) end ) do
752+ { :ok }
753+ else
754+ { :error , % InvalidServerHeader { } }
718755 end
719756 end
720757
@@ -723,7 +760,7 @@ defmodule Eventsourcingdb do
723760 end
724761
725762 defp validate_response ( { :ok , % { body: body } } ) do
726- { :error , :api_error , body }
763+ { :error , % ApiError { reason: body } }
727764 end
728765
729766 defp validate_request_response ( response , request_module ) do
0 commit comments