svelte-on-rails 5.3.0 → 5.3.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: 8f91cbdd2375be3978749859e8bb36b16fbba13fa1e9ac494b9b5e731bc06f91
4
- data.tar.gz: f0164b5a93bfb62b2abeedbaebc85064253ad6e4500d9d94a0cfda570416e794
3
+ metadata.gz: 66ba05e463ee27dcf6234fd49f46f1879daecd331f52549080d1d9f2f9e0748d
4
+ data.tar.gz: 1947be68d44b723ed074098728db6a0aaba6e5c5bbbb72dc09604b5fc4dc93f3
5
5
  SHA512:
6
- metadata.gz: f490b501d07cfe64636b73e45ba2b42d30cfc2fc33168488635565fee4a1d3def9e31b5097cbba82aa7ebfad92e08b6a6be30afa53385dbb206e616d6a72352e
7
- data.tar.gz: 94e88d6876d9d434e504899f47f5d71ba2d3129a3a55a94992ce6a573d9e78ab305e306f7c3c2576c0135b3aeb03c5578fec74175eb2fc18d89151bac059d664
6
+ metadata.gz: 3c4a60a0c0f2d372535af2a7972c4df70ecb2958e0f0f2e9c718f6aeeccbab8f2797c329ec8ea789e5aa9d9e5154bc5b5cc88f70d0a5211416aa1d5d0296d8ad
7
+ data.tar.gz: afa1cef4cef2787e3da4d0a040b6261f1313b503ae149238faa74f779c46a5d78a569a4ac98c84d0e76276c514d8940f9dd6b6086a58c9c7e54490a2671d18a1
data/README.md CHANGED
@@ -5,24 +5,17 @@
5
5
 
6
6
  ---
7
7
 
8
- Combining [DHH's vision](https://rubyonrails.org/2021/12/15/Rails-7-fulfilling-a-vision)
9
- with modern front-end requirements:
8
+ Realizing [DHH's vision](https://rubyonrails.org/2021/12/15/Rails-7-fulfilling-a-vision) with modern front-end technologies.
10
9
 
11
- Svelte.
10
+ # Why Integrate Svelte?
12
11
 
13
- Vite.
14
-
15
- # Why Choose Svelte for Integration?
16
-
17
- Svelte delivers the robust frontend experience missing from DHH’s
18
- vision while aligning seamlessly with Rails’ full-stack philosophy.
12
+ Svelte offers the simplest and most elegant soulution to building reactive, high-performance front-end components.
19
13
 
20
14
  - **Seamless Integration**
21
15
  - Works flawlessly with Hotwired/Turbo
22
- - Complements Hotwired perfectly
16
+ - Enhances Hotwire’s capabilities
23
17
  - **Developer-Friendly**
24
- - Easy to learn
25
- - Intuitive and powerful
18
+ - Simple to learn, intuitive, and powerful
26
19
  - Lightning-fast performance
27
20
  - **Compared to Single Page Apps (SPAs)**
28
21
  - Full-stack development delivers maximum value:
@@ -30,20 +23,17 @@ vision while aligning seamlessly with Rails’ full-stack philosophy.
30
23
  - Single-source system delivery
31
24
  - For the most HTML Hotwired is enough
32
25
  - **Compared to Hotwired**
33
- - Stimulus is not a tool for writing frontend-apps
34
- - Svelte eliminates redundant HTML state logic
26
+ - Stimulus is not a tool for frontend-apps
27
+ - Svelte eliminates redundant HTML initial state logic
35
28
  - Consolidates component logic into a single file
36
- - Offloads rendering of certain HTML components to frontend JavaScript, reducing server load
29
+ - Offloads rendering to JavaScript by Frontend, Server side Rendering only where necessary, reducing server load
37
30
  - **Compared to React/Vue**
38
- - Svelte eliminates the virtual DOM, resulting in leaner, more compact packages and faster performance
39
- - Watch Rich Harris’ [Rethinking Reactivity](https://svelte.dev/blog/svelte-3-rethinking-reactivity) (3:50–6:40) for a compelling comparison with react
31
+ - No virtual DOM, resulting in leaner packages and faster performance
32
+ - See Rich Harris’ [Rethinking Reactivity](https://svelte.dev/blog/svelte-3-rethinking-reactivity) (3:50–6:40) for a compelling comparison
40
33
  - Easier to learn
41
- - React and Vue having a vaster Community, bigger Ecosystem
42
- - But, for integration, like here, this is not importand
43
- - Svelte is sufficiently established
44
- - Svelte is younger and growing
34
+ - While React and Vue have larger communities, Svelte’s ecosystem is robust and growing, ideal for Rails integration
45
35
 
46
- Svelte empowers Rails’ full-stack vision with modern, streamlined frontend integration.
36
+ Svelte empowers Rails’ full-stack vision with modern, efficient front-end integration.
47
37
 
48
38
  # Features
49
39
 
@@ -389,39 +379,19 @@ on the svelte-on-rails config file or pass the `expires_in` as argument to the v
389
379
 
390
380
  Pass `debug: true` to the helper and you will see on the logs how your configuration works.
391
381
 
392
- ## ActionCable / TurboStream
382
+ ## ActionCable vs. TurboStream
393
383
 
394
384
  There are two ways that the server can talk to the client over Websocket:
395
385
 
396
- - ActionCable transmits directly to the frontends javascript
397
- - TurboStreams is a wrapper around ActionCable
398
- - You always need a html part for communication
399
-
400
- **Configs**
401
-
402
- Check the regarding keys and their commends on the [config file](https://gitlab.com/sedl/svelte-on-rails/-/blob/main/templates/config_base/config/svelte_on_rails.yml?ref_type=heads).
403
- From there, you just need:
404
-
405
- ```yaml
406
- turbo_stream:
407
- target_html_id: 'svelte-on-rails-stream-actions-box'
408
- channel: 'public'
409
- ```
410
-
411
- ## ActionCable vs TurboStream
412
-
413
- - **ActionCable**
414
- - Cleaner setup no html needed
415
- - Seams to initialize securer, especially for testings (not: production)
416
- - **TurboStream**
417
- - Secured Streams by html-tag `signed-stream-name` if you want to send confidential data
418
- over streams or have different channels for each user privileges
419
- - Has [Compatibility issue with UJS](https://github.com/hotwired/turbo-rails?tab=readme-ov-file#compatibility-with-rails-ujs)
386
+ - **ActionCable** transmits directly to the frontends javascript
387
+ - **TurboStreams** is a wrapper around ActionCable
388
+ - You always need a html part for communication by secured channels
389
+ - Makes sense when you want to transfer confidential data or separate onto privileged user channels
390
+ - Has [compatibility issues with Rails-UJS](https://github.com/hotwired/turbo-rails?tab=readme-ov-file#compatibility-with-rails-ujs)
420
391
 
392
+
421
393
  ## SvelteOnRails::ActionCable
422
394
 
423
- ActionCable is the more basic library behind `TurboStream` and it is a second Option to call Javascript Actions from the server.
424
-
425
395
  **Setup**
426
396
 
427
397
  Add `app/channels/svelte_on_rails_channel.rb`
@@ -438,7 +408,14 @@ class SvelteOnRailsChannel < ApplicationCable::Channel
438
408
  end
439
409
  ```
440
410
 
441
- run
411
+ config
412
+
413
+ ```yaml
414
+ action_cable:
415
+ channel: "svelte_on_rails_channel"
416
+ ```
417
+
418
+ javascript
442
419
 
443
420
  ```shell
444
421
  npm i @rails/actioncable
@@ -511,11 +488,6 @@ on the whole `document` and fires the given event there.
511
488
 
512
489
  # SvelteOnRails::TurboStream
513
490
 
514
- Turbo Stream makes more sense when you think of sending confidential data to the components
515
- or you want to separate to channels based on user groups, for example.
516
-
517
- Few setup is needed for that:
518
-
519
491
  **Setup**
520
492
 
521
493
  Please setup the `turbo-rails` gem and follow the chapter [Come alive with Turbo Streams](https://github.com/hotwired/turbo-rails?tab=readme-ov-file#come-alive-with-turbo-streams), which mainly is:
@@ -542,6 +514,17 @@ you can test it by:
542
514
 
543
515
  When this works you are good to go.
544
516
 
517
+ **Configs**
518
+
519
+ Check the regarding keys and their commends on the [config file](https://gitlab.com/sedl/svelte-on-rails/-/blob/main/templates/config_base/config/svelte_on_rails.yml?ref_type=heads).
520
+ From there, you just need:
521
+
522
+ ```yaml
523
+ turbo_stream:
524
+ target_html_id: 'svelte-on-rails-stream-actions-box'
525
+ channel: 'public'
526
+ ```
527
+
545
528
  **Minimal Usage Example**
546
529
 
547
530
  And call this by:
@@ -40,7 +40,7 @@ module SvelteOnRails
40
40
 
41
41
  args = {
42
42
  eventDetail: event_detail,
43
- component: '/false/',
43
+ component: ':false:',
44
44
  event: event,
45
45
  selector: selector
46
46
  }
@@ -10,8 +10,30 @@ module SvelteOnRails
10
10
  # Returns a hash of attributes, methods, and associations formatted for Svelte components
11
11
  def svelte_attributes(*attributes)
12
12
  @svelte_attributes ||= begin
13
+
14
+ # separate offset and limit
15
+
16
+ h = attributes.grep(Hash)
17
+ attr = if h.present?
18
+ opts = h.first.symbolize_keys
19
+ offset = opts[:offset]
20
+ limit = opts[:limit]
21
+ if offset || limit
22
+ unless self.respond_to?(:each)
23
+ raise 'offset and limit are only supported for record sets that respond to :each'
24
+ end
25
+ _opts = opts.reject { |key, _| [:offset, :limit].include?(key) }
26
+ attributes.select { |item| !item.is_a?(Hash) }.push(_opts)
27
+ else
28
+ attributes
29
+ end
30
+ else
31
+ attributes
32
+ end
33
+
13
34
  utils = SvelteOnRails::Lib::Utils
14
- utils.svelte_attributes(self, attributes)
35
+ utils.svelte_attributes(self, attr, offset: offset, limit: limit)
36
+
15
37
  end
16
38
  end
17
39
 
@@ -163,21 +163,9 @@ module SvelteOnRails
163
163
  end
164
164
  end
165
165
 
166
- def self.svelte_attributes(record, attributes, labels = {}, call_stack: 0, offset: nil, limit: nil)
166
+ def self.svelte_attributes(record, attributes, labels: {}, call_stack: 0, offset: nil, limit: nil)
167
167
 
168
- if record.respond_to?(:each)
169
- unless record.is_a?(ActiveRecord::Relation) || record.is_a?(ActiveRecord::Associations::CollectionProxy)
170
- raise 'record set must be a Article::ActiveRecord_Associations_CollectionProxy'
171
- end
172
-
173
- recs = (limit ? record.limit(limit) : record)
174
- recs2 = (offset ? recs.offset(limit) : recs)
175
-
176
- values = recs2.map do |rec|
177
- svelte_attributes(rec, attributes, labels, call_stack: call_stack + 1)
178
- end
179
-
180
- elsif record.is_a?(Class)
168
+ if record.is_a?(Class)
181
169
 
182
170
  # this is the case if a belongs_to association is empty; In that case we pass the class itself and extract only the labels
183
171
  raise 'limit and offset are supported only for iterable objects' if limit || offset
@@ -189,6 +177,19 @@ module SvelteOnRails
189
177
  end
190
178
  values = {}
191
179
 
180
+ elsif record.respond_to?(:each)
181
+
182
+ unless record.is_a?(ActiveRecord::Relation) || record.is_a?(ActiveRecord::Associations::CollectionProxy)
183
+ raise 'record set must be a Article::ActiveRecord_Associations_CollectionProxy'
184
+ end
185
+
186
+ recs = (offset ? record.offset(offset) : record)
187
+ recs2 = (limit ? recs.limit(limit) : recs)
188
+
189
+ values = recs2.map do |rec|
190
+ svelte_attributes(rec, attributes, labels: labels, call_stack: call_stack + 1)
191
+ end
192
+
192
193
  else
193
194
 
194
195
  # we have a single record
@@ -222,20 +223,24 @@ module SvelteOnRails
222
223
 
223
224
  # values
224
225
 
225
- content = record.send(_key)
226
226
  reflect = record.class.reflect_on_association(_key)
227
227
  if reflect
228
+ recs = record.send(_key)
229
+ content = (recs.present? ? recs : reflect.active_record) # if no record, we extract only the labels
228
230
  if content.respond_to?(:each)
229
231
  values[_key] = svelte_attributes(
230
- content, value, labels,
232
+ content,
233
+ value,
234
+ labels: labels,
231
235
  call_stack: call_stack + 1,
232
236
  offset: offs,
233
237
  limit: lim
234
238
  )
235
239
  else
236
240
  values[_key] = svelte_attributes(
237
- content || reflect.active_record, # if no record, we extract only the labels
238
- value, labels,
241
+ content,
242
+ value,
243
+ labels: labels,
239
244
  call_stack: call_stack + 1,
240
245
  offset: offs,
241
246
  limit: lim
@@ -275,12 +280,12 @@ module SvelteOnRails
275
280
  hash_args = attributes.grep(Hash).first.with_indifferent_access # multiple arrays is not possible
276
281
 
277
282
  offset = if hash_args["#{key}_offset"] && !record.respond_to?("#{key}_offset")
278
- hash_args["#{key}_offset"]
279
- end
283
+ hash_args["#{key}_offset"]
284
+ end
280
285
 
281
286
  limit = if hash_args["#{key}_limit"] && !record.respond_to?("#{key}_limit")
282
- hash_args["#{key}_limit"]
283
- end
287
+ hash_args["#{key}_limit"]
288
+ end
284
289
 
285
290
  [offset, limit]
286
291
  end
@@ -79,7 +79,13 @@ module SvelteOnRails
79
79
 
80
80
  def render_ssr
81
81
  renderer = SvelteOnRails::Renderer.new(filename)
82
- renderer.render(@svelte_props)
82
+ res = renderer.render(@svelte_props)
83
+ if res['html'].is_a?(Array)
84
+ res['html'] = res['html'].join
85
+ res
86
+ else
87
+ res
88
+ end
83
89
  end
84
90
 
85
91
  def custom_cache_key
@@ -14,13 +14,13 @@ import {loadComponentModule, readPropsFromStdin} from './utils.js';
14
14
 
15
15
  try {
16
16
  MyComponent(payload, props); // Writes directly to payload.out
17
- console.log(`[svelte-on-rails:debug] written to payload`)
17
+ console.log(`[svelte-on-rails:debug] written to payload (typeof payload.out => «${typeof payload.out}»)`)
18
18
  } catch (error) {
19
19
  console.error('[svelte-on-rails:debug] Error rendering component:', error);
20
20
  process.exit(1);
21
21
  }
22
22
 
23
- const res = {status: 'SUCCESS', html: payload.out.join('')};
23
+ const res = {status: 'SUCCESS', html: payload.out};
24
24
  console.log('[svelte-on-rails:successful-json-response]' + JSON.stringify(res));
25
25
  })();
26
26
 
@@ -40,7 +40,7 @@ module SvelteOnRails
40
40
 
41
41
  args = {
42
42
  eventDetail: event_detail,
43
- component: '/false/',
43
+ component: ':false:',
44
44
  event: event,
45
45
  selector: selector
46
46
  }
@@ -1,5 +1,6 @@
1
1
  import { createConsumer } from "@rails/actioncable"
2
- import {dispatchSvelteStreamEvent, actionCableDebugLog} from '@csedl/svelte-on-rails'
2
+ import { SvelteOnRails, dispatchSvelteStreamEvent, actionCableDebugLog } from '@csedl/svelte-on-rails'
3
+ SvelteOnRails.debug = true
3
4
 
4
5
  const consumer = createConsumer()
5
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: svelte-on-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.0
4
+ version: 5.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Sedlmair