smplkit 1.0.13 → 1.0.15

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.
data/lib/smplkit/ws.rb CHANGED
@@ -90,14 +90,16 @@ module Smplkit
90
90
  def stop
91
91
  Smplkit.debug("websocket", "stopping shared WebSocket")
92
92
  @closed = true
93
- @connection_status = "disconnected"
94
93
  close_active_connection
95
94
  thread = @ws_thread
96
95
  @ws_thread = nil
97
- return unless thread
98
-
99
- thread.join(2.0)
100
- thread.kill if thread.alive?
96
+ if thread
97
+ thread.join(2.0)
98
+ thread.kill if thread.alive?
99
+ end
100
+ # Set authoritatively after the thread is dead so a racing connect
101
+ # call (which also sets "connecting") cannot clobber this value.
102
+ @connection_status = "disconnected"
101
103
  end
102
104
 
103
105
  # ----- URL builder ----------------------------------------------
@@ -169,6 +171,8 @@ module Smplkit
169
171
  end
170
172
 
171
173
  def connect(task)
174
+ return if @closed
175
+
172
176
  url = build_ws_url
173
177
  @connection_status = "connecting"
174
178
  Smplkit.debug("websocket", "connecting to #{safe_url}")
data/lib/smplkit.rb CHANGED
@@ -11,6 +11,29 @@ module Smplkit
11
11
  end
12
12
 
13
13
  require_relative "smplkit/version"
14
+
15
+ # Load the generated OpenAPI client trees. Each tree under
16
+ # +lib/smplkit/_generated/<svc>/lib+ uses internal +require+ paths like
17
+ # +smplkit_<svc>_client/api_client+, so the directory has to be on
18
+ # +$LOAD_PATH+ before its top-level entry is required.
19
+ %w[app config flags logging].each do |svc|
20
+ generated_lib = File.expand_path("smplkit/_generated/#{svc}/lib", __dir__)
21
+ $LOAD_PATH.unshift(generated_lib) if File.directory?(generated_lib)
22
+ end
23
+
24
+ # The openapi-generator-produced files declare +module SmplkitGeneratedClient::App+
25
+ # without first declaring the parent module. MRI requires it to already
26
+ # exist, so pre-declare here.
27
+ module SmplkitGeneratedClient # rubocop:disable Style/OneClassPerFile
28
+ end
29
+
30
+ %w[smplkit_app_client smplkit_config_client smplkit_flags_client smplkit_logging_client].each do |gem_lib|
31
+ require gem_lib
32
+ rescue LoadError
33
+ # Generated tree may be intentionally absent in development snapshots —
34
+ # the wrapper layer falls back gracefully.
35
+ end
36
+
14
37
  require_relative "smplkit/errors"
15
38
  require_relative "smplkit/debug"
16
39
  require_relative "smplkit/helpers"
@@ -0,0 +1,78 @@
1
+ module Smplkit
2
+ module Config
3
+ module ItemType
4
+ STRING: String
5
+ NUMBER: String
6
+ BOOLEAN: String
7
+ JSON: String
8
+ ALL: Array[String]
9
+ end
10
+
11
+ class ConfigItem
12
+ attr_accessor name: String
13
+ attr_accessor value: untyped
14
+ attr_accessor type: String
15
+ attr_accessor description: String?
16
+ def initialize: (name: String, value: untyped, type: String, ?description: String?) -> void
17
+ def to_h: () -> Hash[String, untyped]
18
+ end
19
+
20
+ class ConfigEnvironment
21
+ def initialize: (?values: Hash[String, untyped]?) -> void
22
+ def values: () -> Hash[String, untyped]
23
+ def values_raw: () -> Hash[String, Hash[String, untyped]]
24
+ end
25
+
26
+ class Config
27
+ attr_accessor id: String?
28
+ attr_accessor key: String
29
+ attr_accessor name: String?
30
+ attr_accessor description: String?
31
+ attr_accessor parent_id: String?
32
+ attr_accessor created_at: untyped
33
+ attr_accessor updated_at: untyped
34
+
35
+ def items: () -> Array[ConfigItem]
36
+ def environments: () -> Hash[String, ConfigEnvironment]
37
+ def set_string: (String, String, ?environment: String?, ?description: String?) -> Config
38
+ def set_number: (String, (Integer | Float), ?environment: String?, ?description: String?) -> Config
39
+ def set_boolean: (String, bool, ?environment: String?, ?description: String?) -> Config
40
+ def set_json: (String, untyped, ?environment: String?, ?description: String?) -> Config
41
+ def remove_item: (String, ?environment: String?) -> Config
42
+ def save: () -> Config
43
+ alias save! save
44
+ def delete: () -> void
45
+ alias delete! delete
46
+ end
47
+
48
+ class ConfigChangeEvent
49
+ attr_reader key: String
50
+ attr_reader source: String
51
+ attr_reader deleted: bool
52
+ def deleted?: () -> bool
53
+ end
54
+
55
+ class LiveConfigProxy
56
+ def get: (String?, ?untyped) -> untyped
57
+ def []: (String) -> untyped
58
+ def to_h: () -> Hash[String, untyped]
59
+ def refresh: () -> LiveConfigProxy
60
+ end
61
+
62
+ class ConfigClient
63
+ def start: () -> void
64
+ def get: (String, ?untyped?) -> untyped
65
+ def get_string: (String, ?default: String?, ?config: String?) -> String?
66
+ def get_number: (String, ?default: untyped, ?config: String?) -> untyped
67
+ def get_boolean: (String, ?default: bool?, ?config: String?) -> bool
68
+ def get_json: (String, ?default: untyped, ?config: String?) -> untyped
69
+ def live: (String) -> LiveConfigProxy
70
+ def on_change: (?String?) { (ConfigChangeEvent) -> void } -> Proc
71
+ def refresh: () -> void
72
+ end
73
+ end
74
+
75
+ ConfigItem: singleton(Config::ConfigItem)
76
+ ConfigEnvironment: singleton(Config::ConfigEnvironment)
77
+ ItemType: singleton(Config::ItemType)
78
+ end
@@ -0,0 +1,93 @@
1
+ module Smplkit
2
+ module Flags
3
+ class FlagValue
4
+ attr_reader name: String
5
+ attr_reader value: untyped
6
+ def self.new: (name: String, value: untyped) -> FlagValue
7
+ end
8
+
9
+ class FlagRule
10
+ attr_reader logic: Hash[String, untyped]
11
+ attr_reader value: untyped
12
+ attr_reader description: String?
13
+ def self.new: (logic: Hash[String, untyped], ?value: untyped, ?description: String?) -> FlagRule
14
+ end
15
+
16
+ class FlagEnvironment
17
+ attr_reader enabled: bool
18
+ attr_reader default: untyped
19
+ attr_reader rules: Array[FlagRule]
20
+ def enabled?: () -> bool
21
+ def with: (**untyped) -> FlagEnvironment
22
+ end
23
+
24
+ class Flag
25
+ attr_accessor id: String?
26
+ attr_accessor name: String
27
+ attr_accessor type: String
28
+ attr_accessor default: untyped
29
+ attr_accessor description: String?
30
+ attr_accessor created_at: untyped
31
+ attr_accessor updated_at: untyped
32
+
33
+ def values: () -> Array[FlagValue]?
34
+ def environments: () -> Hash[String, FlagEnvironment]
35
+ def add_rule: (Hash[String, untyped]) -> Flag
36
+ def enable_rules: (?environment: String?) -> Flag
37
+ def disable_rules: (?environment: String?) -> Flag
38
+ def clear_rules: (?environment: String?) -> Flag
39
+ def set_default: (untyped, environment: String) -> Flag
40
+ def clear_default: (environment: String) -> Flag
41
+ def add_value: (FlagValue) -> Flag
42
+ def remove_value: (String) -> Flag
43
+ def clear_values: () -> Flag
44
+ def save: () -> Flag
45
+ alias save! save
46
+ def delete: () -> void
47
+ alias delete! delete
48
+ end
49
+
50
+ class BooleanFlag < Flag
51
+ def get: (?context: Array[Smplkit::Context]?) -> bool
52
+ end
53
+
54
+ class StringFlag < Flag
55
+ def get: (?context: Array[Smplkit::Context]?) -> String
56
+ end
57
+
58
+ class NumberFlag < Flag
59
+ def get: (?context: Array[Smplkit::Context]?) -> (Integer | Float)
60
+ end
61
+
62
+ class JsonFlag < Flag
63
+ def get: (?context: Array[Smplkit::Context]?) -> untyped
64
+ end
65
+
66
+ class FlagChangeEvent
67
+ attr_reader id: String
68
+ attr_reader source: String
69
+ attr_reader deleted: bool
70
+ def deleted?: () -> bool
71
+ end
72
+
73
+ class FlagStats
74
+ attr_reader cache_hits: Integer
75
+ attr_reader cache_misses: Integer
76
+ end
77
+
78
+ class FlagsClient
79
+ def boolean_flag: (String, default: bool) -> BooleanFlag
80
+ def string_flag: (String, default: String) -> StringFlag
81
+ def number_flag: (String, default: (Integer | Float)) -> NumberFlag
82
+ def json_flag: (String, default: untyped) -> JsonFlag
83
+ def start: () -> void
84
+ def refresh: () -> void
85
+ def stats: () -> FlagStats
86
+ def on_change: (?String?) { (FlagChangeEvent) -> void } -> Proc
87
+ end
88
+ end
89
+
90
+ FlagValue: singleton(Flags::FlagValue)
91
+ FlagRule: singleton(Flags::FlagRule)
92
+ FlagEnvironment: singleton(Flags::FlagEnvironment)
93
+ end
@@ -0,0 +1,92 @@
1
+ module Smplkit
2
+ module Logging
3
+ class LoggerSource
4
+ attr_reader name: String
5
+ attr_reader resolved_level: Smplkit::LogLevel
6
+ attr_reader level: Smplkit::LogLevel?
7
+ attr_reader service: String?
8
+ attr_reader environment: String?
9
+ def self.new: (name: String, resolved_level: Smplkit::LogLevel,
10
+ ?level: Smplkit::LogLevel?, ?service: String?,
11
+ ?environment: String?) -> LoggerSource
12
+ end
13
+
14
+ class SmplLogger
15
+ attr_accessor id: String?
16
+ attr_accessor name: String
17
+ attr_accessor resolved_level: Smplkit::LogLevel?
18
+ attr_accessor level: Smplkit::LogLevel?
19
+ attr_accessor service: String?
20
+ attr_accessor environment: String?
21
+ attr_accessor log_group_id: String?
22
+ attr_accessor managed: bool
23
+ attr_accessor description: String?
24
+ attr_accessor created_at: untyped
25
+ attr_accessor updated_at: untyped
26
+ def managed?: () -> bool
27
+ def save: () -> SmplLogger
28
+ alias save! save
29
+ def delete: () -> void
30
+ alias delete! delete
31
+ end
32
+
33
+ class SmplLogGroup
34
+ attr_accessor id: String?
35
+ attr_accessor key: String
36
+ attr_accessor name: String?
37
+ attr_accessor level: Smplkit::LogLevel?
38
+ attr_accessor description: String?
39
+ attr_accessor parent_id: String?
40
+ attr_accessor environments: Hash[String, untyped]
41
+ def save: () -> SmplLogGroup
42
+ alias save! save
43
+ def delete: () -> void
44
+ alias delete! delete
45
+ end
46
+
47
+ class LoggingClient
48
+ def install: () -> LoggingClient
49
+ alias start install
50
+ def register_adapter: (Adapters::Base) -> LoggingClient
51
+ def adapters: () -> Array[Adapters::Base]
52
+ def get: (String) -> SmplLogger
53
+ def list: () -> Array[SmplLogger]
54
+ def delete: (String) -> bool
55
+ def on_change: (?String?) { (untyped) -> void } -> Proc
56
+ end
57
+
58
+ module Adapters
59
+ class Base
60
+ def name: () -> String
61
+ def discover: () -> Array[[String, Smplkit::LogLevel?, Smplkit::LogLevel]]
62
+ def apply_level: (String, Smplkit::LogLevel) -> void
63
+ def install_hook: () { (String, Smplkit::LogLevel?, Smplkit::LogLevel) -> void } -> void
64
+ def uninstall_hook: () -> void
65
+ end
66
+
67
+ class StdlibLoggerAdapter < Base
68
+ def track: (String, untyped) -> void
69
+ end
70
+
71
+ class SemanticLoggerAdapter < Base
72
+ def track: (String, untyped) -> void
73
+ end
74
+ end
75
+
76
+ module Levels
77
+ def self.smpl_level_to_stdlib: (Smplkit::LogLevel) -> Integer
78
+ def self.stdlib_level_to_smpl: (Integer?) -> Smplkit::LogLevel
79
+ def self.semantic_level_to_smpl: (Symbol?) -> Smplkit::LogLevel
80
+ def self.smpl_level_to_semantic: (Smplkit::LogLevel) -> Symbol
81
+ end
82
+
83
+ module Normalize
84
+ def self.normalize_logger_name: (String) -> String
85
+ end
86
+ end
87
+
88
+ LoggerSource: singleton(Logging::LoggerSource)
89
+ StdlibLoggerAdapter: singleton(Logging::Adapters::StdlibLoggerAdapter)
90
+ SemanticLoggerAdapter: singleton(Logging::Adapters::SemanticLoggerAdapter)
91
+ LoggingAdapter: singleton(Logging::Adapters::Base)
92
+ end
@@ -0,0 +1,123 @@
1
+ module Smplkit
2
+ module Management
3
+ module EnvironmentClassification
4
+ STANDARD: String
5
+ AD_HOC: String
6
+ ALL: Array[String]
7
+ end
8
+
9
+ class Color
10
+ attr_reader hex: String
11
+ def initialize: (String) -> void
12
+ def self.rgb: (Integer, Integer, Integer) -> Color
13
+ end
14
+
15
+ class Environment
16
+ attr_accessor id: String?
17
+ attr_accessor key: String
18
+ attr_accessor name: String?
19
+ attr_accessor color: Color?
20
+ attr_accessor classification: String
21
+ attr_accessor description: String?
22
+ attr_accessor created_at: untyped
23
+ attr_accessor updated_at: untyped
24
+ def save: () -> Environment
25
+ alias save! save
26
+ def delete: () -> void
27
+ alias delete! delete
28
+ end
29
+
30
+ class ContextType
31
+ attr_accessor id: String?
32
+ attr_accessor key: String
33
+ attr_accessor name: String?
34
+ attr_accessor description: String?
35
+ def save: () -> ContextType
36
+ alias save! save
37
+ def delete: () -> void
38
+ alias delete! delete
39
+ end
40
+
41
+ class AccountSettings
42
+ attr_accessor id: String?
43
+ attr_accessor environment_order: Array[String]
44
+ attr_accessor default_environment: String?
45
+ attr_accessor updated_at: untyped
46
+ def save: () -> AccountSettings
47
+ alias save! save
48
+ end
49
+ end
50
+
51
+ Color: singleton(Management::Color)
52
+ EnvironmentClassification: singleton(Management::EnvironmentClassification)
53
+
54
+ class ManagementClient
55
+ class ContextsNamespace
56
+ def register: (Array[Smplkit::Context]?) -> void
57
+ def flush: () -> void
58
+ def list: () -> Array[Smplkit::Context]
59
+ def get: (String, ?String?) -> Smplkit::Context
60
+ def delete: (String, ?String?) -> bool
61
+ end
62
+
63
+ class ContextTypesNamespace
64
+ def list: () -> Array[Management::ContextType]
65
+ def get: (String) -> Management::ContextType
66
+ def delete: (String) -> bool
67
+ def new_context_type: (String, ?name: String?, ?description: String?) -> Management::ContextType
68
+ end
69
+
70
+ class EnvironmentsNamespace
71
+ def list: () -> Array[Management::Environment]
72
+ def get: (String) -> Management::Environment
73
+ def delete: (String) -> bool
74
+ def new: (String, ?name: String?, ?color: (String | Management::Color)?,
75
+ ?classification: String, ?description: String?) -> Management::Environment
76
+ end
77
+
78
+ class AccountSettingsNamespace
79
+ def get: () -> Management::AccountSettings
80
+ end
81
+
82
+ class ConfigNamespace
83
+ def list: () -> Array[Smplkit::Config::Config]
84
+ def get: (String) -> Smplkit::Config::Config
85
+ def delete: (String) -> bool
86
+ def new_config: (String, ?name: String?, ?description: String?,
87
+ ?parent: (String | Smplkit::Config::Config)?) -> Smplkit::Config::Config
88
+ def fetch_chain: (String) -> Array[Hash[String, untyped]]
89
+ end
90
+
91
+ class FlagsNamespace
92
+ def register: (Smplkit::FlagDeclaration) -> void
93
+ def flush: () -> void
94
+ def list: () -> Array[Smplkit::Flags::Flag]
95
+ def get: (String) -> Smplkit::Flags::Flag
96
+ def delete: (String) -> bool
97
+ def new_boolean_flag: (String, default: bool, ?name: String?,
98
+ ?description: String?, ?values: Array[Smplkit::Flags::FlagValue]?) -> Smplkit::Flags::BooleanFlag
99
+ def new_string_flag: (String, default: String, ?name: String?,
100
+ ?description: String?, ?values: Array[Smplkit::Flags::FlagValue]?) -> Smplkit::Flags::StringFlag
101
+ def new_number_flag: (String, default: (Integer | Float), ?name: String?,
102
+ ?description: String?, ?values: Array[Smplkit::Flags::FlagValue]?) -> Smplkit::Flags::NumberFlag
103
+ def new_json_flag: (String, default: untyped, ?name: String?,
104
+ ?description: String?, ?values: Array[Smplkit::Flags::FlagValue]?) -> Smplkit::Flags::JsonFlag
105
+ end
106
+
107
+ class LoggersNamespace
108
+ def register: (Smplkit::LoggerSource | Array[Smplkit::LoggerSource]) -> void
109
+ def flush: () -> void
110
+ def list: () -> Array[Smplkit::Logging::SmplLogger]
111
+ def get: (String) -> Smplkit::Logging::SmplLogger
112
+ def delete: (String) -> bool
113
+ end
114
+
115
+ class LogGroupsNamespace
116
+ def list: () -> Array[Smplkit::Logging::SmplLogGroup]
117
+ def get: (String) -> Smplkit::Logging::SmplLogGroup
118
+ def delete: (String) -> bool
119
+ def new_log_group: (String, ?name: String?, ?level: untyped, ?description: String?,
120
+ ?parent: (String | Smplkit::Logging::SmplLogGroup)?) -> Smplkit::Logging::SmplLogGroup
121
+ end
122
+ end
123
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smplkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.13
4
+ version: 1.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Smpl Solutions LLC
@@ -13,44 +13,62 @@ dependencies:
13
13
  name: async
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '2.6'
19
+ - - "<"
17
20
  - !ruby/object:Gem::Version
18
- version: '2.39'
21
+ version: '3'
19
22
  type: :runtime
20
23
  prerelease: false
21
24
  version_requirements: !ruby/object:Gem::Requirement
22
25
  requirements:
23
- - - "~>"
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '2.6'
29
+ - - "<"
24
30
  - !ruby/object:Gem::Version
25
- version: '2.39'
31
+ version: '3'
26
32
  - !ruby/object:Gem::Dependency
27
33
  name: async-http
28
34
  requirement: !ruby/object:Gem::Requirement
29
35
  requirements:
30
- - - "~>"
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0.79'
39
+ - - "<"
31
40
  - !ruby/object:Gem::Version
32
- version: '0.95'
41
+ version: '1'
33
42
  type: :runtime
34
43
  prerelease: false
35
44
  version_requirements: !ruby/object:Gem::Requirement
36
45
  requirements:
37
- - - "~>"
46
+ - - ">="
38
47
  - !ruby/object:Gem::Version
39
- version: '0.95'
48
+ version: '0.79'
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '1'
40
52
  - !ruby/object:Gem::Dependency
41
53
  name: async-websocket
42
54
  requirement: !ruby/object:Gem::Requirement
43
55
  requirements:
44
- - - "~>"
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0.26'
59
+ - - "<"
45
60
  - !ruby/object:Gem::Version
46
- version: '0.30'
61
+ version: '1'
47
62
  type: :runtime
48
63
  prerelease: false
49
64
  version_requirements: !ruby/object:Gem::Requirement
50
65
  requirements:
51
- - - "~>"
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0.26'
69
+ - - "<"
52
70
  - !ruby/object:Gem::Version
53
- version: '0.30'
71
+ version: '1'
54
72
  - !ruby/object:Gem::Dependency
55
73
  name: concurrent-ruby
56
74
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +125,20 @@ dependencies:
107
125
  - - "~>"
108
126
  - !ruby/object:Gem::Version
109
127
  version: '0.0'
128
+ - !ruby/object:Gem::Dependency
129
+ name: marcel
130
+ requirement: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - "~>"
133
+ - !ruby/object:Gem::Version
134
+ version: '1.0'
135
+ type: :runtime
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - "~>"
140
+ - !ruby/object:Gem::Version
141
+ version: '1.0'
110
142
  description: Ruby SDK for the smplkit platform — flags, config, and logging APIs with
111
143
  runtime evaluation, live updates, and management operations.
112
144
  email:
@@ -536,6 +568,10 @@ files:
536
568
  - lib/smplkit/version.rb
537
569
  - lib/smplkit/ws.rb
538
570
  - sig/smplkit.rbs
571
+ - sig/smplkit/config.rbs
572
+ - sig/smplkit/flags.rbs
573
+ - sig/smplkit/logging.rbs
574
+ - sig/smplkit/management.rbs
539
575
  homepage: https://www.smplkit.com
540
576
  licenses:
541
577
  - MIT
@@ -552,7 +588,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
552
588
  requirements:
553
589
  - - ">="
554
590
  - !ruby/object:Gem::Version
555
- version: '3.3'
591
+ version: '3.1'
556
592
  required_rubygems_version: !ruby/object:Gem::Requirement
557
593
  requirements:
558
594
  - - ">="