dexiecable 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 390eddcb71f97e5e8755696c49a8ce2417e7f8636e0e43be8742acd4f31f4b59
4
- data.tar.gz: 2058ae8d76759483bc047b4e74622154335eb55fa2124052f518f51d14539a0d
3
+ metadata.gz: d0959acfdf7865fc834899dd5ec5f14c5fbc85bdbc16a874f269bca2688d2579
4
+ data.tar.gz: 9e1b0ea9fb9a89c8289aa0faa77b47c6cdd09bb6fd336eb14c9292fc7c67d0a1
5
5
  SHA512:
6
- metadata.gz: 9057f8f5bdbb694a2673c47773db75d2d99a0f3383043908b51152f3f6279a4aabae9f4436dffeebd31e6882d684ca9f505f7a30e5bf1942de89787199a07589
7
- data.tar.gz: 39b6503f4ac13bf8abbaae9352ea6b2355bf34f3210dfd2cd99d87413a39a606f389f39236cafca0143aa94621f8bb0be5835fb34c08027cca0d0c2a7ac6feac
6
+ metadata.gz: a7106c7ed40f0fcf680109f1f476f4195e911836633766c0706d84852621f8a36b76a7eeaa78b2b9fb09ffa5f750a0147fae11a73fc4d8028e75b00840a77799
7
+ data.tar.gz: 8f78e58b67faef035cf225ce08d79f4ab0b954123fe76385e7f458e995f955f4880827b3c62353b3763ab888b57f47af4d8954978758fb4edbf5e50601d68ec5
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > [!NOTE]
4
4
  > DexieCable is NOT a local-first solution, because it lacks the capability to automatically sync updates back to the server (this might be added later). For now, think of it as a real-time local-cache solution. Also, check out this [blog post introducing DexieCable](https://dev.to/buhrmi/real-time-rails-without-turbo-modern-reactive-uis-with-inertia-and-dexiecable-4lge).
5
5
 
6
- DexieCable augments ActionCable channels with a query DSL that mirrors the Dexie.js API, letting you push database mutations from the server to the client in real time. It also gives you a [`syncs_to_dexie`](#syncs_to_dexie--automatic-model-syncing) ActiveRecord macro for automatic change syncing.
6
+ DexieCable augments ActionCable channels with a query DSL that mirrors the Dexie.js API, letting you push database mutations from the server to the client in real time. It also gives you a [`streams_to_dexie`](#streams_to_dexie--automatic-model-syncing) ActiveRecord macro for automatic change syncing.
7
7
 
8
8
  You can run any Dexie table update directly inside a channel:
9
9
 
@@ -30,11 +30,11 @@ class NotificationsController < ApplicationController
30
30
  end
31
31
  ```
32
32
 
33
- An even more convenient way is to use the `syncs_to_dexie` macro (more info [below](#syncs_to_dexie--automatic-model-syncing))
33
+ An even more convenient way is to use the `streams_to_dexie` macro (more info [below](#streams_to_dexie--automatic-model-syncing))
34
34
 
35
35
  ```ruby
36
36
  class Notification < ApplicationRecord
37
- syncs_to_dexie via: -> { UserChannel[user] }
37
+ streams_to_dexie via: UserChannel, to: :user
38
38
  end
39
39
  ```
40
40
 
@@ -48,7 +48,7 @@ Add to your `Gemfile`:
48
48
  gem "dexiecable"
49
49
  ```
50
50
 
51
- Then `bundle install`. The Railtie automatically extends `ActiveRecord::Base` with `syncs_to_dexie`.
51
+ Then `bundle install`. The Railtie automatically extends `ActiveRecord::Base` with `streams_to_dexie`.
52
52
 
53
53
  ### npm package
54
54
 
@@ -131,33 +131,25 @@ UserChannel[current_user]
131
131
 
132
132
  The full query chain is serialized as JSON and sent over ActionCable. The JS client replays every method call against the local Dexie database in order.
133
133
 
134
- ### `syncs_to_dexie` — automatic model syncing
134
+ ### `streams_to_dexie` — automatic model syncing
135
135
 
136
- Add to any ActiveRecord model. The simplest approach: pass a Proc to `via` that returns a scoped channel.
137
-
138
- ```ruby
139
- class Message < ApplicationRecord
140
- syncs_to_dexie via: -> { UserChannel[current_user] }
141
- end
142
- ```
143
-
144
- You can also pass a channel class with `to:` to have DexieCable handle the scoping:
136
+ Add to any ActiveRecord model. Just provide the channel class and the broadcast target.
145
137
 
146
138
  ```ruby
147
139
  class Message < ApplicationRecord
148
140
  # Calls send(:receiver), then broadcasts: UserChannel.broadcast_to(receiver, ...)
149
- syncs_to_dexie via: UserChannel, to: :receiver
141
+ streams_to_dexie via: UserChannel, to: :receiver
150
142
 
151
143
  # String used directly: UserChannel.broadcast_to("global_feed", ...)
152
- syncs_to_dexie via: UserChannel, to: "global_feed"
144
+ streams_to_dexie via: UserChannel, to: "global_feed"
153
145
 
154
146
  # Procs are also supported. If an array is returned, multiple broadcasts are made
155
147
  # conversation.users.each { |u| UserChannel.broadcast_to(u, ...) }
156
- syncs_to_dexie via: UserChannel, to: -> { conversation.users }
148
+ streams_to_dexie via: UserChannel, to: -> { conversation.users }
157
149
  end
158
150
  ```
159
151
 
160
- Internally, `syncs_to_dexie` sets up the following ActiveRecord callbacks:
152
+ Internally, `streams_to_dexie` sets up the following ActiveRecord callbacks:
161
153
 
162
154
  | Event | Action |
163
155
  |---|---|
@@ -169,21 +161,23 @@ Internally, `syncs_to_dexie` sets up the following ActiveRecord callbacks:
169
161
 
170
162
  | Option | Default | Description |
171
163
  |---|---|---|
172
- | `via:` | *(required)* | A DexieCable channel class, or a Proc that returns a channel or scoped channel (e.g. `-> { UserChannel[current_user] }`) |
173
- | `to:` | *(none)* | The stream target passed to `broadcast_to`. Symbol → calls `send`. String → used as-is. Proc → evaluated in record context. Returns a single recipient or collection. Only used when `via` is a channel class. |
164
+ | `via:` | *(required)* | A DexieCable channel class |
165
+ | `to:` | *(none)* | The stream target passed to `broadcast_to`. Symbol → calls `send`. String → used as-is. Proc → evaluated in record context. Returns a single recipient or collection. |
174
166
  | `table:` | model's `table_name` | Override the Dexie table name. A Proc is evaluated in the record's context. |
175
167
  | `only:` | `[:create, :update, :destroy]` | Limit which events trigger a sync |
176
168
  | `with:` | `:as_json_for_dexie` | Method name (Symbol) or Proc for serializing records |
177
169
  | `if:` | *(none)* | Symbol (method name) or Proc — only sync when it returns truthy |
178
170
  | `unless:` | *(none)* | Symbol (method name) or Proc — skip sync when it returns truthy |
179
171
 
180
- You can combine multiple `syncs_to_dexie` declarations, each with different conditions:
172
+ You can combine multiple `streams_to_dexie` declarations, each with different conditions:
181
173
 
182
174
  ```ruby
183
175
  class Message < ApplicationRecord
184
- syncs_to_dexie via: -> { UserChannel[current_user] }
185
- syncs_to_dexie via: -> { BoardChannel[board] },
176
+ streams_to_dexie via: UserChannel, to: -> { sender },
186
177
  if: :published?
178
+
179
+ streams_to_dexie via: AdminChannel,
180
+ unless: -> { draft? }
187
181
  end
188
182
  ```
189
183
 
@@ -194,14 +188,14 @@ Override `as_json_for_dexie` in your model, or use the `with` option to specify
194
188
  ```ruby
195
189
  class Message < ApplicationRecord
196
190
  # Using the default as_json_for_dexie override:
197
- syncs_to_dexie via: -> { UserChannel[current_user] }
191
+ streams_to_dexie via: UserChannel, to: :sender
198
192
 
199
193
  def as_json_for_dexie
200
194
  super.merge(room_name: room.name)
201
195
  end
202
196
 
203
197
  # Or use a custom serializer method:
204
- syncs_to_dexie via: AdminChannel,
198
+ streams_to_dexie via: AdminChannel, to: :admin,
205
199
  with: :admin_payload
206
200
 
207
201
  def admin_payload
@@ -209,7 +203,7 @@ class Message < ApplicationRecord
209
203
  end
210
204
 
211
205
  # Or a Proc:
212
- syncs_to_dexie via: PublicChannel,
206
+ streams_to_dexie via: PublicChannel,
213
207
  with: -> { { id: id, summary: body.truncate(100) } }
214
208
  end
215
209
  ```
@@ -255,7 +249,7 @@ dexie.messages.where("room_id").equals(5).add({ id: 1, text: "hello" })
255
249
 
256
250
  ### Use sequence IDs to avoid data loss
257
251
 
258
- A common pattern to avoid data loss during transient disconnections is using sequence IDs to bridge the offline gap. When a connection drops, updates continue on the server. Sending the client’s latest known sequence ID upon reconnect allows the backend to query and stream only the records missed while offline.
252
+ A common pattern to avoid data loss during transient disconnections is using sequence IDs to bridge the offline gap and detect gaps in transmitted records. When a connection drops, updates continue on the server. Sending the client’s latest known sequence ID upon reconnect allows the backend to query and stream only the records missed while offline.
259
253
 
260
254
  To enable this, DexieCable ships its own version of the ActionCable client with one key
261
255
  extension: **channel params can be functions**. When a param value is a
@@ -286,7 +280,7 @@ class RoomChannel < ApplicationChannel:Base
286
280
  end
287
281
  ```
288
282
 
289
- You might want to have look at the [Sequenced](https://github.com/derrickreimer/sequenced) gem to automatically add sequence IDs to your records.
283
+ To add Sequence IDs, you might want to have look at the [Sequenced](https://github.com/derrickreimer/sequenced). Another option is to use [AnyCable](https://docs.anycable.io/rails/getting_started) since it guarantees deliveries of ActionCable messages.
290
284
 
291
285
  ### Multi-user environments
292
286
 
@@ -9,19 +9,17 @@ module DexieCable
9
9
  # DexieCable channel.
10
10
  #
11
11
  # class Message < ApplicationRecord
12
- # syncs_to_dexie via: -> { UserChannel[current_user] }
13
- # syncs_to_dexie via: PublicChannel
14
- # syncs_to_dexie via: UserChannel, to: :user
15
- # syncs_to_dexie via: UserChannel, to: -> { conversation.users }
16
- # syncs_to_dexie via: -> { tenant_channel }
12
+ # streams_to_dexie via: UserChannel, to: :sender
13
+ # streams_to_dexie via: UserChannel, to: "global_feed"
14
+ # streams_to_dexie via: UserChannel, to: -> { conversation.users }
15
+ # streams_to_dexie via: PublicChannel
17
16
  # end
18
17
  #
19
- # @param via [Class, Proc] A DexieCable channel class, or a Proc
20
- # evaluated in record context that returns a channel
21
- # class or a scoped channel (e.g.
22
- # +-> { UserChannel[current_user] }+). When +to+
18
+ # @param via [Class] A DexieCable channel class. When +to+
23
19
  # is given, each recipient is mapped through
24
20
  # +via[to]+ to produce scoped channels.
21
+ # Without +to+, +via+ is used directly as an
22
+ # unscoped channel.
25
23
  # @param to [Proc, Symbol, String] A Proc evaluated in record
26
24
  # context, a Symbol to call via +send+, or a String
27
25
  # used directly as the stream name for +broadcast_to+.
@@ -38,7 +36,7 @@ module DexieCable
38
36
  # returns truthy (evaluated in the record's context).
39
37
  # @param unless [Symbol, Proc] Skip sync if the given method or proc
40
38
  # returns truthy (evaluated in the record's context).
41
- def syncs_to_dexie(via:, to: nil, table: nil, only: nil, with: nil, **options)
39
+ def streams_to_dexie(via:, to: nil, table: nil, only: nil, with: nil, **options)
42
40
  events = Array(only || %i[create update destroy])
43
41
  conditions = options.slice(:if, :unless)
44
42
  serializer = with || :as_json_for_dexie
@@ -82,12 +80,11 @@ module DexieCable
82
80
  private
83
81
 
84
82
  def resolve_channel(via, to = nil)
85
- channel = via.is_a?(Proc) ? instance_exec(&via) : via
86
83
  if to
87
84
  recipients = resolve_recipient(to)
88
- Array(recipients).map { |r| channel[r] }
85
+ Array(recipients).map { |r| via[r] }
89
86
  else
90
- channel
87
+ via
91
88
  end
92
89
  end
93
90
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DexieCable
4
- VERSION = "0.1.9"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dexiecable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Buhrmester
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: '7.0'
40
40
  description: DexieCable augments ActionCable channels with a query DSL that mirrors
41
41
  the Dexie.js API, letting you push database mutations from the server to the client
42
- in real time. Includes an ActiveRecord macro (syncs_to_dexie) for automatic change
42
+ in real time. Includes an ActiveRecord macro (streams_to_dexie) for automatic change
43
43
  syncing.
44
44
  email:
45
45
  - stefan@buhrmi.de
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  requirements: []
78
- rubygems_version: 4.0.8
78
+ rubygems_version: 4.0.16
79
79
  specification_version: 4
80
80
  summary: Run Dexie.js IndexedDB operations from your Rails ActionCable channels.
81
81
  test_files: []