cubism 0.1.0.pre1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fe95381d8e51d520357a7fa08fe84d8107739b039b1f2f11846decb30b63afae
4
+ data.tar.gz: 2a4cfb19b44eb395be36c9fafd340c967d51b91690b4ebfbf11321f23a6162e8
5
+ SHA512:
6
+ metadata.gz: 335f728fbe45554a741baee7cd4e717e5b4807cdc1ee7506fac3f9273e6f0f69f416192c7b7fe69ba6202a4de573be342b19b9d60a132372c58cdb33a8af75a6
7
+ data.tar.gz: b3e49b66ffa6f6348365436be31714953ef56f95187a5db49cc5afdc71ab4b8f6d28d08423a02fa9ee3e351d539d4f7b5a1420c170aafba20b507d403f0232b8
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2021 Julian Rubisch
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # Cubism
2
+ [![Twitter follow](https://img.shields.io/twitter/follow/julian_rubisch?style=social)](https://twitter.com/julian_rubisch)
3
+
4
+ Lightweight Resource-Based Presence Solution with CableReady
5
+
6
+ ## Table of Contents
7
+
8
+ - [Table of Contents](#table-of-contents)
9
+ - [Usage](#usage)
10
+ - [Installation](#installation)
11
+ - [Manual Installation](#manual-installation)
12
+ - [Contributing](#contributing)
13
+ - [License](#license)
14
+ - [Contributors](#contributors)
15
+
16
+ ## Usage
17
+
18
+ ### Prepare your User Model
19
+ In your app's `User` model, include `Cubism::User` and set up a safelist of exposed attributes:
20
+
21
+ ```rb
22
+ class User < ApplicationRecord
23
+ include Cubism::User
24
+ self.cubicle_attributes = %i[email id]
25
+
26
+ # ...
27
+ end
28
+ ```
29
+
30
+ ### Track Present Users in your Models
31
+ In the models you'd like to track presence for, include the `Cubism::Presence` concern:
32
+
33
+ ```rb
34
+ class Project < ApplicationRecord
35
+ include Cubism::Presence
36
+ end
37
+ ```
38
+
39
+ ### Set Up the Cubicle Template
40
+
41
+ Using the `cubicle_for` helper, you can set up a presence indicator. It will
42
+
43
+ 1. subscribe to the respective resource, and
44
+ 2. accept a "template" using the attributes safelisted above. Elements marked with `data-cubicle-attribute=` will have their `innerHTML` replaced by Cubism.
45
+
46
+ ```erb
47
+ <%= cubicle_for @project do %>
48
+ <span class="avatar">
49
+ <span data-cubicle-attribute="email"></span>
50
+ </span>
51
+ <% end %>
52
+ ```
53
+
54
+ Note that this template will simply be repeated for every user that's in the `@project`s `present_users` set.
55
+
56
+ ## Installation
57
+ Add this line to your application's Gemfile:
58
+
59
+ ```ruby
60
+ gem 'cubism'
61
+ ```
62
+
63
+ And then execute:
64
+ ```bash
65
+ $ bundle
66
+ ```
67
+
68
+ After `bundle`, install the Javascript library:
69
+
70
+ ```bash
71
+ $ bin/yarn add @minthesize/cubism
72
+ ```
73
+
74
+ ### Kredis
75
+
76
+ This gem uses [kredis](https://github.com/rails/kredis) under the hood, so be sure to follow their [installation instructions](https://github.com/rails/kredis#installation). In other words, provide a Redis instance and configure it in `config/redis/shared.yml`.
77
+
78
+ ### Javascript
79
+
80
+ In your app's Javascript entrypoint (e.g. `app/javascript/packs/application.js`) import and initialize `CableReady` (cubism will make use of the injected ActionCable consumer):
81
+
82
+ ```js
83
+ import CableReady from "cable_ready";
84
+ import "@minthesize/cubism";
85
+
86
+ CableReady.initialize({ consumer });
87
+ ```
88
+
89
+
90
+ ## Contributing
91
+
92
+ ### Get local environment setup
93
+
94
+ Below are a set of instructions that may help you get a local development environment working
95
+
96
+ ```sh
97
+ # Get the gem/npm package source locally
98
+ git clone cubism
99
+ cd cubism/javascript
100
+ yarn install # install all of the npm package's dependencies
101
+ yarn link # set the local machine's cubism npm package's lookup to this local path
102
+
103
+ # Setup a sample project and edit Gemfile to point to local gem
104
+ # (e.g. `gem "cubism", path: "../cubism"`)
105
+ # yarn link @stimulus_reflex/cubism
106
+
107
+
108
+ # Do your work, Submit PR, Profit!
109
+
110
+
111
+ # To stop using your local version of cubism
112
+ # change your Gemfile back to the published (e.g. `gem "cubism"`)
113
+ cd path/to/cubism/javascript
114
+ # Stop using the local npm package
115
+ yarn unlink
116
+
117
+ # Instruct your project to reinstall the published version of the npm package
118
+ cd path/to/project
119
+ yarn install --force
120
+ ```
121
+
122
+ ### Release
123
+
124
+ 1. Update the version numbers in `javascript/package.json` and `lib/cubism/version.rb`
125
+ 2. `git commit -m "Bump version to x.x.x"`
126
+ 3. Run `bundle exec rake build`
127
+ 4. Run `bundle exec rake release`
128
+ 5. `cd javascript && npm publish --access public`
129
+
130
+ ## License
131
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
132
+
133
+ ## Contributors
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
9
+
10
+ require "rake/testtask"
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << "test"
14
+ t.pattern = "test/**/*_test.rb"
15
+ t.verbose = false
16
+ end
17
+
18
+ task default: :test
@@ -0,0 +1,18 @@
1
+ class Cubism::Presence < ActionCable::Channel::Base
2
+ def subscribed
3
+ resource = GlobalID::Locator.locate_signed params[:signed_resource]
4
+ if resource.present?
5
+ stream_for resource
6
+ resource.present_users.add(current_user.id)
7
+ else
8
+ reject
9
+ end
10
+ end
11
+
12
+ def unsubscribed
13
+ resource = GlobalID::Locator.locate_signed params[:signed_resource]
14
+ return unless resource.present?
15
+
16
+ resource.present_users.remove(current_user.id)
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ class Cubism::PresenceChannel < ActionCable::Channel::Base
2
+ include CableReady::StreamIdentifier
3
+
4
+ def subscribed
5
+ if resource.present?
6
+ stream_for resource
7
+ resource.present_users.add(current_user.id)
8
+ else
9
+ reject
10
+ end
11
+ end
12
+
13
+ def unsubscribed
14
+ return unless resource.present?
15
+
16
+ resource.present_users.remove(current_user.id)
17
+ end
18
+
19
+ private
20
+
21
+ def resource
22
+ locator = verified_stream_identifier(params[:identifier])
23
+ GlobalID::Locator.locate(locator)
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ class Cubism::PresenceChannel < ActionCable::Channel::Base
2
+ include CableReady::StreamIdentifier
3
+
4
+ def subscribed
5
+ if resource.present?
6
+ stream_for resource
7
+ resource.present_users.add(current_user.id)
8
+ else
9
+ reject
10
+ end
11
+ end
12
+
13
+ def unsubscribed
14
+ return unless resource.present?
15
+
16
+ resource.present_users.remove(current_user.id)
17
+ end
18
+
19
+ private
20
+
21
+ def resource
22
+ locator = verified_stream_identifier(params[:identifier])
23
+ GlobalID::Locator.locate(locator)
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module CubismHelper
2
+ include CableReady::StreamIdentifier
3
+
4
+ def cubicle_for(resource, html_options: {}, &block)
5
+ template = capture(&block)
6
+
7
+ tag.cubicle_element({identifier: signed_stream_identifier(resource.to_global_id.to_s)}) do
8
+ content_tag(:template, template, {slot: "template"})
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ module CubismHelper
2
+ include CableReady::Compoundable
3
+ include CableReady::StreamIdentifier
4
+
5
+ def cubicle_for(*keys, html_options: {})
6
+ tag.cubicle_element({identifier: signed_stream_identifier(compound(keys))})
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ class Cubism::StreamPresenceJob < ApplicationJob
2
+ include CableReady::Broadcaster
3
+ include CableReady::StreamIdentifier
4
+ queue_as :default
5
+
6
+ def perform(resource:)
7
+ cable_ready[Cubism::PresenceChannel].dispatch_event(
8
+ name: "cubism:update",
9
+ selector: "cubicle-element[identifier='#{signed_stream_identifier(resource.to_global_id.to_s)}']",
10
+ detail: {
11
+ users: Cubism.user_class.find(resource.present_users.members).map { |user| user.slice(user.cubicle_attributes) }.as_json
12
+ }
13
+ ).broadcast_to(resource)
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ class Cubism::StreamPresenceJob < ApplicationJob
2
+ include CableReady::Broadcaster
3
+ queue_as :default
4
+
5
+ def perform(resource:)
6
+ cable_ready[Cubism::PresenceChannel].outer_html(
7
+ selector: dom_id(resource, "cubicle").to_s,
8
+ html: ApplicationController.render(partial: "shared/presence_indicator", locals: {users: User.where(id: resource.present_users.members)})
9
+ ).broadcast
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Cubism::Base
2
+ extend ActiveSupport::Concern
3
+ end
@@ -0,0 +1,11 @@
1
+ module Cubism::Presence
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ kredis_set :present_users, after_change: :stream_presence_later
6
+ end
7
+
8
+ def stream_presence_later
9
+ Cubism::StreamPresenceJob.perform_later(resource: self)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Cubism::Presence
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ kredis_set :present_users, after_change: :stream_presence_later
6
+ end
7
+
8
+ def stream_presence_later
9
+ Cubism::StreamPresenceJob.perform_later(resource: self)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Cubism::User
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ Cubism.user_class = self
6
+
7
+ class_eval do
8
+ cattr_accessor :cubicle_attributes
9
+ end
10
+ end
11
+ end
File without changes
@@ -0,0 +1,13 @@
1
+ class Cubism::Base
2
+ include ActiveModel::Model
3
+ include Cubism::Presence
4
+ include GlobalID::Identifiable
5
+
6
+ def self.find(id)
7
+ new if id == "cubism-#{self.class.name.underscore}"
8
+ end
9
+
10
+ def id
11
+ "cubism-#{self.class.name.underscore}"
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ class Cubism::Base
2
+ include Cubism::Presence
3
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,4 @@
1
+ module Cubism
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Cubism
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
5
+
@@ -0,0 +1,4 @@
1
+ module Cubism
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Cubism
2
+ VERSION = "0.1.0.pre1"
3
+ end
@@ -0,0 +1,3 @@
1
+ module Cubism
2
+ VERSION = "0.1.0"
3
+ end
data/lib/cubism.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "cubism/version"
2
+ require "cubism/engine"
3
+
4
+ module Cubism
5
+ mattr_accessor :user_class, instance_writer: false, instance_reader: false
6
+ end
data/lib/cubism.rb~ ADDED
@@ -0,0 +1,6 @@
1
+ require "cubism/version"
2
+ require "cubism/engine"
3
+
4
+ module Cubism
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :cubism do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cubism
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre1
5
+ platform: ruby
6
+ authors:
7
+ - Julian Rubisch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-10-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 6.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: kredis
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cable_ready
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 5.0.0.pre6
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 5.0.0.pre6
55
+ - !ruby/object:Gem::Dependency
56
+ name: standard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Lightweight Resource-Based Presence Solution with CableReady
70
+ email:
71
+ - julian@julianrubisch.at
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - MIT-LICENSE
77
+ - README.md
78
+ - Rakefile
79
+ - app/channels/cubism/presence.rb~
80
+ - app/channels/cubism/presence_channel.rb
81
+ - app/channels/cubism/presence_channel.rb~
82
+ - app/helpers/cubism_helper.rb
83
+ - app/helpers/cubism_helper.rb~
84
+ - app/jobs/cubism/stream_presence_job.rb
85
+ - app/jobs/cubism/stream_presence_job.rb~
86
+ - app/models/concerns/cubism/base.rb~
87
+ - app/models/concerns/cubism/presence.rb
88
+ - app/models/concerns/cubism/presence.rb~
89
+ - app/models/concerns/cubism/user.rb
90
+ - app/models/concerns/cubism/user.rb~
91
+ - app/models/cubism/base.rb
92
+ - app/models/cubism/base.rb~
93
+ - config/routes.rb
94
+ - lib/cubism.rb
95
+ - lib/cubism.rb~
96
+ - lib/cubism/engine.rb
97
+ - lib/cubism/engine.rb~
98
+ - lib/cubism/railtie.rb~
99
+ - lib/cubism/version.rb
100
+ - lib/cubism/version.rb~
101
+ - lib/tasks/cubism_tasks.rake
102
+ homepage: https://github.com/julianrubisch/cubism
103
+ licenses:
104
+ - MIT
105
+ metadata:
106
+ homepage_uri: https://github.com/julianrubisch/cubism
107
+ source_code_uri: https://github.com/julianrubisch/cubism.git
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">"
120
+ - !ruby/object:Gem::Version
121
+ version: 1.3.1
122
+ requirements: []
123
+ rubygems_version: 3.2.3
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Lightweight Resource-Based Presence Solution with CableReady
127
+ test_files: []