tina4ruby 3.11.12 → 3.11.13
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 +4 -4
- data/README.md +18 -12
- data/lib/tina4/rack_app.rb +2 -2
- data/lib/tina4/router.rb +28 -11
- data/lib/tina4/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca811aa2cb83ea336ce8be177f6f3688d014d6a7cb2ad4b90304a752a163d6aa
|
|
4
|
+
data.tar.gz: 51208212f5cf5b7c49fde4f77d80b042a99d65ec615f9e422228299dd04993c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8baf46841c98a50c37b767ce9f963404c04250802e58b33c97d4927847fd7895098e243affbde71caae19d872fd6238b388c2d08affc5d157f9b9a51aae73e46
|
|
7
|
+
data.tar.gz: bcc3047216b640f05573f7f450f6f591b8e3467979f12c503f80d2a652cdbb17cc513ed373b7e881b6c1305502b420910941bba6aefba401d827e45b21d918ec
|
data/README.md
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
<h1 align="center">Tina4 Ruby</h1>
|
|
5
5
|
<h3 align="center">TINA4 — The Intelligent Native Application 4ramework</h3>
|
|
6
6
|
<p align="center"><em>Simple. Fast. Human. | Built for AI. Built for you.</em></p>
|
|
7
|
-
<p align="center">
|
|
7
|
+
<p align="center">55 built-in features. Zero runtime dependencies. One require, everything works.</p>
|
|
8
8
|
<p align="center">
|
|
9
9
|
<a href="https://rubygems.org/gems/tina4ruby"><img src="https://img.shields.io/gem/v/tina4ruby?color=7b1fa2&label=RubyGems" alt="RubyGems"></a>
|
|
10
|
-
<img src="https://img.shields.io/badge/tests-
|
|
11
|
-
<img src="https://img.shields.io/badge/features-
|
|
10
|
+
<img src="https://img.shields.io/badge/tests-2%2C508%20passing-brightgreen" alt="Tests">
|
|
11
|
+
<img src="https://img.shields.io/badge/features-55-blue" alt="Features">
|
|
12
12
|
<img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="Zero Deps">
|
|
13
13
|
<a href="https://tina4.com"><img src="https://img.shields.io/badge/docs-tina4.com-7b1fa2" alt="Docs"></a>
|
|
14
14
|
</p>
|
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
## Quick Start
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
+
# With the Tina4 CLI (recommended — enables SCSS + live reload)
|
|
22
|
+
cargo install tina4 # or grab a binary from https://github.com/tina4stack/tina4/releases
|
|
23
|
+
tina4 init ruby ./my-app
|
|
24
|
+
cd my-app && tina4 serve
|
|
25
|
+
|
|
26
|
+
# Without the Tina4 CLI
|
|
21
27
|
gem install tina4ruby
|
|
22
28
|
tina4ruby init my-app
|
|
23
29
|
cd my-app && tina4ruby serve
|
|
@@ -60,7 +66,7 @@ db = Tina4::Database.new("sqlite://app.db")
|
|
|
60
66
|
| **Developer Tools** (7) | Dev dashboard (11 tabs), dev toolbar, error overlay (Catppuccin Mocha), dev mailbox, hot reload + CSS hot-reload, code metrics (complexity, coupling, maintainability), AI context installer (7 tools) |
|
|
61
67
|
| **Utilities** (7) | DI container (transient + singleton), HtmlElement builder, inline testing (`@tests` decorator), i18n (6 languages), Swagger/OpenAPI auto-generation, CLI scaffolding (`generate model/route/migration/middleware`), structured logging |
|
|
62
68
|
|
|
63
|
-
**
|
|
69
|
+
**2,508 tests. Zero runtime dependencies. Full parity across Python, PHP, Ruby, and Node.js.**
|
|
64
70
|
|
|
65
71
|
---
|
|
66
72
|
|
|
@@ -82,10 +88,10 @@ Benchmarked with `wrk` — 5,000 requests, 50 concurrent, median of 3 runs:
|
|
|
82
88
|
|
|
83
89
|
| Framework | JSON req/s | Deps | Features |
|
|
84
90
|
|-----------|-----------|------|----------|
|
|
85
|
-
| **Tina4 Ruby** | **10,243** | 0 |
|
|
91
|
+
| **Tina4 Ruby** | **10,243** | 0 | 55 |
|
|
86
92
|
| Sinatra | 9,548 | 5+ | ~4 |
|
|
87
93
|
|
|
88
|
-
Tina4 Ruby outperforms Sinatra while delivering **
|
|
94
|
+
Tina4 Ruby outperforms Sinatra while delivering **55 features vs ~4** — with zero runtime dependencies.
|
|
89
95
|
|
|
90
96
|
**Across all 4 Tina4 implementations:**
|
|
91
97
|
|
|
@@ -93,21 +99,21 @@ Tina4 Ruby outperforms Sinatra while delivering **54 features vs ~4** — with z
|
|
|
93
99
|
|---|--------|-----|------|---------|
|
|
94
100
|
| **JSON req/s** | 6,508 | 29,293 | 10,243 | 84,771 |
|
|
95
101
|
| **Dependencies** | 0 | 0 | 0 | 0 |
|
|
96
|
-
| **Features** |
|
|
102
|
+
| **Features** | 55 | 55 | 55 | 55 |
|
|
97
103
|
|
|
98
104
|
---
|
|
99
105
|
|
|
100
106
|
## Cross-Framework Parity
|
|
101
107
|
|
|
102
|
-
Tina4 ships identical features across four languages — same architecture, same conventions, same
|
|
108
|
+
Tina4 ships identical features across four languages — same architecture, same conventions, same 55 features:
|
|
103
109
|
|
|
104
110
|
| | Python | PHP | Ruby | Node.js |
|
|
105
111
|
|---|--------|-----|------|---------|
|
|
106
|
-
| **Package** | `tina4-python` | `tina4stack/tina4php` | `tina4ruby` |
|
|
107
|
-
| **Tests** | 2,
|
|
108
|
-
| **Default port** |
|
|
112
|
+
| **Package** | `tina4-python` | `tina4stack/tina4php` | `tina4ruby` | `@tina4/core` |
|
|
113
|
+
| **Tests (v3.11.12)** | 2,281 | 2,073 | 2,508 | 2,897 |
|
|
114
|
+
| **Default port** | 7146 | 7145 | 7147 | 7148 |
|
|
109
115
|
|
|
110
|
-
|
|
116
|
+
**~9,700 tests** across all 4 frameworks. See [tina4.com](https://tina4.com).
|
|
111
117
|
|
|
112
118
|
---
|
|
113
119
|
|
data/lib/tina4/rack_app.rb
CHANGED
|
@@ -560,13 +560,13 @@ module Tina4
|
|
|
560
560
|
var maxAttempts = 5;
|
|
561
561
|
function pollRoute() {
|
|
562
562
|
fetch(tryUrl, {method: 'HEAD'}).then(function() {
|
|
563
|
-
window.
|
|
563
|
+
window.open(tryUrl, '_blank');
|
|
564
564
|
}).catch(function() {
|
|
565
565
|
attempts++;
|
|
566
566
|
if (attempts < maxAttempts) {
|
|
567
567
|
setTimeout(pollRoute, 500);
|
|
568
568
|
} else {
|
|
569
|
-
window.
|
|
569
|
+
window.open(tryUrl, '_blank');
|
|
570
570
|
}
|
|
571
571
|
});
|
|
572
572
|
}
|
data/lib/tina4/router.rb
CHANGED
|
@@ -98,6 +98,27 @@ module Tina4
|
|
|
98
98
|
p
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
# Supported typed-parameter constraints. Mirrored verbatim in
|
|
102
|
+
# tina4-python / tina4-php / tina4-nodejs for cross-framework parity.
|
|
103
|
+
#
|
|
104
|
+
# Any type name not in this table raises ``ArgumentError`` at route
|
|
105
|
+
# registration — we never silently fall through to the default matcher,
|
|
106
|
+
# because a typo like ``{id:inetger}`` would otherwise match anything
|
|
107
|
+
# and create a security footgun (see tina4-book#125).
|
|
108
|
+
PARAM_TYPE_PATTERNS = {
|
|
109
|
+
"string" => "[^/]+", # default, any non-slash segment
|
|
110
|
+
"int" => '\d+',
|
|
111
|
+
"integer" => '\d+',
|
|
112
|
+
"float" => '[\d.]+',
|
|
113
|
+
"number" => '[\d.]+',
|
|
114
|
+
"alpha" => "[A-Za-z]+", # letters only
|
|
115
|
+
"alnum" => "[A-Za-z0-9]+", # letters + digits
|
|
116
|
+
"slug" => "[a-z0-9-]+", # URL slug
|
|
117
|
+
"uuid" => "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",
|
|
118
|
+
"path" => ".+", # greedy
|
|
119
|
+
".*" => ".+",
|
|
120
|
+
}.freeze
|
|
121
|
+
|
|
101
122
|
def compile_pattern(path)
|
|
102
123
|
return Regexp.new("\\A/\\z") if path == "/"
|
|
103
124
|
|
|
@@ -113,23 +134,19 @@ module Tina4
|
|
|
113
134
|
# to match Python/PHP/Node parity (docs say `request.params["*"]`).
|
|
114
135
|
@param_names << { name: :"*", type: "path" }
|
|
115
136
|
'(.+)'
|
|
116
|
-
elsif part =~ /\A\{(\w+)(?::(\w+))?\}\z/
|
|
137
|
+
elsif part =~ /\A\{(\w+)(?::([\w.*]+))?\}\z/
|
|
117
138
|
# Tina4/Python-style brace params: {id} or {id:int}
|
|
118
139
|
# This is the ONLY supported param syntax, matching Python exactly.
|
|
119
140
|
# Do NOT add :id (colon) style params.
|
|
120
141
|
name = Regexp.last_match(1)
|
|
121
142
|
type = Regexp.last_match(2) || "string"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
when "float", "number"
|
|
127
|
-
'([\d.]+)'
|
|
128
|
-
when "path"
|
|
129
|
-
'(.+)'
|
|
130
|
-
else
|
|
131
|
-
'([^/]+)'
|
|
143
|
+
unless PARAM_TYPE_PATTERNS.key?(type)
|
|
144
|
+
valid = PARAM_TYPE_PATTERNS.keys.reject { |k| k == ".*" }.sort.join(", ")
|
|
145
|
+
raise ArgumentError,
|
|
146
|
+
"Unknown param type '#{type}' in route '#{path}'. Valid types: #{valid}."
|
|
132
147
|
end
|
|
148
|
+
@param_names << { name: name.to_sym, type: type }
|
|
149
|
+
"(#{PARAM_TYPE_PATTERNS[type]})"
|
|
133
150
|
else
|
|
134
151
|
Regexp.escape(part)
|
|
135
152
|
end
|
data/lib/tina4/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tina4ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.11.
|
|
4
|
+
version: 3.11.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tina4 Team
|
|
@@ -179,33 +179,33 @@ dependencies:
|
|
|
179
179
|
- !ruby/object:Gem::Version
|
|
180
180
|
version: '1.8'
|
|
181
181
|
- !ruby/object:Gem::Dependency
|
|
182
|
-
name:
|
|
182
|
+
name: sqlite3
|
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
|
184
184
|
requirements:
|
|
185
185
|
- - "~>"
|
|
186
186
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: '
|
|
188
|
-
type: :
|
|
187
|
+
version: '2.0'
|
|
188
|
+
type: :runtime
|
|
189
189
|
prerelease: false
|
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
191
|
requirements:
|
|
192
192
|
- - "~>"
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: '
|
|
194
|
+
version: '2.0'
|
|
195
195
|
- !ruby/object:Gem::Dependency
|
|
196
|
-
name:
|
|
196
|
+
name: listen
|
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
|
198
198
|
requirements:
|
|
199
199
|
- - "~>"
|
|
200
200
|
- !ruby/object:Gem::Version
|
|
201
|
-
version: '
|
|
201
|
+
version: '3.8'
|
|
202
202
|
type: :development
|
|
203
203
|
prerelease: false
|
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
|
205
205
|
requirements:
|
|
206
206
|
- - "~>"
|
|
207
207
|
- !ruby/object:Gem::Version
|
|
208
|
-
version: '
|
|
208
|
+
version: '3.8'
|
|
209
209
|
- !ruby/object:Gem::Dependency
|
|
210
210
|
name: pg
|
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|