posthog-ruby 3.9.0 → 3.9.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: 3f033107e265e546dca78bfbf8f6adb3552e5803ac7dec0bf822afb814e7658d
4
- data.tar.gz: efe43054d73bfce034973fc12a01301f3b935cfacb1e7e86358332a9879f8911
3
+ metadata.gz: 44b91bbae760e03c60cedc5e14bebc275a4e0fd112ba20bed4c2539016cc8241
4
+ data.tar.gz: 15cfdaa8da6474bd7f6854339aa4123a02991eac0eac8bd3b4d78da3f4d131e9
5
5
  SHA512:
6
- metadata.gz: e1e3e4e0e5712ab73c8c0c11ce5a5869df0dc95f293b151f81d7fc715844e36867d3aeed393427494789bf8b35f2d96f42c703085d6be405fe1168feaa7daa82
7
- data.tar.gz: 1347919dcaeda0b7ad237964ae00acc34d4b6e4b9273d3335ce6e4666f09471d8d8fefb53c13d51e345cf3b7c8e467b813b14cbbdad74062dbabbc12fbeadc26
6
+ metadata.gz: 3dc592f13f48e806ae7ac7f5985ce4466f7dff80f6965e8a5e0f5df774f4f7529e83023c0cde3a7ad2686d18a4aebab38e8538467576c8b17145c373648382e7
7
+ data.tar.gz: 3fa007054bb09b32ae6df99570683dc568a35365f44f46375f50a9b0a8338640d281dcb37dc6bc6041013093df0f64cb44a42b44c30e8a6e5ee49b0a8291e880
@@ -3,10 +3,13 @@
3
3
  require 'posthog/defaults'
4
4
 
5
5
  module PostHog
6
+ # Retry backoff policy used by the SDK transport.
7
+ #
8
+ # @api private
6
9
  class BackoffPolicy
7
10
  include PostHog::Defaults::BackoffPolicy
8
11
 
9
- # @param [Hash] opts
12
+ # @param opts [Hash]
10
13
  # @option opts [Numeric] :min_timeout_ms The minimum backoff timeout
11
14
  # @option opts [Numeric] :max_timeout_ms The maximum backoff timeout
12
15
  # @option opts [Numeric] :multiplier The value to multiply the current
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'time'
4
+ require 'json'
4
5
  require 'securerandom'
5
6
 
6
7
  require 'posthog/defaults'
@@ -50,29 +51,28 @@ module PostHog
50
51
  end
51
52
  end
52
53
 
53
- # @param [Hash] opts
54
- # @option opts [String] :api_key Your project's api_key
55
- # @option opts [String] :personal_api_key Your personal API key
56
- # @option opts [FixNum] :max_queue_size Maximum number of calls to be
57
- # remain queued. Defaults to 10_000.
58
- # @option opts [Bool] :test_mode +true+ if messages should remain
59
- # queued for testing. Defaults to +false+.
60
- # @option opts [Bool] :sync_mode +true+ to send events synchronously
61
- # on the calling thread. Useful in forking environments like Sidekiq
62
- # and Resque. Defaults to +false+.
63
- # @option opts [Proc] :on_error Handles error calls from the API.
64
- # @option opts [String] :host Fully qualified hostname of the PostHog server. Defaults to `https://us.i.posthog.com`
65
- # @option opts [Integer] :feature_flags_polling_interval How often to poll for feature flag definition changes.
66
- # Measured in seconds, defaults to 30.
67
- # @option opts [Integer] :feature_flag_request_timeout_seconds How long to wait for feature flag evaluation.
68
- # Measured in seconds, defaults to 3.
69
- # @option opts [Proc] :before_send A block that receives the event hash and should return either a modified hash
70
- # to be sent to PostHog or nil to prevent the event from being sent. e.g. `before_send: ->(event) { event }`
71
- # @option opts [Bool] :disable_singleton_warning +true+ to suppress the warning when multiple clients
72
- # share the same API key. Use only when you intentionally need multiple clients. Defaults to +false+.
73
- # @option opts [Object] :flag_definition_cache_provider An object implementing the
74
- # {FlagDefinitionCacheProvider} interface for distributed flag definition caching.
75
- # EXPERIMENTAL: This API may change in future minor version bumps.
54
+ # @param opts [Hash] Client configuration.
55
+ # @option opts [String] :api_key Your project's API key. Required.
56
+ # @option opts [String, nil] :personal_api_key Your personal API key. Required for local feature flag evaluation.
57
+ # @option opts [String] :host Fully qualified hostname of the PostHog server. Defaults to `https://us.i.posthog.com`.
58
+ # @option opts [Integer] :max_queue_size Maximum number of calls to remain queued. Defaults to 10_000.
59
+ # @option opts [Integer] :batch_size Maximum number of events to send in one async batch.
60
+ # @option opts [Boolean] :test_mode +true+ if messages should remain queued for testing. Defaults to +false+.
61
+ # @option opts [Boolean] :sync_mode +true+ to send events synchronously on the calling thread. Useful in
62
+ # forking environments like Sidekiq and Resque. Defaults to +false+.
63
+ # @option opts [Proc] :on_error Callback invoked as `on_error.call(status, error)` for API or serialization errors.
64
+ # @option opts [Integer] :feature_flags_polling_interval How often to poll for feature flag definition changes,
65
+ # in seconds. Defaults to 30.
66
+ # @option opts [Integer] :feature_flag_request_timeout_seconds How long to wait for feature flag evaluation,
67
+ # in seconds. Defaults to 3.
68
+ # @option opts [Proc] :before_send A callback that receives the event hash and should return either a modified
69
+ # hash to be sent to PostHog or nil to prevent the event from being sent. e.g. `before_send: ->(event) { event }`.
70
+ # @option opts [Boolean] :disable_singleton_warning +true+ to suppress the warning when multiple clients share
71
+ # the same API key. Use only when you intentionally need multiple clients. Defaults to +false+.
72
+ # @option opts [Boolean] :skip_ssl_verification +true+ to disable SSL certificate verification for requests.
73
+ # Intended only for local development or custom deployments.
74
+ # @option opts [Object] :flag_definition_cache_provider An object implementing the {FlagDefinitionCacheProvider}
75
+ # interface for distributed flag definition caching. EXPERIMENTAL: This API may change in future minor versions.
76
76
  def initialize(opts = {})
77
77
  symbolize_keys!(opts)
78
78
 
@@ -143,7 +143,9 @@ module PostHog
143
143
  # Synchronously waits until the worker has cleared the queue.
144
144
  #
145
145
  # Use only for scripts which are not long-running, and will specifically
146
- # exit
146
+ # exit.
147
+ #
148
+ # @return [void]
147
149
  def flush
148
150
  if @sync_mode
149
151
  # Wait for any in-flight sync send to complete
@@ -159,7 +161,9 @@ module PostHog
159
161
 
160
162
  # Clears the queue without waiting.
161
163
  #
162
- # Use only in test mode
164
+ # Use only in test mode.
165
+ #
166
+ # @return [void]
163
167
  def clear
164
168
  @queue.clear
165
169
  end
@@ -176,8 +180,10 @@ module PostHog
176
180
  #
177
181
  # @option attrs [String] :event Event name
178
182
  # @option attrs [Hash] :properties Event properties (optional)
179
- # @option attrs [Bool, Hash, SendFeatureFlagsOptions] :send_feature_flags
180
- # Whether to send feature flags with this event, or configuration for feature flag evaluation (optional)
183
+ # @option attrs [Hash] :groups Group analytics mapping from group type to group key (optional)
184
+ # @option attrs [Boolean, Hash, SendFeatureFlagsOptions] :send_feature_flags
185
+ # Deprecated. Whether to send feature flags with this event, or configuration for feature flag evaluation
186
+ # (optional)
181
187
  # @option attrs [PostHog::FeatureFlagEvaluations] :flags A snapshot returned by
182
188
  # {#evaluate_flags}. When present, `$feature/<key>` and `$active_feature_flags` are
183
189
  # attached from the snapshot without making an additional /flags request, and this
@@ -189,6 +195,7 @@ module PostHog
189
195
  # @note If `:distinct_id` is omitted, request/context distinct_id is used when
190
196
  # available; otherwise a UUID is generated and the event is marked personless
191
197
  # with `$process_person_profile: false`.
198
+ # @return [Boolean] Whether the event was queued or sent.
192
199
  # @macro common_attrs
193
200
  def capture(attrs)
194
201
  symbolize_keys! attrs
@@ -268,9 +275,10 @@ module PostHog
268
275
  # @param [String] distinct_id The ID for the user (optional, defaults to request/context distinct_id
269
276
  # or a generated UUID)
270
277
  # @param [Hash] additional_properties Additional properties to include with the exception event (optional)
271
- # @param [PostHog::FeatureFlagEvaluations] flags A snapshot returned by {#evaluate_flags}.
278
+ # @param flags [PostHog::FeatureFlagEvaluations, nil] A snapshot returned by {#evaluate_flags}.
272
279
  # Forwarded to the inner {#capture} call so the captured `$exception` event carries the
273
280
  # same `$feature/<key>` and `$active_feature_flags` properties as the snapshot.
281
+ # @return [Boolean, nil] Whether the exception event was queued or sent, or nil if the input could not be parsed.
274
282
  def capture_exception(exception, distinct_id = nil, additional_properties = {}, flags: nil)
275
283
  exception_info = ExceptionCapture.build_parsed_exception(exception)
276
284
 
@@ -295,6 +303,7 @@ module PostHog
295
303
  # @param [Hash] attrs
296
304
  #
297
305
  # @option attrs [Hash] :properties User properties (optional)
306
+ # @return [Boolean] Whether the identify event was queued or sent.
298
307
  # @macro common_attrs
299
308
  def identify(attrs)
300
309
  symbolize_keys! attrs
@@ -309,6 +318,7 @@ module PostHog
309
318
  # @option attrs [String] :group_key Group key
310
319
  # @option attrs [Hash] :properties Group properties (optional)
311
320
  # @option attrs [String] :distinct_id Distinct ID (optional)
321
+ # @return [Boolean] Whether the group identify event was queued or sent.
312
322
  # @macro common_attrs
313
323
  def group_identify(attrs)
314
324
  symbolize_keys! attrs
@@ -320,23 +330,32 @@ module PostHog
320
330
  # @param [Hash] attrs
321
331
  #
322
332
  # @option attrs [String] :alias The alias to give the distinct id
333
+ # @return [Boolean] Whether the alias event was queued or sent.
323
334
  # @macro common_attrs
324
335
  def alias(attrs)
325
336
  symbolize_keys! attrs
326
337
  enqueue(FieldParser.parse_for_alias(attrs))
327
338
  end
328
339
 
329
- # @return [Hash] pops the last message from the queue
340
+ # @return [Hash] Pops the last message from the queue. Intended for test mode.
330
341
  def dequeue_last_message
331
342
  @queue.pop
332
343
  end
333
344
 
334
- # @return [Fixnum] number of messages in the queue
345
+ # @return [Integer] Number of messages in the queue. Intended for test mode.
335
346
  def queued_messages
336
347
  @queue.length
337
348
  end
338
349
 
339
- # @deprecated Use {#evaluate_flags} and {FeatureFlagEvaluations#is_enabled} instead.
350
+ # @deprecated Use {#evaluate_flags} and {FeatureFlagEvaluations#enabled?} instead.
351
+ # @param flag_key [String, Symbol] The unique key of the feature flag.
352
+ # @param distinct_id [String] The distinct id of the user.
353
+ # @param groups [Hash] Group analytics mapping from group type to group key.
354
+ # @param person_properties [Hash] Properties to use when evaluating the user locally or remotely.
355
+ # @param group_properties [Hash] Properties to use when evaluating groups locally or remotely.
356
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
357
+ # @param send_feature_flag_events [Boolean] Whether to capture `$feature_flag_called` for this access.
358
+ # @return [Boolean, nil] Whether the flag is enabled, or nil when the flag could not be evaluated.
340
359
  # TODO: In future version, rename to `feature_flag_enabled?`
341
360
  def is_feature_enabled( # rubocop:disable Naming/PredicateName
342
361
  flag_key,
@@ -366,8 +385,8 @@ module PostHog
366
385
  !!response
367
386
  end
368
387
 
369
- # @param [String, Symbol] flag_key The unique flag key of the feature flag
370
- # @return [String] The decrypted value of the feature flag payload
388
+ # @param flag_key [String, Symbol] The unique flag key of the remote config feature flag.
389
+ # @return [Hash] The parsed remote config payload response.
371
390
  def get_remote_config_payload(flag_key)
372
391
  @feature_flags_poller.get_remote_config_payload(flag_key.to_s)
373
392
  end
@@ -379,8 +398,10 @@ module PostHog
379
398
  # @param [Hash] groups
380
399
  # @param [Hash] person_properties key-value pairs of properties to associate with the user.
381
400
  # @param [Hash] group_properties
401
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
402
+ # @param send_feature_flag_events [Boolean] Whether to capture `$feature_flag_called` for this access.
382
403
  #
383
- # @return [String, nil] The value of the feature flag
404
+ # @return [String, Boolean, nil] The value of the feature flag
384
405
  #
385
406
  # The provided properties are used to calculate feature flags locally, if possible.
386
407
  #
@@ -420,6 +441,14 @@ module PostHog
420
441
 
421
442
  # @deprecated Use {#evaluate_flags} and {FeatureFlagEvaluations#get_flag} /
422
443
  # {FeatureFlagEvaluations#get_flag_payload} instead.
444
+ # @param key [String, Symbol] The unique key of the feature flag.
445
+ # @param distinct_id [String] The distinct id of the user.
446
+ # @param groups [Hash] Group analytics mapping from group type to group key.
447
+ # @param person_properties [Hash] Properties to use when evaluating the user locally or remotely.
448
+ # @param group_properties [Hash] Properties to use when evaluating groups locally or remotely.
449
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
450
+ # @param send_feature_flag_events [Boolean] Whether to capture `$feature_flag_called` for this access.
451
+ # @return [PostHog::FeatureFlagResult, nil]
423
452
  def get_feature_flag_result(
424
453
  key,
425
454
  distinct_id,
@@ -456,7 +485,8 @@ module PostHog
456
485
  # @param [Hash] person_properties key-value pairs of properties to associate with the user
457
486
  # @param [Hash] group_properties
458
487
  # @param [Boolean] only_evaluate_locally Skip the remote /flags call entirely
459
- # @param [Boolean] disable_geoip Stamped on captured access events
488
+ # @param [Boolean, nil] disable_geoip When true, disables GeoIP lookup for remote evaluation and stamps captured
489
+ # access events.
460
490
  # @param [Array<String, Symbol>] flag_keys When set, scopes the underlying /flags
461
491
  # request to only these flag keys (sent as `flag_keys_to_evaluate`).
462
492
  # Distinct from {FeatureFlagEvaluations#only}, which filters the
@@ -580,6 +610,7 @@ module PostHog
580
610
  # @param [Hash] groups
581
611
  # @param [Hash] person_properties key-value pairs of properties to associate with the user.
582
612
  # @param [Hash] group_properties
613
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
583
614
  #
584
615
  # @return [Hash] String (not symbol) key value pairs of flag and their values
585
616
  def get_all_flags(
@@ -602,11 +633,12 @@ module PostHog
602
633
  #
603
634
  # @param [String, Symbol] key The key of the feature flag
604
635
  # @param [String] distinct_id The distinct id of the user
605
- # @option [String or boolean] match_value The value of the feature flag to be matched
606
- # @option [Hash] groups
607
- # @option [Hash] person_properties key-value pairs of properties to associate with the user.
608
- # @option [Hash] group_properties
609
- # @option [Boolean] only_evaluate_locally
636
+ # @param match_value [String, Boolean, nil] The value of the feature flag to be matched
637
+ # @param groups [Hash]
638
+ # @param person_properties [Hash] key-value pairs of properties to associate with the user.
639
+ # @param group_properties [Hash]
640
+ # @param only_evaluate_locally [Boolean]
641
+ # @return [Object, nil] The parsed payload for the matched flag value.
610
642
  #
611
643
  # @deprecated Use {#evaluate_flags} and {FeatureFlagEvaluations#get_flag_payload} instead.
612
644
  def get_feature_flag_payload(
@@ -639,10 +671,10 @@ module PostHog
639
671
  # featureFlagPayloads: A hash of feature flag payloads
640
672
  #
641
673
  # @param [String] distinct_id The distinct id of the user
642
- # @option [Hash] groups
643
- # @option [Hash] person_properties key-value pairs of properties to associate with the user.
644
- # @option [Hash] group_properties
645
- # @option [Boolean] only_evaluate_locally
674
+ # @param groups [Hash]
675
+ # @param person_properties [Hash] key-value pairs of properties to associate with the user.
676
+ # @param group_properties [Hash]
677
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
646
678
  #
647
679
  def get_all_flags_and_payloads(
648
680
  distinct_id,
@@ -664,6 +696,9 @@ module PostHog
664
696
  response
665
697
  end
666
698
 
699
+ # Reload locally cached feature flag definitions.
700
+ #
701
+ # @return [void]
667
702
  def reload_feature_flags
668
703
  unless @personal_api_key
669
704
  logger.error(
@@ -674,6 +709,9 @@ module PostHog
674
709
  @feature_flags_poller.load_feature_flags(true)
675
710
  end
676
711
 
712
+ # Flush pending events and stop background resources.
713
+ #
714
+ # @return [void]
677
715
  def shutdown
678
716
  self.class._decrement_instance_count(@api_key) if @api_key
679
717
  @feature_flags_poller.shutdown_poller
@@ -723,11 +761,22 @@ module PostHog
723
761
  # Shared by the legacy single-flag path ({#get_feature_flag_result}) and the
724
762
  # snapshot's access-recording. Owns dedup-key construction, the
725
763
  # per-distinct_id sent-flags cache, and the `$feature_flag_called` capture call.
764
+ # Group context is included in the dedup key so group-scoped flags fire a
765
+ # separate event for each group a user is evaluated under.
726
766
  def _capture_feature_flag_called_if_needed(
727
767
  distinct_id: nil, key: nil, response: nil, properties: nil,
728
768
  groups: nil, disable_geoip: nil
729
769
  )
730
- reported_key = "#{key}_#{response.nil? ? '::null::' : response}"
770
+ response_repr = response.nil? ? '::null::' : response
771
+ groups_repr =
772
+ if groups && !groups.empty?
773
+ # Canonicalize so two equal hashes with keys inserted in a different
774
+ # order produce the same dedup key.
775
+ "_#{groups.sort.to_json}"
776
+ else
777
+ ''
778
+ end
779
+ reported_key = "#{key}_#{response_repr}#{groups_repr}"
731
780
  return if @distinct_id_has_sent_flag_calls[distinct_id].include?(reported_key)
732
781
 
733
782
  msg = {
@@ -11,6 +11,9 @@
11
11
  # 💖 open source (under MIT License)
12
12
 
13
13
  module PostHog
14
+ # Builds PostHog exception payloads from Ruby exception objects.
15
+ #
16
+ # @api private
14
17
  module ExceptionCapture
15
18
  RUBY_INPUT_FORMAT = /
16
19
  ^ \s* (?: [a-zA-Z]: | uri:classloader: )? ([^:]+ | <.*>):
@@ -18,6 +21,8 @@ module PostHog
18
21
  (?: :in\s('|`)(?:([\w:]+)\#)?([^']+)')?$
19
22
  /x
20
23
 
24
+ # @param value [Exception, String, Object] Exception input to parse.
25
+ # @return [Hash, nil] Parsed exception payload, or nil when the input is unsupported.
21
26
  def self.build_parsed_exception(value)
22
27
  title, message, backtrace = coerce_exception_input(value)
23
28
  return nil if title.nil?
@@ -25,6 +30,10 @@ module PostHog
25
30
  build_single_exception_from_data(title, message, backtrace)
26
31
  end
27
32
 
33
+ # @param title [String]
34
+ # @param message [String, nil]
35
+ # @param backtrace [Array<String>, nil]
36
+ # @return [Hash]
28
37
  def self.build_single_exception_from_data(title, message, backtrace)
29
38
  {
30
39
  'type' => title,
@@ -37,6 +46,8 @@ module PostHog
37
46
  }
38
47
  end
39
48
 
49
+ # @param backtrace [Array<String>, nil]
50
+ # @return [Hash, nil]
40
51
  def self.build_stacktrace(backtrace)
41
52
  return nil unless backtrace && !backtrace.empty?
42
53
 
@@ -50,6 +61,8 @@ module PostHog
50
61
  }
51
62
  end
52
63
 
64
+ # @param line [String]
65
+ # @return [Hash, nil]
53
66
  def self.parse_backtrace_line(line)
54
67
  match = line.match(RUBY_INPUT_FORMAT)
55
68
  return nil unless match
@@ -72,6 +85,8 @@ module PostHog
72
85
  frame
73
86
  end
74
87
 
88
+ # @param path [String]
89
+ # @return [Boolean]
75
90
  def self.gem_path?(path)
76
91
  path.include?('/gems/') ||
77
92
  path.include?('/ruby/') ||
@@ -79,6 +94,11 @@ module PostHog
79
94
  path.include?('/.rvm/')
80
95
  end
81
96
 
97
+ # @param frame [Hash]
98
+ # @param file_path [String]
99
+ # @param lineno [Integer]
100
+ # @param context_size [Integer]
101
+ # @return [void]
82
102
  def self.add_context_lines(frame, file_path, lineno, context_size = 5)
83
103
  lines = File.readlines(file_path)
84
104
  return if lines.empty?
@@ -97,6 +117,8 @@ module PostHog
97
117
  # Silently ignore file read errors
98
118
  end
99
119
 
120
+ # @param value [Exception, String, Object]
121
+ # @return [Array] Three-item array of title, message, and backtrace.
100
122
  def self.coerce_exception_input(value)
101
123
  if value.is_a?(String)
102
124
  title = 'Error'
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Represents a feature flag returned by /flags v2
4
3
  module PostHog
4
+ # Represents a feature flag returned by /flags v2.
5
+ #
6
+ # @api private
5
7
  class FeatureFlag
6
8
  attr_reader :key, :enabled, :variant, :reason, :metadata, :failed
7
9
 
10
+ # @param json [Hash] Raw feature flag data returned by /flags.
8
11
  def initialize(json)
9
12
  json.transform_keys!(&:to_s)
10
13
  @key = json['key']
@@ -15,15 +18,21 @@ module PostHog
15
18
  @failed = json['failed']
16
19
  end
17
20
 
21
+ # @return [String, Boolean] The variant value when present, otherwise the enabled status.
18
22
  # TODO: Rename to `value` in future version
19
23
  def get_value # rubocop:disable Naming/AccessorMethodName
20
24
  @variant || @enabled
21
25
  end
22
26
 
27
+ # @return [Object, nil] The flag payload from metadata.
23
28
  def payload
24
29
  @metadata&.payload
25
30
  end
26
31
 
32
+ # @param key [String, Symbol] The feature flag key.
33
+ # @param value [String, Boolean] The feature flag value.
34
+ # @param payload [Object, nil] The feature flag payload.
35
+ # @return [PostHog::FeatureFlag]
27
36
  def self.from_value_and_payload(key, value, payload)
28
37
  new({
29
38
  'key' => key,
@@ -40,10 +49,13 @@ module PostHog
40
49
  end
41
50
  end
42
51
 
43
- # Represents the reason why a flag was enabled/disabled
52
+ # Represents the reason why a flag was enabled/disabled.
53
+ #
54
+ # @api private
44
55
  class EvaluationReason
45
56
  attr_reader :code, :description, :condition_index
46
57
 
58
+ # @param json [Hash] Raw reason data returned by /flags.
47
59
  def initialize(json)
48
60
  json.transform_keys!(&:to_s)
49
61
  @code = json['code']
@@ -52,10 +64,13 @@ module PostHog
52
64
  end
53
65
  end
54
66
 
55
- # Represents metadata about a feature flag
67
+ # Represents metadata about a feature flag.
68
+ #
69
+ # @api private
56
70
  class FeatureFlagMetadata
57
71
  attr_reader :id, :version, :payload, :description
58
72
 
73
+ # @param json [Hash] Raw metadata returned by /flags.
59
74
  def initialize(json)
60
75
  json.transform_keys!(&:to_s)
61
76
  @id = json['id']
@@ -17,6 +17,7 @@ module PostHog
17
17
  #
18
18
  # For API errors with status codes, use the api_error() method which returns
19
19
  # a string like "api_error_500".
20
+ # @api private
20
21
  class FeatureFlagError
21
22
  ERRORS_WHILE_COMPUTING = 'errors_while_computing_flags'
22
23
  FLAG_MISSING = 'flag_missing'
@@ -4,7 +4,7 @@ require 'set'
4
4
 
5
5
  module PostHog
6
6
  # A snapshot of feature flag evaluations for one distinct_id, returned by
7
- # PostHog::Client#evaluate_flags. Calls to {#is_enabled} / {#get_flag} fire the
7
+ # PostHog::Client#evaluate_flags. Calls to {#enabled?} / {#get_flag} fire the
8
8
  # `$feature_flag_called` event (deduped through the existing per-distinct_id
9
9
  # cache); {#get_flag_payload} does not. Pass the snapshot to `capture(flags:)`
10
10
  # to attach `$feature/<key>` and `$active_feature_flags` without a second
@@ -19,8 +19,32 @@ module PostHog
19
19
 
20
20
  Host = Struct.new(:capture_flag_called_event_if_needed, :log_warning, keyword_init: true)
21
21
 
22
- attr_reader :distinct_id, :groups, :request_id, :evaluated_at, :flag_definitions_loaded_at
22
+ # @return [String] The distinct id these evaluations belong to.
23
+ attr_reader :distinct_id
23
24
 
25
+ # @return [Hash, nil] Group analytics mapping used for evaluation.
26
+ attr_reader :groups
27
+
28
+ # @return [String, nil] Request id returned by the /flags endpoint.
29
+ attr_reader :request_id
30
+
31
+ # @return [String, nil] Evaluation timestamp returned by the /flags endpoint.
32
+ attr_reader :evaluated_at
33
+
34
+ # @return [Time, nil] When local flag definitions were loaded.
35
+ attr_reader :flag_definitions_loaded_at
36
+
37
+ # @param host [Host, nil] Internal host callbacks used to record flag access events.
38
+ # @param distinct_id [String, nil] The distinct id these evaluations belong to.
39
+ # @param flags [Hash] Evaluated flags keyed by flag key.
40
+ # @param groups [Hash, nil] Group analytics mapping from group type to group key.
41
+ # @param disable_geoip [Boolean, nil] Whether GeoIP was disabled during evaluation.
42
+ # @param request_id [String, nil] The request id returned by the /flags endpoint.
43
+ # @param evaluated_at [String, nil] The evaluation timestamp returned by the /flags endpoint.
44
+ # @param flag_definitions_loaded_at [Time, nil] When local flag definitions were loaded.
45
+ # @param errors_while_computing [Boolean] Whether the server reported errors while computing flags.
46
+ # @param quota_limited [Boolean] Whether feature flag evaluation was quota limited.
47
+ # @param accessed [Array<String>, Set<String>, nil] Flag keys already accessed by this snapshot.
24
48
  def initialize(
25
49
  host: nil,
26
50
  distinct_id: nil,
@@ -47,10 +71,13 @@ module PostHog
47
71
  @accessed = Set.new(accessed || [])
48
72
  end
49
73
 
74
+ # @return [Array<String>] The evaluated flag keys in this snapshot.
50
75
  def keys
51
76
  @flags.keys
52
77
  end
53
78
 
79
+ # @param key [String, Symbol] The feature flag key.
80
+ # @return [Boolean] true when the flag is enabled, false when disabled or missing.
54
81
  def enabled?(key)
55
82
  key = key.to_s
56
83
  flag = @flags[key]
@@ -58,6 +85,9 @@ module PostHog
58
85
  flag&.enabled ? true : false
59
86
  end
60
87
 
88
+ # @param key [String, Symbol] The feature flag key.
89
+ # @return [String, Boolean, nil] Variant string for multivariate flags, true/false for boolean flags,
90
+ # or nil when the flag was not returned by the evaluation.
61
91
  def get_flag(key)
62
92
  key = key.to_s
63
93
  flag = @flags[key]
@@ -65,6 +95,8 @@ module PostHog
65
95
  _flag_value(flag)
66
96
  end
67
97
 
98
+ # @param key [String, Symbol] The feature flag key.
99
+ # @return [Object, nil] The parsed payload for the flag, if any.
68
100
  def get_flag_payload(key)
69
101
  flag = @flags[key.to_s]
70
102
  flag&.payload
@@ -73,10 +105,14 @@ module PostHog
73
105
  # Order-dependent: if nothing has been accessed yet, the returned snapshot is
74
106
  # empty. The method honors its name — pre-access flags before calling this if
75
107
  # you want a populated result.
108
+ # @return [PostHog::FeatureFlagEvaluations] A snapshot containing only flags already accessed with
109
+ # {#enabled?} or {#get_flag}.
76
110
  def only_accessed
77
111
  _clone_with(@flags.slice(*@accessed))
78
112
  end
79
113
 
114
+ # @param keys [Array<String, Symbol>, String, Symbol] Flag keys to keep in the returned snapshot.
115
+ # @return [PostHog::FeatureFlagEvaluations] A snapshot containing only the requested keys that exist.
80
116
  def only(keys)
81
117
  keys = Array(keys).map(&:to_s)
82
118
  missing = keys.reject { |k| @flags.key?(k) }
@@ -92,6 +128,9 @@ module PostHog
92
128
 
93
129
  # Builds the `$feature/<key>` and `$active_feature_flags` properties for a
94
130
  # captured event. Called from PostHog::Client#capture when `flags:` is set.
131
+ #
132
+ # @api private
133
+ # @return [Hash]
95
134
  def _get_event_properties
96
135
  properties = {}
97
136
  active = []
@@ -6,8 +6,19 @@ module PostHog
6
6
  # Represents the result of a feature flag evaluation
7
7
  # containing both the flag value and payload
8
8
  class FeatureFlagResult
9
- attr_reader :key, :variant, :payload
9
+ # @return [String, Symbol] The feature flag key.
10
+ attr_reader :key
10
11
 
12
+ # @return [String, nil] The variant key for multivariate flags.
13
+ attr_reader :variant
14
+
15
+ # @return [Object, nil] The parsed feature flag payload.
16
+ attr_reader :payload
17
+
18
+ # @param key [String, Symbol] The feature flag key.
19
+ # @param enabled [Boolean] Whether the feature flag is enabled.
20
+ # @param variant [String, nil] The variant key for multivariate flags.
21
+ # @param payload [Object, nil] The parsed feature flag payload.
11
22
  def initialize(key:, enabled:, variant: nil, payload: nil)
12
23
  @key = key
13
24
  @enabled = enabled
@@ -15,18 +26,27 @@ module PostHog
15
26
  @payload = payload
16
27
  end
17
28
 
18
- # Returns the effective value of the feature flag
19
- # variant if present, otherwise enabled status
29
+ # Returns the effective value of the feature flag: variant if present,
30
+ # otherwise enabled status.
31
+ #
32
+ # @return [String, Boolean]
20
33
  def value
21
34
  @variant || @enabled
22
35
  end
23
36
 
24
- # Returns whether or not the feature flag evaluated as enabled
37
+ # Returns whether or not the feature flag evaluated as enabled.
38
+ #
39
+ # @return [Boolean]
25
40
  def enabled?
26
41
  @enabled
27
42
  end
28
43
 
29
- # Factory method to create from flag value and payload
44
+ # Factory method to create from flag value and payload.
45
+ #
46
+ # @param key [String, Symbol] The feature flag key.
47
+ # @param value [String, Boolean, nil] The raw feature flag value.
48
+ # @param payload [Object, String, nil] The raw or JSON-encoded feature flag payload.
49
+ # @return [PostHog::FeatureFlagResult, nil]
30
50
  def self.from_value_and_payload(key, value, payload)
31
51
  return nil if value.nil?
32
52
 
@@ -43,6 +63,9 @@ module PostHog
43
63
  # returned when the body is not valid JSON); already-deserialized values
44
64
  # pass through. Public so {FeatureFlagEvaluations} can normalize payloads
45
65
  # the same way {FeatureFlagResult} does.
66
+ #
67
+ # @param payload [Object, String, nil] The raw payload value.
68
+ # @return [Object, nil] The parsed payload.
46
69
  def self.parse_payload(payload)
47
70
  return nil if payload.nil?
48
71
  return payload unless payload.is_a?(String)
@@ -20,10 +20,20 @@ module PostHog
20
20
  class RequiresServerEvaluation < StandardError
21
21
  end
22
22
 
23
+ # Polls and evaluates feature flag definitions for {PostHog::Client}.
24
+ #
25
+ # @api private
23
26
  class FeatureFlagsPoller
24
27
  include PostHog::Logging
25
28
  include PostHog::Utils
26
29
 
30
+ # @param polling_interval [Integer, nil] Seconds between local feature flag definition polls.
31
+ # @param personal_api_key [String, nil] Personal API key used to fetch local evaluation definitions.
32
+ # @param project_api_key [String] Project API key.
33
+ # @param host [String] PostHog API host URL.
34
+ # @param feature_flag_request_timeout_seconds [Integer] Timeout for feature flag requests.
35
+ # @param on_error [Proc, nil] Callback invoked as `on_error.call(status, error)`.
36
+ # @param flag_definition_cache_provider [Object, nil] Optional {FlagDefinitionCacheProvider} implementation.
27
37
  def initialize(
28
38
  polling_interval,
29
39
  personal_api_key,
@@ -446,6 +456,16 @@ module PostHog
446
456
  parsed_dt
447
457
  end
448
458
 
459
+ # Parse a single semver numeric identifier, rejecting empty, non-digit, or
460
+ # leading-zero values per semver 2.0.0 §2.
461
+ def self.parse_semver_numeric(part)
462
+ raise InconclusiveMatchError, 'Invalid semver format' if part.nil? || part.empty? || part !~ /^\d+$/
463
+ # Semver 2.0.0 §2: numeric identifiers MUST NOT include leading zeros.
464
+ raise InconclusiveMatchError, 'Invalid semver format' if part.length > 1 && part[0] == '0'
465
+
466
+ part.to_i
467
+ end
468
+
449
469
  # Parse a semver string into a comparable [major, minor, patch] integer array.
450
470
  # Handles v-prefix, whitespace, pre-release suffixes. Defaults missing components to 0.
451
471
  def self.parse_semver(value)
@@ -461,14 +481,9 @@ module PostHog
461
481
 
462
482
  raise InconclusiveMatchError, 'Invalid semver format' if parts.empty? || parts[0].to_s.empty?
463
483
 
464
- # Check for leading dot or non-numeric parts
465
- parts.each do |part|
466
- raise InconclusiveMatchError, 'Invalid semver format' if part.empty? || part !~ /^\d+$/
467
- end
468
-
469
- major = parts[0].to_i
470
- minor = parts.length > 1 ? parts[1].to_i : 0
471
- patch = parts.length > 2 ? parts[2].to_i : 0
484
+ major = parse_semver_numeric(parts[0])
485
+ minor = parts.length > 1 ? parse_semver_numeric(parts[1]) : 0
486
+ patch = parts.length > 2 ? parse_semver_numeric(parts[2]) : 0
472
487
 
473
488
  [major, minor, patch]
474
489
  end
@@ -525,20 +540,22 @@ module PostHog
525
540
 
526
541
  raise InconclusiveMatchError, 'Invalid semver wildcard format' if parts.empty?
527
542
 
528
- parts.each do |part|
529
- raise InconclusiveMatchError, 'Invalid semver wildcard format' if part !~ /^\d+$/
543
+ numeric = parts.map do |part|
544
+ parse_semver_numeric(part)
545
+ rescue InconclusiveMatchError
546
+ raise InconclusiveMatchError, 'Invalid semver wildcard format'
530
547
  end
531
548
 
532
- major = parts[0].to_i
533
- case parts.length
549
+ major = numeric[0]
550
+ case numeric.length
534
551
  when 1
535
552
  [[major, 0, 0], [major + 1, 0, 0]]
536
553
  when 2
537
- minor = parts[1].to_i
554
+ minor = numeric[1]
538
555
  [[major, minor, 0], [major, minor + 1, 0]]
539
556
  else
540
- minor = parts[1].to_i
541
- patch = parts[2].to_i
557
+ minor = numeric[1]
558
+ patch = numeric[2]
542
559
  [[major, minor, patch], [major, minor, patch + 1]]
543
560
  end
544
561
  end
@@ -3,6 +3,9 @@
3
3
  require 'posthog/logging'
4
4
 
5
5
  module PostHog
6
+ # Converts public SDK method arguments into PostHog API event payloads.
7
+ #
8
+ # @api private
6
9
  class FieldParser
7
10
  class << self
8
11
  include PostHog::Utils
@@ -14,6 +17,8 @@ module PostHog
14
17
  # - "properties"
15
18
  # - "groups"
16
19
  # - "uuid"
20
+ # @param fields [Hash]
21
+ # @return [Hash]
17
22
  def parse_for_capture(fields)
18
23
  common = parse_common_fields(fields)
19
24
 
@@ -45,6 +50,8 @@ module PostHog
45
50
  # In addition to the common fields, identify accepts:
46
51
  #
47
52
  # - "properties"
53
+ # @param fields [Hash]
54
+ # @return [Hash]
48
55
  def parse_for_identify(fields)
49
56
  common = parse_common_fields(fields)
50
57
 
@@ -63,6 +70,8 @@ module PostHog
63
70
  )
64
71
  end
65
72
 
73
+ # @param fields [Hash]
74
+ # @return [Hash]
66
75
  def parse_for_group_identify(fields)
67
76
  properties = fields[:properties] || {}
68
77
  group_type = fields[:group_type]
@@ -92,6 +101,8 @@ module PostHog
92
101
  # In addition to the common fields, alias accepts:
93
102
  #
94
103
  # - "alias"
104
+ # @param fields [Hash]
105
+ # @return [Hash]
95
106
  def parse_for_alias(fields)
96
107
  common = parse_common_fields(fields)
97
108
 
@@ -14,26 +14,31 @@ module PostHog
14
14
  #
15
15
  # == Required Methods
16
16
  #
17
- # [+flag_definitions+]
17
+ # @!method flag_definitions
18
18
  # Retrieve cached flag definitions. Return a Hash with +:flags+,
19
19
  # +:group_type_mapping+, and +:cohorts+ keys, or +nil+ if the cache
20
20
  # is empty. Returning +nil+ triggers an API fetch when no flags are
21
21
  # loaded yet (emergency fallback).
22
+ # @return [Hash, nil]
22
23
  #
23
- # [+should_fetch_flag_definitions?+]
24
+ # @!method should_fetch_flag_definitions?
24
25
  # Return +true+ if this instance should fetch new definitions from the
25
26
  # API, +false+ to read from cache instead. Use for distributed lock
26
27
  # coordination so only one worker fetches at a time.
28
+ # @return [Boolean]
27
29
  #
28
- # [+on_flag_definitions_received(data)+]
30
+ # @!method on_flag_definitions_received(data)
29
31
  # Called after successfully fetching new definitions from the API.
30
32
  # +data+ is a Hash with +:flags+, +:group_type_mapping+, and +:cohorts+
31
33
  # keys (plain Ruby types, not Concurrent:: wrappers). Store it in your
32
34
  # external cache.
35
+ # @param data [Hash]
36
+ # @return [void]
33
37
  #
34
- # [+shutdown+]
38
+ # @!method shutdown
35
39
  # Called when the PostHog client shuts down. Release any distributed
36
40
  # locks and clean up resources.
41
+ # @return [void]
37
42
  #
38
43
  # == Error Handling
39
44
  #
@@ -66,6 +71,7 @@ module PostHog
66
71
  #
67
72
  # @param provider [Object] the cache provider to validate
68
73
  # @raise [ArgumentError] if any required methods are missing
74
+ # @return [void]
69
75
  def self.validate!(provider)
70
76
  missing = REQUIRED_METHODS.reject { |m| provider.respond_to?(m) }
71
77
  return if missing.empty?
@@ -3,8 +3,12 @@
3
3
  require 'logger'
4
4
 
5
5
  module PostHog
6
- # Wraps an existing logger and adds a prefix to all messages
6
+ # Wraps an existing logger and adds a prefix to all messages.
7
+ #
8
+ # @api private
7
9
  class PrefixedLogger
10
+ # @param logger [Logger, #debug, #info, #warn, #error]
11
+ # @param prefix [String]
8
12
  def initialize(logger, prefix)
9
13
  @logger = logger
10
14
  @prefix = prefix
@@ -37,6 +41,7 @@ module PostHog
37
41
 
38
42
  module Logging
39
43
  class << self
44
+ # @return [Logger, PostHog::PrefixedLogger] The logger used by the SDK.
40
45
  def logger
41
46
  return @logger if @logger
42
47
 
@@ -52,6 +57,7 @@ module PostHog
52
57
  @logger = PrefixedLogger.new(base_logger, '[posthog-ruby]')
53
58
  end
54
59
 
60
+ # @param logger [Logger, #debug, #info, #warn, #error] Custom logger used by the SDK.
55
61
  attr_writer :logger
56
62
  end
57
63
 
@@ -63,6 +69,7 @@ module PostHog
63
69
  end
64
70
  end
65
71
 
72
+ # @return [Logger, PostHog::PrefixedLogger] The logger used by the SDK.
66
73
  def logger
67
74
  Logging.logger
68
75
  end
@@ -4,7 +4,9 @@ require 'forwardable'
4
4
  require 'posthog/logging'
5
5
 
6
6
  module PostHog
7
- # A batch of `Message`s to be sent to the API
7
+ # A batch of messages to be sent to the API.
8
+ #
9
+ # @api private
8
10
  class MessageBatch
9
11
  class JSONGenerationError < StandardError
10
12
  end
@@ -13,12 +15,15 @@ module PostHog
13
15
  include PostHog::Logging
14
16
  include PostHog::Defaults::MessageBatch
15
17
 
18
+ # @param max_message_count [Integer] Maximum number of messages in the batch.
16
19
  def initialize(max_message_count)
17
20
  @messages = []
18
21
  @max_message_count = max_message_count
19
22
  @json_size = 0
20
23
  end
21
24
 
25
+ # @param message [Hash] Message to add to the batch.
26
+ # @return [Array<Hash>, nil]
22
27
  def <<(message)
23
28
  begin
24
29
  message_json = message.to_json
@@ -35,10 +40,12 @@ module PostHog
35
40
  end
36
41
  end
37
42
 
43
+ # @return [Boolean] Whether the batch is full.
38
44
  def full?
39
45
  item_count_exhausted? || size_exhausted?
40
46
  end
41
47
 
48
+ # @return [void]
42
49
  def clear
43
50
  @messages.clear
44
51
  @json_size = 0
@@ -1,21 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # A worker that doesn't consume jobs
4
3
  module PostHog
4
+ # A worker that doesn't consume jobs.
5
+ #
6
+ # @api private
5
7
  class NoopWorker
8
+ # @param queue [Queue]
6
9
  def initialize(queue)
7
10
  @queue = queue
8
11
  end
9
12
 
13
+ # @return [void]
10
14
  def run
11
15
  # Does nothing
12
16
  end
13
17
 
18
+ # @return [Boolean]
14
19
  # TODO: Rename to `requesting?` in future version
15
20
  def is_requesting? # rubocop:disable Naming/PredicateName
16
21
  false
17
22
  end
18
23
 
24
+ # @return [void]
19
25
  def shutdown
20
26
  # Does nothing
21
27
  end
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PostHog
4
+ # API response wrapper returned by the SDK transport.
5
+ #
6
+ # @api private
4
7
  class Response
5
8
  attr_reader :status, :error
6
9
 
7
- # public: Simple class to wrap responses from the API
8
- #
9
- #
10
+ # @param status [Integer] HTTP status code, or -1 for SDK/transport errors.
11
+ # @param error [String, nil] Error message returned by the API or SDK.
10
12
  def initialize(status = 200, error = nil)
11
13
  @status = status
12
14
  @error = error
@@ -3,16 +3,29 @@
3
3
  require 'posthog/utils'
4
4
 
5
5
  module PostHog
6
- # Options for configuring feature flag behavior in capture calls
6
+ # Options for configuring deprecated feature flag behavior in capture calls.
7
+ #
8
+ # @deprecated Prefer passing a {PostHog::FeatureFlagEvaluations} snapshot to `capture(flags:)`.
7
9
  class SendFeatureFlagsOptions
8
- attr_reader :only_evaluate_locally, :person_properties, :group_properties
10
+ # @return [Boolean, nil] Whether remote feature flag evaluation should be skipped.
11
+ attr_reader :only_evaluate_locally
9
12
 
13
+ # @return [Hash] Person properties to use for feature flag evaluation.
14
+ attr_reader :person_properties
15
+
16
+ # @return [Hash] Group properties to use for feature flag evaluation.
17
+ attr_reader :group_properties
18
+
19
+ # @param only_evaluate_locally [Boolean, nil] Skip remote feature flag evaluation.
20
+ # @param person_properties [Hash, nil] Person properties to use for feature flag evaluation.
21
+ # @param group_properties [Hash, nil] Group properties to use for feature flag evaluation.
10
22
  def initialize(only_evaluate_locally: nil, person_properties: nil, group_properties: nil)
11
23
  @only_evaluate_locally = only_evaluate_locally
12
24
  @person_properties = person_properties || {}
13
25
  @group_properties = group_properties || {}
14
26
  end
15
27
 
28
+ # @return [Hash] A hash representation suitable for `capture(send_feature_flags:)`.
16
29
  def to_h
17
30
  {
18
31
  only_evaluate_locally: @only_evaluate_locally,
@@ -21,6 +34,8 @@ module PostHog
21
34
  }
22
35
  end
23
36
 
37
+ # @param hash [Hash]
38
+ # @return [PostHog::SendFeatureFlagsOptions, nil]
24
39
  def self.from_hash(hash)
25
40
  return nil unless hash.is_a?(Hash)
26
41
 
@@ -6,6 +6,9 @@ require 'posthog/transport'
6
6
  require 'posthog/utils'
7
7
 
8
8
  module PostHog
9
+ # Background worker that batches and sends queued events.
10
+ #
11
+ # @api private
9
12
  class SendWorker
10
13
  include PostHog::Utils
11
14
  include PostHog::Defaults
@@ -16,12 +19,13 @@ module PostHog
16
19
  # The worker continuously takes messages off the queue
17
20
  # and makes requests to the posthog.com api
18
21
  #
19
- # queue - Queue synchronized between client and worker
20
- # api_key - String of the project's API key
21
- # options - Hash of worker options
22
- # batch_size - Fixnum of how many items to send in a batch
23
- # on_error - Proc of what to do on an error
24
- #
22
+ # @param queue [Queue] Queue synchronized between client and worker.
23
+ # @param api_key [String] Project API key.
24
+ # @param options [Hash] Worker options.
25
+ # @option options [Integer] :batch_size How many items to send in a batch.
26
+ # @option options [Proc] :on_error Callback invoked as `on_error.call(status, error)`.
27
+ # @option options [String] :host PostHog API host URL.
28
+ # @option options [Boolean] :skip_ssl_verification Disable SSL certificate verification.
25
29
  def initialize(queue, api_key, options = {})
26
30
  symbolize_keys! options
27
31
  @queue = queue
@@ -33,8 +37,9 @@ module PostHog
33
37
  @transport = Transport.new api_host: options[:host], skip_ssl_verification: options[:skip_ssl_verification]
34
38
  end
35
39
 
36
- # public: Continuously runs the loop to check for new events
40
+ # Continuously runs the loop to check for new events.
37
41
  #
42
+ # @return [void]
38
43
  def run
39
44
  until Thread.current[:should_exit]
40
45
  return if @queue.empty?
@@ -54,12 +59,14 @@ module PostHog
54
59
  @transport.shutdown
55
60
  end
56
61
 
62
+ # @return [void]
57
63
  def shutdown
58
64
  @transport.shutdown
59
65
  end
60
66
 
61
67
  # public: Check whether we have outstanding requests.
62
68
  #
69
+ # @return [Boolean] Whether the worker has outstanding requests.
63
70
  # TODO: Rename to `requesting?` in future version
64
71
  def is_requesting? # rubocop:disable Naming/PredicateName
65
72
  @lock.synchronize { !@batch.empty? }
@@ -10,11 +10,24 @@ require 'net/https'
10
10
  require 'json'
11
11
 
12
12
  module PostHog
13
+ # HTTP transport used by the SDK workers.
14
+ #
15
+ # @api private
13
16
  class Transport
14
17
  include PostHog::Defaults::Request
15
18
  include PostHog::Utils
16
19
  include PostHog::Logging
17
20
 
21
+ # @param options [Hash] Transport configuration.
22
+ # @option options [String] :api_host Full PostHog API host URL.
23
+ # @option options [String] :host Hostname to connect to.
24
+ # @option options [Integer] :port Port to connect to.
25
+ # @option options [Boolean] :ssl Whether to use HTTPS.
26
+ # @option options [Hash] :headers HTTP headers for batch requests.
27
+ # @option options [String] :path HTTP path for batch requests.
28
+ # @option options [Integer] :retries Number of retry attempts for retryable failures.
29
+ # @option options [PostHog::BackoffPolicy] :backoff_policy Backoff policy used between retries.
30
+ # @option options [Boolean] :skip_ssl_verification Disable SSL certificate verification.
18
31
  def initialize(options = {})
19
32
  if options[:api_host]
20
33
  uri = URI.parse(options[:api_host])
@@ -43,6 +56,8 @@ module PostHog
43
56
 
44
57
  # Sends a batch of messages to the API
45
58
  #
59
+ # @param api_key [String] Project API key.
60
+ # @param batch [PostHog::MessageBatch, Array<Hash>] Batch of messages to send.
46
61
  # @return [Response] API response
47
62
  def send(api_key, batch)
48
63
  logger.debug("Sending request for #{batch.length} items")
@@ -72,7 +87,9 @@ module PostHog
72
87
  end
73
88
  end
74
89
 
75
- # Closes a persistent connection if it exists
90
+ # Closes a persistent connection if it exists.
91
+ #
92
+ # @return [void]
76
93
  def shutdown
77
94
  @http.finish if @http.started?
78
95
  end
data/lib/posthog/utils.rb CHANGED
@@ -6,6 +6,9 @@ module PostHog
6
6
  class InconclusiveMatchError < StandardError
7
7
  end
8
8
 
9
+ # Utility helpers used internally by the SDK.
10
+ #
11
+ # @api private
9
12
  module Utils
10
13
  module_function
11
14
 
@@ -145,12 +148,19 @@ module PostHog
145
148
  end
146
149
  end
147
150
 
151
+ # Hash that clears itself when it reaches a maximum length.
152
+ #
153
+ # @api private
148
154
  class SizeLimitedHash < Hash
155
+ # @param max_length [Integer]
149
156
  def initialize(max_length, ...)
150
157
  super(...)
151
158
  @max_length = max_length
152
159
  end
153
160
 
161
+ # @param key [Object]
162
+ # @param value [Object]
163
+ # @return [Object]
154
164
  def []=(key, value)
155
165
  clear if length >= @max_length
156
166
  super
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PostHog
4
- VERSION = '3.9.0'
4
+ VERSION = '3.9.2'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: posthog-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.0
4
+ version: 3.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''