Skip to content

Commit

Permalink
Added re-init api, fixes #72, fixes #67, re-fixes #13
Browse files Browse the repository at this point in the history
  • Loading branch information
oliyh committed Aug 10, 2020
1 parent a29d104 commit fae1da9
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 5 deletions.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Features include:
* Queues websocket messages until ready
* Websocket reconnects on disconnect
* Simultaneous connection to multiple GraphQL services
* Handles reauthentication without disruption

## Usage

Expand Down Expand Up @@ -120,7 +121,7 @@ Options can be passed to the init event, with the following possibilities:
}

:http {:url "http://bar.io/graphql" ;; override the http url (defaults to /graphql)
:impl {} ;; implementation-specific options (see clj-http or hato for options, defaults to {})
:impl {} ;; implementation-specific options (see clj-http or hato for options, defaults to {}, may be a literal or a function that returns the options)
}
}])
```
Expand Down Expand Up @@ -194,6 +195,25 @@ When initializing re-graph, configure both the HTTP and WebSocket connections wi

In the call, you can provide any supported re-graph or hato options. Be careful though; hato convenience options for the HTTP client will be ignored when using the `:http-client` option.

## Re-initialisation

When initialising re-graph you may have included authorisation tokens e.g.

```
(re-frame/dispatch [::re-graph/init {:http {:url "http://foo.bar/graph-ql"
:impl {:headers {"Authorization" 123}}}
:ws {:connection-init-payload {"Authorization" 123}}}])
```

If those tokens expire you can refresh them using `re-init` as follows which allows you to change any parameter provided to re-graph:

```
(re-frame/dispatch [::re-graph/re-init {:http {:impl {:headers {"Authorization" 456}}}
:ws {:connection-init-payload {"Authorization" 456}}}])
```

The `connection-init-payload` will be sent again and all future remote calls will contain the updated parameters.

## Development

`cider-jack-in-clj&cljs`
Expand Down
14 changes: 14 additions & 0 deletions src/re_graph/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,20 @@
([instance-name subscription-id]
(re-frame/dispatch [::unsubscribe instance-name subscription-id])))

(re-frame/reg-event-fx
::re-init
[re-frame/trim-v internals/re-graph-instance]
(fn [{:keys [db instance-name]} [opts]]
(let [new-db (internals/deep-merge db opts)]
(merge {:db new-db}
(when (get-in new-db [:ws :ready?])
{:dispatch [::internals/connection-init instance-name]})))))

(defn re-init
([opts] (re-init default-instance-name opts))
([instance-name opts]
(re-frame/dispatch [::re-init instance-name opts])))

(re-frame/reg-event-fx
::init
(fn [{:keys [db]} [_ instance-name opts]]
Expand Down
14 changes: 10 additions & 4 deletions src/re_graph/internals.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@
trimmed-event)
trimmed-event))

(defn deep-merge [a b]
(merge-with
(fn [a b]
(if (every? map? [a b])
(deep-merge a b)
b))
a b))

(defn- build-impl [impl]
(if (fn? impl)
(impl)
Expand Down Expand Up @@ -175,12 +183,10 @@
(re-frame/dispatch [::http-complete instance-name query-id (insert-http-status body status)]))))]
(re-frame/dispatch [::register-abort instance-name query-id #(.cancel future)])))))



(re-frame/reg-fx
::send-ws
(fn [[websocket payload]]
(println "Send ws" websocket payload)
(log/debug "Send ws" websocket payload)
#?(:cljs (.send websocket (encode payload))
:clj (interop/send-ws websocket (encode payload)))))

Expand Down Expand Up @@ -275,7 +281,7 @@
((on-open instance-name websocket))))
([instance-name websocket]
(fn []
(println "opened ws!" websocket)
(log/info "opened ws" websocket)
(re-frame/dispatch [::on-ws-open instance-name websocket]))))

(defn- on-close [instance-name]
Expand Down
56 changes: 56 additions & 0 deletions test/re_graph/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -846,3 +846,59 @@

(is (nil? (get-in @app-db [:re-graph :service-a :subscriptions "a-sub"])))
(is (nil? (get-in @app-db [:re-graph :service-b :subscriptions "b-sub"]))))))))


(deftest reinit-ws-test []
(run-test-sync
(install-websocket-stub!)

(testing "websocket connection payload is sent"
(let [last-ws-message (atom nil)]

(re-frame/reg-fx
::internals/send-ws
(fn [[ws payload]]
(is (= ::websocket-connection ws))
(reset! last-ws-message payload)))

(re-frame/dispatch [::re-graph/init {:ws {:url "ws://socket.rocket"
:connection-init-payload {:auth-token 123}}}])

(is (= {:type "connection_init"
:payload {:auth-token 123}}
@last-ws-message))

(testing "updated when re-inited"
(re-frame/dispatch [::re-graph/re-init {:ws {:connection-init-payload {:auth-token 234}}}] )

(is (= {:type "connection_init"
:payload {:auth-token 234}}
@last-ws-message)))))))

(deftest re-init-http-test []
(run-test-sync

(testing "http headers are sent"

(let [last-http-message (atom nil)]
(re-frame/reg-fx
::internals/send-http
(fn [[_ _ http-url {:keys [request]} :as fx-args]]
(reset! last-http-message request)
(dispatch-response fx-args {})))

(re-frame/dispatch [::re-graph/init {:http {:url "http://foo.bar/graph-ql"
:impl {:headers {"Authorization" 123}}}
:ws nil}])

(re-frame/dispatch [::re-graph/query "{ things { id } }" {:some "variable"} [::on-thing]])

(is (= {:headers {"Authorization" 123}}
@last-http-message))

(testing "and can be updated"
(re-frame/dispatch [::re-graph/re-init {:http {:impl {:headers {"Authorization" 234}}}}])
(re-frame/dispatch [::re-graph/query "{ things { id } }" {:some "variable"} [::on-thing]])

(is (= {:headers {"Authorization" 234}}
@last-http-message)))))))

0 comments on commit fae1da9

Please sign in to comment.