sessionvision 0.1.0 → 0.1.1

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: f94cb9100274b790c0eeff2de556da99bd0a0f45980e2ddf7f350c7ab119026f
4
- data.tar.gz: ea6cce1a64cf136ef40cf37d397a908295ee91fc6c63368e47d211f280c5a813
3
+ metadata.gz: 66e755d6fdb9d9e7135e64473ea7077c4fed08ab9fd0185ac50155000e91ce35
4
+ data.tar.gz: 795e7caa56b074c01d118b6e6bd4d0bd0919e30499f018631e8ddbcf3df4b255
5
5
  SHA512:
6
- metadata.gz: 0bbaa3ccd591fcccf34e737a6b1469090d44742d813a8261e3b002e31396dfa289f1552683bfbce69ab25e052db749a13c451bed788f7a60206293fab8b54eff
7
- data.tar.gz: 1ff05e7cd2de691da8fb71b471a595c4f592be2b9bb1e556913691320cec6a4bccc7c2dbd45c42dccf50241e06f921bf44a1dd37da0adf8e1ab08ab1d86efc5d
6
+ metadata.gz: c85e057308dfa09dca4a33d99e4ca0694c9ba42de5335882c0404c96fe23f2a6f1591b3e65ba40c8bda0121fc8cdc128988d334e088c907e7e3fd8cf19af538e
7
+ data.tar.gz: a6db7d00432f903968ae4a9475559110ea992b71e7542aba3e6960c1e84f6139355dce9d625f00f1afeecdaeac99e919a068b1eaf1770ca251f7b6268d326641
@@ -5,10 +5,15 @@ require "logger"
5
5
 
6
6
  module SessionVision
7
7
  class Client
8
+ MAX_GROUPS = 8
9
+ MAX_GROUP_KEY_LENGTH = 200
10
+ CONTROL_CHARS = /[\x00-\x1f\x7f]/
11
+
8
12
  def initialize(config)
9
13
  @config = config
10
14
  @lock = Mutex.new
11
15
  @registered = {}
16
+ @groups = []
12
17
  @shutdown_called = false
13
18
 
14
19
  @logger = config.debug ? Logger.new($stdout, progname: "sessionvision") : nil
@@ -35,11 +40,13 @@ module SessionVision
35
40
  @logger&.debug("Client initialized (host=#{config.ingest_host})")
36
41
  end
37
42
 
38
- def capture(event_name, user_id: nil, anonymous_id: nil, session_id: nil, properties: {})
43
+ def capture(event_name, user_id: nil, anonymous_id: nil, session_id: nil, properties: {}, groups: nil)
39
44
  raise ArgumentError, "event_name must be a non-empty string" unless event_name.is_a?(String) && !event_name.empty?
40
45
  raise ArgumentError, "Either user_id or anonymous_id is required" if user_id.nil? && anonymous_id.nil?
41
46
 
42
- merged_props = @lock.synchronize { @registered.merge(properties || {}) }
47
+ merged_props, merged_groups = @lock.synchronize do
48
+ [@registered.merge(properties || {}), merge_groups(groups)]
49
+ end
43
50
 
44
51
  event = {
45
52
  "event" => event_name,
@@ -49,15 +56,23 @@ module SessionVision
49
56
  }
50
57
  event["userId"] = user_id if user_id
51
58
  event["anonymousId"] = anonymous_id if anonymous_id
59
+ event["groups"] = merged_groups unless merged_groups.empty?
52
60
 
53
61
  @logger&.debug("Event captured: #{event_name}")
54
62
  @buffer.push(event)
55
63
  end
56
64
 
57
- def identify(user_id, **traits)
65
+ def identify(user_id, groups: nil, **traits)
58
66
  raise ArgumentError, "user_id must be a non-empty string" unless user_id.is_a?(String) && !user_id.empty?
59
67
 
60
- capture("$identify", user_id: user_id, properties: traits.transform_keys(&:to_s))
68
+ set_groups(groups) unless groups.nil?
69
+ capture("$identify", user_id: user_id, properties: traits.transform_keys(&:to_s), groups: groups)
70
+ end
71
+
72
+ def set_groups(groups)
73
+ @lock.synchronize do
74
+ @groups = normalize_groups(groups)
75
+ end
61
76
  end
62
77
 
63
78
  def register(**properties)
@@ -96,6 +111,31 @@ module SessionVision
96
111
 
97
112
  private
98
113
 
114
+ def normalize_groups(input)
115
+ return [] unless input.is_a?(Array)
116
+
117
+ seen = {}
118
+ normalized = []
119
+
120
+ input.each do |raw_group|
121
+ break if normalized.length >= MAX_GROUPS
122
+ next unless raw_group.is_a?(String)
123
+
124
+ trimmed_group = raw_group.strip
125
+ next if trimmed_group.empty? || trimmed_group.length > MAX_GROUP_KEY_LENGTH
126
+ next if CONTROL_CHARS.match?(trimmed_group) || seen.key?(trimmed_group)
127
+
128
+ seen[trimmed_group] = true
129
+ normalized << trimmed_group
130
+ end
131
+
132
+ normalized
133
+ end
134
+
135
+ def merge_groups(inline_groups)
136
+ normalize_groups([*@groups, *(inline_groups || [])])
137
+ end
138
+
99
139
  def send_batch(events)
100
140
  @transport.send_batch(@config.project_token, events)
101
141
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SessionVision
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/sessionvision.rb CHANGED
@@ -29,15 +29,19 @@ module SessionVision
29
29
  end
30
30
  end
31
31
 
32
- def capture(event_name, user_id: nil, anonymous_id: nil, session_id: nil, properties: {})
32
+ def capture(event_name, user_id: nil, anonymous_id: nil, session_id: nil, properties: {}, groups: nil)
33
33
  client.capture(event_name, user_id: user_id, anonymous_id: anonymous_id,
34
- session_id: session_id, properties: properties)
34
+ session_id: session_id, properties: properties, groups: groups)
35
35
  end
36
36
 
37
37
  def identify(user_id, **traits)
38
38
  client.identify(user_id, **traits)
39
39
  end
40
40
 
41
+ def set_groups(groups)
42
+ client.set_groups(groups)
43
+ end
44
+
41
45
  def register(**properties)
42
46
  client.register(**properties)
43
47
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sessionvision
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - sessionvision
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-13 00:00:00.000000000 Z
11
+ date: 2026-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec