takagi 0.1.0 → 1.1.0

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.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +70 -7
  3. data/.yard/templates/default/layout/html/layout.erb +34 -0
  4. data/AGENTS.md +16 -0
  5. data/CHANGELOG.md +158 -1
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +590 -23
  8. data/ROADMAP.md +55 -0
  9. data/Rakefile +4 -4
  10. data/Steepfile +39 -0
  11. data/bin/takagi-dev +159 -0
  12. data/docs/FIRST_PLUGIN_GUIDE.md +224 -0
  13. data/docs/HOOKS.md +31 -0
  14. data/examples/client_lifecycle_example.rb +118 -0
  15. data/examples/cloud_gateway_app.rb +217 -0
  16. data/examples/nested_api_app.rb +258 -0
  17. data/examples/simple_device_app.rb +71 -0
  18. data/examples/takagi.yml +138 -0
  19. data/lib/takagi/application.rb +256 -0
  20. data/lib/takagi/base/middleware_management.rb +39 -0
  21. data/lib/takagi/base/plugin_management.rb +75 -0
  22. data/lib/takagi/base/reactor_management.rb +104 -0
  23. data/lib/takagi/base/server_lifecycle.rb +156 -0
  24. data/lib/takagi/base.rb +103 -11
  25. data/lib/takagi/branding.rb +88 -0
  26. data/lib/takagi/cbor/decoder.rb +385 -0
  27. data/lib/takagi/cbor/encoder.rb +260 -0
  28. data/lib/takagi/cbor/error.rb +17 -0
  29. data/lib/takagi/cbor/version.rb +9 -0
  30. data/lib/takagi/client/response.rb +236 -0
  31. data/lib/takagi/client.rb +265 -0
  32. data/lib/takagi/client_base.rb +204 -0
  33. data/lib/takagi/coap/code_helpers.rb +190 -0
  34. data/lib/takagi/coap/registries/base.rb +165 -0
  35. data/lib/takagi/coap/registries/content_format.rb +71 -0
  36. data/lib/takagi/coap/registries/message_type.rb +69 -0
  37. data/lib/takagi/coap/registries/method.rb +38 -0
  38. data/lib/takagi/coap/registries/option.rb +71 -0
  39. data/lib/takagi/coap/registries/response.rb +93 -0
  40. data/lib/takagi/coap/registries/signaling.rb +34 -0
  41. data/lib/takagi/coap/signaling.rb +10 -0
  42. data/lib/takagi/coap.rb +37 -0
  43. data/lib/takagi/composite_router.rb +186 -0
  44. data/lib/takagi/config.rb +337 -0
  45. data/lib/takagi/controller/resource_allocator.rb +164 -0
  46. data/lib/takagi/controller/thread_pool.rb +144 -0
  47. data/lib/takagi/controller.rb +319 -0
  48. data/lib/takagi/core/attribute_set.rb +128 -0
  49. data/lib/takagi/discovery/core_link_format.rb +137 -0
  50. data/lib/takagi/errors.rb +536 -0
  51. data/lib/takagi/event_bus/address_prefix.rb +142 -0
  52. data/lib/takagi/event_bus/async_executor.rb +235 -0
  53. data/lib/takagi/event_bus/coap_bridge.rb +208 -0
  54. data/lib/takagi/event_bus/future.rb +153 -0
  55. data/lib/takagi/event_bus/lru_cache.rb +157 -0
  56. data/lib/takagi/event_bus/message_buffer.rb +237 -0
  57. data/lib/takagi/event_bus/observer_cleanup.rb +110 -0
  58. data/lib/takagi/event_bus/scope.rb +74 -0
  59. data/lib/takagi/event_bus.rb +594 -0
  60. data/lib/takagi/helpers.rb +88 -0
  61. data/lib/takagi/hooks.rb +82 -0
  62. data/lib/takagi/initializer.rb +18 -0
  63. data/lib/takagi/logger.rb +15 -6
  64. data/lib/takagi/message/base.rb +155 -0
  65. data/lib/takagi/message/deduplication_cache.rb +84 -0
  66. data/lib/takagi/message/inbound.rb +147 -0
  67. data/lib/takagi/message/outbound.rb +223 -0
  68. data/lib/takagi/message/request.rb +158 -0
  69. data/lib/takagi/message/retransmission_manager.rb +193 -0
  70. data/lib/takagi/middleware/authentication.rb +19 -0
  71. data/lib/takagi/middleware/caching.rb +23 -0
  72. data/lib/takagi/middleware/debugging.rb +16 -0
  73. data/lib/takagi/middleware/logging.rb +14 -0
  74. data/lib/takagi/middleware/metrics.rb +440 -0
  75. data/lib/takagi/middleware/rate_limiting.rb +24 -0
  76. data/lib/takagi/middleware_stack.rb +166 -0
  77. data/lib/takagi/network/base.rb +76 -0
  78. data/lib/takagi/network/framing/tcp.rb +222 -0
  79. data/lib/takagi/network/framing/udp.rb +110 -0
  80. data/lib/takagi/network/registry.rb +72 -0
  81. data/lib/takagi/network/tcp.rb +60 -0
  82. data/lib/takagi/network/tcp_sender.rb +21 -0
  83. data/lib/takagi/network/udp.rb +61 -0
  84. data/lib/takagi/network/udp_sender.rb +20 -0
  85. data/lib/takagi/observable/emitter.rb +62 -0
  86. data/lib/takagi/observable/reactor.rb +488 -0
  87. data/lib/takagi/observable/registry.rb +122 -0
  88. data/lib/takagi/observe_registry.rb +10 -0
  89. data/lib/takagi/observer/client.rb +68 -0
  90. data/lib/takagi/observer/registry.rb +137 -0
  91. data/lib/takagi/observer/sender.rb +39 -0
  92. data/lib/takagi/observer/watcher.rb +43 -0
  93. data/lib/takagi/plugin.rb +313 -0
  94. data/lib/takagi/profiles.rb +176 -0
  95. data/lib/takagi/reactor.rb +23 -0
  96. data/lib/takagi/reactor_registry.rb +64 -0
  97. data/lib/takagi/registry/base.rb +268 -0
  98. data/lib/takagi/response_builder.rb +141 -0
  99. data/lib/takagi/router/metadata_extractor.rb +133 -0
  100. data/lib/takagi/router/route_matcher.rb +83 -0
  101. data/lib/takagi/router.rb +284 -25
  102. data/lib/takagi/serialization/base.rb +102 -0
  103. data/lib/takagi/serialization/cbor_serializer.rb +92 -0
  104. data/lib/takagi/serialization/json_serializer.rb +96 -0
  105. data/lib/takagi/serialization/octet_stream_serializer.rb +82 -0
  106. data/lib/takagi/serialization/registry.rb +187 -0
  107. data/lib/takagi/serialization/text_serializer.rb +87 -0
  108. data/lib/takagi/serialization.rb +117 -0
  109. data/lib/takagi/server/multi.rb +41 -0
  110. data/lib/takagi/server/registry.rb +71 -0
  111. data/lib/takagi/server/tcp.rb +249 -0
  112. data/lib/takagi/server/udp.rb +139 -0
  113. data/lib/takagi/server/udp_worker.rb +174 -0
  114. data/lib/takagi/server.rb +1 -31
  115. data/lib/takagi/server_registry.rb +10 -0
  116. data/lib/takagi/tcp_client.rb +142 -0
  117. data/lib/takagi/version.rb +2 -1
  118. data/lib/takagi.rb +24 -3
  119. data/sig/takagi/application.rbs +48 -0
  120. data/sig/takagi/base/middleware_management.rbs +33 -0
  121. data/sig/takagi/base/reactor_management.rbs +52 -0
  122. data/sig/takagi/base/server_lifecycle.rbs +54 -0
  123. data/sig/takagi/base.rbs +48 -0
  124. data/sig/takagi/cbor/decoder.rbs +171 -0
  125. data/sig/takagi/cbor/encoder.rbs +146 -0
  126. data/sig/takagi/cbor/error.rbs +19 -0
  127. data/sig/takagi/cbor/version.rbs +7 -0
  128. data/sig/takagi/client/response.rbs +148 -0
  129. data/sig/takagi/client.rbs +119 -0
  130. data/sig/takagi/client_base.rbs +135 -0
  131. data/sig/takagi/coap/code_helpers.rbs +91 -0
  132. data/sig/takagi/coap/registries/base.rbs +95 -0
  133. data/sig/takagi/coap/registries/content_format.rbs +47 -0
  134. data/sig/takagi/coap/registries/message_type.rbs +53 -0
  135. data/sig/takagi/coap/registries/method.rbs +27 -0
  136. data/sig/takagi/coap/registries/option.rbs +43 -0
  137. data/sig/takagi/coap/registries/response.rbs +52 -0
  138. data/sig/takagi/coap.rbs +24 -0
  139. data/sig/takagi/composite_router.rbs +46 -0
  140. data/sig/takagi/config.rbs +134 -0
  141. data/sig/takagi/controller.rbs +73 -0
  142. data/sig/takagi/core/attribute_set.rbs +57 -0
  143. data/sig/takagi/discovery/core_link_format.rbs +50 -0
  144. data/sig/takagi/event_bus/address_prefix.rbs +78 -0
  145. data/sig/takagi/event_bus/async_executor.rbs +88 -0
  146. data/sig/takagi/event_bus/coap_bridge.rbs +93 -0
  147. data/sig/takagi/event_bus/future.rbs +78 -0
  148. data/sig/takagi/event_bus/lru_cache.rbs +86 -0
  149. data/sig/takagi/event_bus/message_buffer.rbs +133 -0
  150. data/sig/takagi/event_bus/observer_cleanup.rbs +62 -0
  151. data/sig/takagi/event_bus.rbs +320 -0
  152. data/sig/takagi/helpers.rbs +34 -0
  153. data/sig/takagi/initializer.rbs +9 -0
  154. data/sig/takagi/logger.rbs +17 -0
  155. data/sig/takagi/message/base.rbs +64 -0
  156. data/sig/takagi/message/deduplication_cache.rbs +49 -0
  157. data/sig/takagi/message/inbound.rbs +76 -0
  158. data/sig/takagi/message/outbound.rbs +48 -0
  159. data/sig/takagi/message/request.rbs +32 -0
  160. data/sig/takagi/message/retransmission_manager.rbs +76 -0
  161. data/sig/takagi/middleware/authentication.rbs +11 -0
  162. data/sig/takagi/middleware/caching.rbs +13 -0
  163. data/sig/takagi/middleware/debugging.rbs +9 -0
  164. data/sig/takagi/middleware/logging.rbs +7 -0
  165. data/sig/takagi/middleware/metrics.rbs +15 -0
  166. data/sig/takagi/middleware/rate_limiting.rbs +13 -0
  167. data/sig/takagi/middleware_stack.rbs +69 -0
  168. data/sig/takagi/network/tcp_sender.rbs +10 -0
  169. data/sig/takagi/network/udp_sender.rbs +14 -0
  170. data/sig/takagi/observe_registry.rbs +36 -0
  171. data/sig/takagi/observer/client.rbs +36 -0
  172. data/sig/takagi/observer/sender.rbs +12 -0
  173. data/sig/takagi/observer/watcher.rbs +18 -0
  174. data/sig/takagi/profiles.rbs +33 -0
  175. data/sig/takagi/reactor.rbs +20 -0
  176. data/sig/takagi/reactor_registry.rbs +14 -0
  177. data/sig/takagi/response_builder.rbs +12 -0
  178. data/sig/takagi/router/metadata_extractor.rbs +71 -0
  179. data/sig/takagi/router/route_matcher.rbs +43 -0
  180. data/sig/takagi/router.rbs +166 -0
  181. data/sig/takagi/serialization.rbs +32 -0
  182. data/sig/takagi/server/multi.rbs +16 -0
  183. data/sig/takagi/server/tcp.rbs +42 -0
  184. data/sig/takagi/server/udp.rbs +52 -0
  185. data/sig/takagi/server/udp_worker.rbs +42 -0
  186. data/sig/takagi/server.rbs +4 -0
  187. data/sig/takagi/server_registry.rbs +71 -0
  188. data/sig/takagi/tcp_client.rbs +23 -0
  189. data/sig/takagi/version.rbs +5 -0
  190. data/takagi.gemspec +37 -35
  191. metadata +204 -31
  192. data/.idea/.gitignore +0 -8
  193. data/.idea/misc.xml +0 -4
  194. data/.idea/modules.xml +0 -8
  195. data/.idea/takagi.iml +0 -81
  196. data/.idea/vcs.xml +0 -6
  197. data/lib/takagi/message.rb +0 -75
@@ -0,0 +1,95 @@
1
+ module Takagi
2
+ module CoAP
3
+ module Registries
4
+ # Base class for extensible constant registries.
5
+ #
6
+ # Provides a pattern for registering CoAP protocol constants with:
7
+ # - Numeric value
8
+ # - Human-readable name
9
+ # - Symbol accessor (optional)
10
+ #
11
+ # This allows plugins to extend the protocol without modifying core code.
12
+ #
13
+ # @example Creating a custom registry
14
+ # class MyRegistry < Registries::Base
15
+ # register(1, 'First Value', :first)
16
+ # register(2, 'Second Value', :second)
17
+ # end
18
+ #
19
+ # MyRegistry::FIRST # => 1
20
+ # MyRegistry.name_for(1) # => "First Value"
21
+ # MyRegistry.all # => {1 => "First Value", 2 => "Second Value"}
22
+ class Base
23
+ self.@registry: untyped
24
+
25
+ self.@reverse_registry: untyped
26
+
27
+ # Register a new constant in the registry
28
+ #
29
+ # @param value [Integer] Numeric value of the constant
30
+ # @param name [String] Human-readable name
31
+ # @param symbol [Symbol, nil] Optional symbol for constant access
32
+ # @param rfc [String, nil] Optional RFC reference
33
+ #
34
+ # @example
35
+ # register(69, '2.05 Content', :content, rfc: 'RFC 7252 §5.9.1.4')
36
+ def self.register: (untyped value, untyped name, ?untyped? symbol, ?rfc: untyped?) -> untyped
37
+
38
+ # Get human-readable name for a value
39
+ #
40
+ # @param value [Integer] The numeric value
41
+ # @return [String, nil] The name, or nil if not found
42
+ def self.name_for: (untyped value) -> untyped
43
+
44
+ # Get numeric value for a name or symbol
45
+ #
46
+ # @param key [String, Symbol] The name or symbol
47
+ # @return [Integer, nil] The value, or nil if not found
48
+ def self.value_for: (untyped key) -> untyped
49
+
50
+ # Get RFC reference for a value
51
+ #
52
+ # @param value [Integer] The numeric value
53
+ # @return [String, nil] The RFC reference, or nil if not found
54
+ def self.rfc_for: (untyped value) -> untyped
55
+
56
+ # Check if a value is registered
57
+ #
58
+ # @param value [Integer] The value to check
59
+ # @return [Boolean] true if registered
60
+ def self.registered?: (untyped value) -> untyped
61
+
62
+ # Get all registered constants
63
+ #
64
+ # @return [Hash] Map of value => name
65
+ def self.all: () -> untyped
66
+
67
+ # Iterate over registered values
68
+ #
69
+ # @yield [Integer] each registered numeric value
70
+ # @return [Enumerator] if no block given
71
+ def self.each_value: () ?{ (?) -> untyped } -> untyped
72
+
73
+ # Get all registered values
74
+ #
75
+ # @return [Array<Integer>] Array of all values
76
+ def self.values: () -> untyped
77
+
78
+ # Get registry metadata for a value
79
+ #
80
+ # @param value [Integer] The numeric value
81
+ # @return [Hash, nil] Full metadata hash
82
+ def self.metadata_for: (untyped value) -> untyped
83
+
84
+ # Clear all registrations (useful for testing)
85
+ def self.clear!: () -> untyped
86
+
87
+ private
88
+
89
+ def self.registry: () -> untyped
90
+
91
+ def self.reverse_registry: () -> untyped
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,47 @@
1
+ module Takagi
2
+ module CoAP
3
+ module Registries
4
+ # CoAP Content-Format Registry (RFC 7252 §12.3)
5
+ #
6
+ # Extensible registry for CoAP content-format codes.
7
+ # Plugins can register custom content formats without modifying core code.
8
+ #
9
+ # @example Using predefined formats
10
+ # Takagi::CoAP::Registries::ContentFormat::JSON # => 50
11
+ # Takagi::CoAP::Registries::ContentFormat::TEXT_PLAIN # => 0
12
+ #
13
+ # @example Registering a custom format
14
+ # Takagi::CoAP::Registries::ContentFormat.register(65000, 'application/custom', :custom)
15
+ # Takagi::CoAP::Registries::ContentFormat::CUSTOM # => 65000
16
+ #
17
+ # @example Looking up format names
18
+ # Takagi::CoAP::Registries::ContentFormat.name_for(50) # => "application/json"
19
+ class ContentFormat < Base
20
+ # Get MIME type for a content-format code
21
+ # @param code [Integer] Content-format code
22
+ # @return [String, nil] MIME type
23
+ def self.mime_type_for: (untyped code) -> untyped
24
+
25
+ # Get content-format code for a MIME type
26
+ # @param mime_type [String] MIME type
27
+ # @return [Integer, nil] Content-format code
28
+ def self.code_for_mime: (untyped mime_type) -> untyped
29
+
30
+ # Check if format is JSON-based
31
+ # @param code [Integer] Content-format code
32
+ # @return [Boolean] true if JSON format
33
+ def self.json?: (untyped code) -> untyped
34
+
35
+ # Check if format is CBOR-based
36
+ # @param code [Integer] Content-format code
37
+ # @return [Boolean] true if CBOR format
38
+ def self.cbor?: (untyped code) -> untyped
39
+
40
+ # Check if format is text-based
41
+ # @param code [Integer] Content-format code
42
+ # @return [Boolean] true if text format
43
+ def self.text?: (untyped code) -> untyped
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,53 @@
1
+ module Takagi
2
+ module CoAP
3
+ module Registries
4
+ # CoAP Message Type Registry (RFC 7252 §3)
5
+ #
6
+ # Extensible registry for CoAP message types.
7
+ #
8
+ # @example Using predefined types
9
+ # Takagi::CoAP::Registries::MessageType::CONFIRMABLE # => 0
10
+ # Takagi::CoAP::Registries::MessageType::ACK # => 2
11
+ #
12
+ # @example Looking up type names
13
+ # Takagi::CoAP::Registries::MessageType.name_for(0) # => "Confirmable"
14
+ class MessageType < Base
15
+ # Aliases for convenience
16
+ CON: untyped
17
+
18
+ NON: untyped
19
+
20
+ ACK: untyped
21
+
22
+ RST: untyped
23
+
24
+ # Check if type is confirmable
25
+ # @param type [Integer] Message type
26
+ # @return [Boolean] true if confirmable
27
+ def self.confirmable?: (untyped type) -> untyped
28
+
29
+ # Check if type is non-confirmable
30
+ # @param type [Integer] Message type
31
+ # @return [Boolean] true if non-confirmable
32
+ def self.non_confirmable?: (untyped type) -> untyped
33
+
34
+ # Check if type is acknowledgement
35
+ # @param type [Integer] Message type
36
+ # @return [Boolean] true if acknowledgement
37
+ def self.acknowledgement?: (untyped type) -> untyped
38
+
39
+ alias self.ack? self.acknowledgement?
40
+
41
+ # Check if type is reset
42
+ # @param type [Integer] Message type
43
+ # @return [Boolean] true if reset
44
+ def self.reset?: (untyped type) -> untyped
45
+
46
+ # Check if type is valid
47
+ # @param type [Integer] Message type
48
+ # @return [Boolean] true if valid
49
+ def self.valid?: (untyped type) -> untyped
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ module Takagi
2
+ module CoAP
3
+ module Registries
4
+ # CoAP Method Code Registry (RFC 7252 §12.1.1)
5
+ #
6
+ # Extensible registry for CoAP request method codes.
7
+ # Plugins can register custom methods without modifying core code.
8
+ #
9
+ # @example Using predefined methods
10
+ # Takagi::CoAP::Registries::Method::GET # => 1
11
+ # Takagi::CoAP::Registries::Method::POST # => 2
12
+ #
13
+ # @example Registering a custom method
14
+ # Takagi::CoAP::Registries::Method.register(5, 'FETCH', :fetch, rfc: 'RFC 8132')
15
+ # Takagi::CoAP::Registries::Method::FETCH # => 5
16
+ #
17
+ # @example Looking up method names
18
+ # Takagi::CoAP::Registries::Method.name_for(1) # => "GET"
19
+ class Method < Base
20
+ # Check if code is a valid method code
21
+ # @param code [Integer] Code to check
22
+ # @return [Boolean] true if valid method
23
+ def self.valid?: (untyped code) -> untyped
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,43 @@
1
+ module Takagi
2
+ module CoAP
3
+ module Registries
4
+ # CoAP Option Number Registry (RFC 7252 §5.10)
5
+ #
6
+ # Extensible registry for CoAP option numbers.
7
+ # Plugins can register custom options without modifying core code.
8
+ #
9
+ # @example Using predefined options
10
+ # Takagi::CoAP::Registries::Option::URI_PATH # => 11
11
+ # Takagi::CoAP::Registries::Option::CONTENT_FORMAT # => 12
12
+ #
13
+ # @example Registering a custom option
14
+ # Takagi::CoAP::Registries::Option.register(65000, 'Custom-Option', :custom_option)
15
+ # Takagi::CoAP::Registries::Option::CUSTOM_OPTION # => 65000
16
+ #
17
+ # @example Looking up option names
18
+ # Takagi::CoAP::Registries::Option.name_for(11) # => "Uri-Path"
19
+ class Option < Base
20
+ # Check if an option is critical
21
+ # Critical options must be understood by the recipient
22
+ # @param number [Integer] Option number
23
+ # @return [Boolean] true if critical
24
+ def self.critical?: (untyped number) -> untyped
25
+
26
+ # Check if an option is unsafe to forward
27
+ # @param number [Integer] Option number
28
+ # @return [Boolean] true if unsafe
29
+ def self.unsafe?: (untyped number) -> untyped
30
+
31
+ # Check if an option has NoCacheKey property
32
+ # @param number [Integer] Option number
33
+ # @return [Boolean] true if NoCacheKey
34
+ def self.no_cache_key?: (untyped number) -> untyped
35
+
36
+ # Check if option number is valid
37
+ # @param number [Integer] Option number
38
+ # @return [Boolean] true if valid
39
+ def self.valid?: (untyped number) -> untyped
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,52 @@
1
+ module Takagi
2
+ module CoAP
3
+ module Registries
4
+ # CoAP Response Code Registry (RFC 7252 §12.1.2)
5
+ #
6
+ # Extensible registry for CoAP response codes.
7
+ # Plugins can register custom response codes without modifying core code.
8
+ #
9
+ # @example Using predefined codes
10
+ # Takagi::CoAP::Registries::Response::CONTENT # => 69 (2.05)
11
+ # Takagi::CoAP::Registries::Response::NOT_FOUND # => 132 (4.04)
12
+ #
13
+ # @example Registering a custom code
14
+ # Takagi::CoAP::Registries::Response.register(231, '7.07 Custom', :custom)
15
+ # Takagi::CoAP::Registries::Response::CUSTOM # => 231
16
+ #
17
+ # @example Looking up code names
18
+ # Takagi::CoAP::Registries::Response.name_for(69) # => "2.05 Content"
19
+ class Response < Base
20
+ # Get the response class (2, 4, 5, etc.)
21
+ # @param code [Integer] Response code
22
+ # @return [Integer] Class number
23
+ def self.class_for: (untyped code) -> untyped
24
+
25
+ # Check if code is a success (2.xx)
26
+ # @param code [Integer] Response code
27
+ # @return [Boolean] true if success
28
+ def self.success?: (untyped code) -> untyped
29
+
30
+ # Check if code is a client error (4.xx)
31
+ # @param code [Integer] Response code
32
+ # @return [Boolean] true if client error
33
+ def self.client_error?: (untyped code) -> untyped
34
+
35
+ # Check if code is a server error (5.xx)
36
+ # @param code [Integer] Response code
37
+ # @return [Boolean] true if server error
38
+ def self.server_error?: (untyped code) -> untyped
39
+
40
+ # Check if code is any error (4.xx or 5.xx)
41
+ # @param code [Integer] Response code
42
+ # @return [Boolean] true if error
43
+ def self.error?: (untyped code) -> untyped
44
+
45
+ # Check if code is a valid response code
46
+ # @param code [Integer] Code to check
47
+ # @return [Boolean] true if valid response code
48
+ def self.valid?: (untyped code) -> untyped
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ module Takagi
2
+ # CoAP Protocol implementation following RFC 7252 and related RFCs.
3
+ #
4
+ # This module provides a registry-based system for CoAP protocol constants,
5
+ # allowing plugins and extensions to register additional constants without
6
+ # modifying core code.
7
+ #
8
+ # @example Registering a custom response code
9
+ # Takagi::CoAP::Registries::Response.register(231, '7.01 Custom Code', :custom_code)
10
+ #
11
+ # @example Using registered constants
12
+ # code = Takagi::CoAP::Registries::Response::CONTENT # => 69
13
+ # Takagi::CoAP::Registries::Response.name_for(69) # => "2.05 Content"
14
+ module CoAP
15
+ # Default CoAP port (RFC 7252 §6.1)
16
+ DEFAULT_PORT: 5683
17
+
18
+ # Default CoAPS (secure) port (RFC 7252 §6.2)
19
+ DEFAULT_SECURE_PORT: 5684
20
+
21
+ # CoAP version (RFC 7252 §3)
22
+ VERSION: 1
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+ # Takagi::CompositeRouter - Routes requests to mounted controllers
2
+ module Takagi
3
+ class CompositeRouter
4
+ # Represents a mounted controller
5
+ class MountedController < Struct[untyped]
6
+ attr_accessor controller_class: singleton(Controller)
7
+ attr_accessor mount_path: String
8
+ attr_accessor router: Router
9
+ attr_accessor nested_controllers: Array[singleton(Controller)]
10
+
11
+ # Check if this mount handles the given path
12
+ def handles?: (String path) -> bool
13
+
14
+ # Strip mount prefix from path
15
+ def relative_path: (String path) -> String
16
+ end
17
+
18
+ def initialize: () -> void
19
+
20
+ # Mount a controller at a path
21
+ def mount: (singleton(Controller) controller_class, ?at: String?) -> void
22
+
23
+ # Find a route handler
24
+ def find_route: (String method, String path) -> [Proc?, Hash[Symbol, String]]
25
+
26
+ # Get all routes from all controllers
27
+ def all_routes: () -> Array[String]
28
+
29
+ # Get link format entries from all controllers
30
+ def link_format_entries: () -> Array[Router::RouteEntry]
31
+
32
+ # Get all mounted controllers
33
+ def mounted_controllers: () -> Array[MountedController]
34
+
35
+ private
36
+
37
+ # Find the mounted controller for a path
38
+ def find_mounted_controller: (String path) -> MountedController?
39
+
40
+ # Recursively mount nested controllers
41
+ def mount_nested_controllers: (MountedController parent) -> void
42
+
43
+ attr_reader mounted: Array[MountedController]
44
+ attr_reader logger: Logger
45
+ end
46
+ end
@@ -0,0 +1,134 @@
1
+ module Takagi
2
+ # Stores runtime configuration loaded from YAML or manual overrides.
3
+ class Config
4
+ @custom: untyped
5
+
6
+ @server_name: untyped
7
+
8
+ @logger: untyped
9
+
10
+ @port: untyped
11
+
12
+ @bind_address: untyped
13
+
14
+ @auto_migrate: untyped
15
+
16
+ @threads: untyped
17
+
18
+ @processes: untyped
19
+
20
+ @protocols: untyped
21
+
22
+ @observability: untyped
23
+
24
+ @event_bus: untyped
25
+
26
+ @router: untyped
27
+
28
+ @middleware: untyped
29
+
30
+ Observability: untyped
31
+
32
+ EventBusConfig: untyped
33
+
34
+ RouterConfig: untyped
35
+
36
+ MiddlewareConfig: untyped
37
+
38
+ attr_accessor port: untyped
39
+
40
+ attr_accessor bind_address: untyped
41
+
42
+ attr_accessor logger: untyped
43
+
44
+ attr_accessor observability: untyped
45
+
46
+ attr_accessor auto_migrate: untyped
47
+
48
+ attr_accessor custom: untyped
49
+
50
+ attr_accessor processes: untyped
51
+
52
+ attr_accessor threads: untyped
53
+
54
+ attr_accessor protocols: untyped
55
+
56
+ attr_accessor server_name: untyped
57
+
58
+ attr_accessor event_bus: untyped
59
+
60
+ attr_accessor router: untyped
61
+
62
+ attr_accessor middleware: untyped
63
+
64
+ def initialize: () -> void
65
+
66
+ def []: (untyped key) -> untyped
67
+
68
+ def []=: (untyped key, untyped value) -> untyped
69
+
70
+ def method_missing: (untyped name, *untyped args) { (?) -> untyped } -> untyped
71
+
72
+ def respond_to_missing?: (untyped name, ?bool include_private) -> untyped
73
+
74
+ def load_file: (untyped path) -> untyped
75
+
76
+ private
77
+
78
+ def apply_basic_settings: (untyped data) -> untyped
79
+
80
+ def apply_logger: (untyped data) -> (nil | untyped)
81
+
82
+ def apply_observability: (untyped data) -> (nil | untyped)
83
+
84
+ def apply_event_bus: (untyped data) -> (nil | untyped)
85
+
86
+ def apply_router: (untyped data) -> (nil | untyped)
87
+
88
+ def apply_middleware: (untyped data) -> (nil | untyped)
89
+
90
+ def apply_custom_settings: (untyped data) -> untyped
91
+
92
+ def load_yaml: (untyped path) -> untyped
93
+
94
+ def resolve_logger_output: (untyped target) -> untyped
95
+
96
+ def resolve_logger_level: (untyped level) -> untyped
97
+
98
+ def set_server_defaults: () -> untyped
99
+
100
+ def set_observability_defaults: () -> untyped
101
+
102
+ def set_event_bus_defaults: () -> untyped
103
+
104
+ def set_router_defaults: () -> untyped
105
+
106
+ def set_middleware_defaults: () -> untyped
107
+
108
+ def assign_setting: (untyped data, untyped key) { (untyped) -> untyped } -> (nil | untyped)
109
+
110
+ def assign_processes: (untyped data) -> (nil | untyped)
111
+
112
+ def assign_protocols: (untyped protocols) -> (nil | untyped)
113
+
114
+ def assign_event_bus_core: (untyped event_bus_data) -> untyped
115
+
116
+ def assign_message_buffer_settings: (untyped event_bus_data) -> untyped
117
+
118
+ def assign_event_bus_setting: (untyped event_bus_data, untyped key) -> (nil | untyped)
119
+
120
+ # Parse middleware entry from YAML config
121
+ # Supports both simple strings and hash with options
122
+ #
123
+ # @example Simple string
124
+ # "Logging"
125
+ #
126
+ # @example Hash with options
127
+ # { name: "Caching", options: { ttl: 300 } }
128
+ def parse_middleware_entry: (untyped entry) -> untyped
129
+
130
+ # Default middleware stack
131
+ # Returns an array of middleware configurations
132
+ def default_middleware_stack: () -> ::Array[{ name: "Debugging", options: ::Hash[untyped, untyped] }]
133
+ end
134
+ end
@@ -0,0 +1,73 @@
1
+ # Takagi::Controller - Base class for modular controllers
2
+ module Takagi
3
+ class Controller
4
+ # Controller configuration hash
5
+ type config_hash = {
6
+ mount_path: String?,
7
+ nested_from: singleton(Controller)?,
8
+ nested_controllers: Array[singleton(Controller)],
9
+ profile: Symbol?,
10
+ processes: Integer?,
11
+ threads: Integer?
12
+ }
13
+
14
+ # Get the controller's isolated router
15
+ def self.router: () -> Router
16
+
17
+ # Get the controller's configuration
18
+ def self.config: () -> config_hash
19
+
20
+ # Configure the controller
21
+ def self.configure: () { (ConfigContext) -> void } -> void
22
+
23
+ # Register a route
24
+ def self.add_route: (String method, String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
25
+
26
+ # HTTP/CoAP method shortcuts (get, post, put, delete, etc.)
27
+ def self.get: (String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
28
+ def self.post: (String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
29
+ def self.put: (String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
30
+ def self.delete: (String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
31
+ def self.patch: (String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
32
+ def self.fetch: (String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
33
+ def self.ipatch: (String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
34
+
35
+ # Observable route registration
36
+ def self.observable: (String path, ?metadata: Hash[Symbol, untyped]) { (Message::Inbound, Hash[Symbol, String]) -> untyped } -> void
37
+
38
+ # Get the full mount path
39
+ def self.mount_path: () -> String?
40
+
41
+ # Check if mounted
42
+ def self.mounted?: () -> bool
43
+
44
+ # Get nested controllers
45
+ def self.nested_controllers: () -> Array[singleton(Controller)]
46
+
47
+ # Get profile name
48
+ def self.profile_name: () -> Symbol?
49
+
50
+ # Get effective process count
51
+ def self.process_count: () -> Integer?
52
+
53
+ # Get effective thread count
54
+ def self.thread_count: () -> Integer?
55
+
56
+ # Configuration DSL context
57
+ class ConfigContext
58
+ def initialize: (singleton(Controller) controller_class) -> void
59
+
60
+ # Set mount path
61
+ def mount: (String path, ?nested_from: singleton(Controller)?) -> void
62
+
63
+ # Nest child controllers
64
+ def nest: (*singleton(Controller) controllers) -> void
65
+
66
+ # Set load profile
67
+ def profile: (Symbol name) -> void
68
+
69
+ # Set configuration value
70
+ def set: (Symbol key, untyped value) -> void
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,57 @@
1
+ module Takagi
2
+ module Core
3
+ # Encapsulates CoRE Link Format attribute handling for a single route.
4
+ # The DSL is shared between request-time handlers and boot-time helpers,
5
+ # so changes applied here are idempotent and safe to call repeatedly.
6
+ class AttributeSet
7
+ @metadata: untyped
8
+
9
+ @overrides: untyped
10
+
11
+ CONTENT_FORMATS: { "text/plain" => 0, "application/link-format" => 40, "application/xml" => 41, "application/octet-stream" => 42, "application/exi" => 47, "application/json" => 50, "application/cbor" => 60 }
12
+
13
+ REMOVE: untyped
14
+
15
+ attr_reader metadata: untyped
16
+
17
+ def initialize: (untyped metadata) -> void
18
+
19
+ # Evaluates a block that configures any mix of CoRE attributes.
20
+ # Accepts the same DSL as the runtime helpers exposed in RouteContext.
21
+ def core: () ?{ (?) -> untyped } -> (untyped | nil)
22
+
23
+ def ct: (untyped value) -> untyped
24
+
25
+ alias content_format ct
26
+
27
+ def sz: (untyped value) -> untyped
28
+
29
+ def title: (untyped value) -> untyped
30
+
31
+ def obs: (?bool value) -> untyped
32
+
33
+ alias observable obs
34
+
35
+ def rt: (*untyped values) -> untyped
36
+
37
+ def interface: (*untyped values) -> untyped
38
+
39
+ alias if_ interface
40
+
41
+ def attribute: (untyped name, untyped value) -> untyped
42
+
43
+ # Persists staged attribute overrides back onto the route metadata.
44
+ # Invoked automatically after request handling, but also exposed so
45
+ # callers (e.g. Takagi::Router#configure_core) can persist updates.
46
+ def apply!: () -> (nil | untyped)
47
+
48
+ private
49
+
50
+ def assign_list: (untyped key, untyped values) -> (nil | untyped)
51
+
52
+ def metadata_override: (untyped key, untyped value) -> untyped
53
+
54
+ def normalize_content_format: (untyped value) -> untyped
55
+ end
56
+ end
57
+ end