dexiecable 0.1.0 → 0.1.2

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: 86f0f439d4d0a6320b38ce77c0e188fdd590b592107c8a6c4b41f6d63d72c900
4
- data.tar.gz: da0d7f54b972206adf4e07bbcec2660a597f4ac89c28865fc2a8974bc21ac38f
3
+ metadata.gz: dc22d844e30147740e885b5959d13a6f42c47ff9551490f4b8e61701b1481676
4
+ data.tar.gz: 5d82c9e2f8453aa038db8b7eb5997134e56431da93a62ecb30190e5eebef63a2
5
5
  SHA512:
6
- metadata.gz: 22d044c313789238aaa192415a96d8795111078727745ed9ed1b26ce28d14016be02415ef9903eebcfc75fa6d1a4b0856c8eb4cebbdd7693c3b67984ba6a6dd1
7
- data.tar.gz: 7fc66fe6550e35e92fc426ae01131bda13b9a83394c763d24b3c19a7a84670c974843ee47385b9c0298cdfa0e3e8c5507115d4565370fdcbc3eb589632898143
6
+ metadata.gz: 18eb395292b406e4f0cd690eafcf9dc68ac5b39cac89c459e0685c95e7cfe42bd551348c3146df1dcd596405b6198c15ecba41ba9e48abceee8068cd65f020ac
7
+ data.tar.gz: b2135050a6a827ac7e0c596ed64ad8d6d568ad6f18d278a6b8c819c464564a110396fc76c597985d1d4cc4e1be2ddd0b4aab1aa9b58fb4a5b1663509a9762a7d
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # DexieCable
2
2
 
3
- Run Dexie.js IndexedDB operations from your Rails ActionCable channels.
3
+ Run [Dexie.js](https://dexie.org) IndexedDB operations from your Rails ActionCable channels.
4
4
 
5
5
  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` ActiveRecord macro for automatic change syncing.
6
6
 
@@ -100,18 +100,20 @@ Any Dexie.js write operation triggers an immediate broadcast:
100
100
  # Single insert
101
101
  UserChannel[current_user].table("messages").add(id: 1, text: "hello")
102
102
 
103
- # Filtered bulk insert
104
- UserChannel[current_user]
105
- .table("messages")
106
- .where(:room_id).equals(room.id)
107
- .bulkAdd(messages)
103
+ # Bulk insert
104
+ UserChannel[current_user].table("messages").bulkAdd(messages)
108
105
 
109
- # Update
106
+ # Update (using modify)
110
107
  UserChannel[current_user]
111
108
  .table("messages")
112
109
  .where(:id).equals(msg.id)
113
110
  .modify(read: true)
114
111
 
112
+ # Update (using update)
113
+ UserChannel[current_user]
114
+ .table("messages")
115
+ .update(msg.id, text: "updated text")
116
+
115
117
  # Delete
116
118
  UserChannel[current_user]
117
119
  .table("messages")
@@ -129,7 +131,7 @@ Add to any ActiveRecord model:
129
131
  class Message < ApplicationRecord
130
132
  syncs_to_dexie via: -> { UserChannel[sender] }
131
133
  syncs_to_dexie via: -> { UserChannel[receiver] }
132
- syncs_to_dexie via: PublicChannel # broadcast to all connected clients
134
+ syncs_to_dexie via: RoomChannel['public']
133
135
  end
134
136
  ```
135
137
 
@@ -143,9 +145,23 @@ end
143
145
 
144
146
  | Option | Default | Description |
145
147
  |---|---|---|
146
- | `via:` | *(required)* | Proc (evaluated in record context), channel class, or channel instance |
147
- | `table:` | model's `table_name` | Override the Dexie table name |
148
+ | `via:` | *(required)* | Proc (evaluated in record context), or channel instance |
149
+ | `table:` | model's `table_name` | Override the Dexie table name. A Proc is evaluated in the record's context. |
148
150
  | `only:` | `[:create, :update, :destroy]` | Limit which events trigger a sync |
151
+ | `if:` | *(none)* | Symbol (method name) or Proc — only sync when it returns truthy |
152
+ | `unless:` | *(none)* | Symbol (method name) or Proc — skip sync when it returns truthy |
153
+
154
+ You can combine multiple `syncs_to_dexie` declarations, each with different conditions:
155
+
156
+ ```ruby
157
+ class Message < ApplicationRecord
158
+ syncs_to_dexie via: -> { UserChannel[sender] },
159
+ if: :published?
160
+
161
+ syncs_to_dexie via: -> { AdminChannel },
162
+ unless: -> { draft? }
163
+ end
164
+ ```
149
165
 
150
166
  #### Customizing the synced payload
151
167
 
@@ -17,42 +17,47 @@ module DexieCable
17
17
  # @param via [Proc, DexieCable] Proc evaluated in record context,
18
18
  # must return a channel (responds to +table+). A channel
19
19
  # class/instance can also be passed directly. Skipped if nil.
20
- # @param table [String, Symbol] Override the Dexie table name
21
- # (defaults to the model's table_name).
20
+ # @param table [String, Symbol, Proc] Override the Dexie table name
21
+ # (defaults to the model's table_name). A Proc is
22
+ # evaluated in the record's context.
22
23
  # @param only [Array<Symbol>] Limit which lifecycle events sync.
23
24
  # Default: [:create, :update, :destroy].
24
- def syncs_to_dexie(via:, table: nil, only: nil)
25
- table_name = (table || self.table_name).to_s
25
+ # @param if [Symbol, Proc] Only sync if the given method or proc
26
+ # returns truthy (evaluated in the record's context).
27
+ # @param unless [Symbol, Proc] Skip sync if the given method or proc
28
+ # returns truthy (evaluated in the record's context).
29
+ def syncs_to_dexie(via:, table: nil, only: nil, **options)
26
30
  events = Array(only || %i[create update destroy])
31
+ conditions = options.slice(:if, :unless)
27
32
 
28
33
  @dexie_sync_configs ||= []
29
- @dexie_sync_configs << { via: via, table: table_name, only: events }
34
+ @dexie_sync_configs << { via: via, table: table, only: events, **conditions }
30
35
 
31
36
  if events.include?(:destroy)
32
37
  before_destroy :dexie_sync_before_destroy
33
38
 
34
- after_commit on: :destroy do
39
+ after_commit on: :destroy, **conditions do
35
40
  channel = resolve_channel(via)
36
41
  next unless channel
37
- channel.table(table_name).delete(dexie_destroy_id)
42
+ channel.table(resolve_table(table)).delete(dexie_destroy_id)
38
43
  end
39
44
  end
40
45
 
41
46
  if events.include?(:create)
42
- after_commit on: :create do
47
+ after_commit on: :create, **conditions do
43
48
  channel = resolve_channel(via)
44
49
  next unless channel
45
- channel.table(table_name).add(as_json_for_dexie)
50
+ channel.table(resolve_table(table)).add(as_json_for_dexie)
46
51
  end
47
52
  end
48
53
 
49
54
  if events.include?(:update)
50
- after_commit on: :update do
55
+ after_commit on: :update, **conditions do
51
56
  channel = resolve_channel(via)
52
57
  next unless channel
53
58
 
54
59
  changes = as_json_for_dexie.slice(*saved_changes.keys)
55
- channel.table(table_name).update(id, changes)
60
+ channel.table(resolve_table(table)).update(id, changes)
56
61
  end
57
62
  end
58
63
  end
@@ -67,6 +72,14 @@ module DexieCable
67
72
  end
68
73
  end
69
74
 
75
+ def resolve_table(table)
76
+ case table
77
+ when Proc then instance_exec(&table).to_s
78
+ when nil then self.class.table_name
79
+ else table.to_s
80
+ end
81
+ end
82
+
70
83
  # Override in your model to customise the payload synced to Dexie.
71
84
  def as_json_for_dexie
72
85
  as_json
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DexieCable
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.2"
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.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Buhrmester