syntropy 0.31.0 → 0.32.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +13 -0
- data/TODO.md +46 -1
- data/cmd/console.rb +77 -0
- data/cmd/serve.rb +1 -1
- data/examples/blog/app/_layout/default.rb +11 -0
- data/examples/blog/app/_lib/post_store.rb +47 -0
- data/examples/blog/app/_schema/2026-01-01-initial.rb +9 -0
- data/examples/blog/app/_setup.rb +4 -0
- data/examples/blog/app/index.rb +7 -0
- data/examples/blog/app/posts/[id]/edit.rb +33 -0
- data/examples/blog/app/posts/[id]/index.rb +58 -0
- data/examples/blog/app/posts/index.rb +38 -0
- data/examples/blog/app/posts/new.rb +29 -0
- data/examples/mcp-oauth/README.md +3 -3
- data/examples/mcp-oauth/app/mcp.rb +55 -8
- data/examples/mcp-oauth/app/oauth/authorize.rb +0 -8
- data/examples/mcp-oauth/app/oauth/register.rb +0 -1
- data/lib/syntropy/app.rb +23 -9
- data/lib/syntropy/db/connection_pool.rb +71 -0
- data/lib/syntropy/db/schema.rb +92 -0
- data/lib/syntropy/db/store.rb +31 -0
- data/lib/syntropy/http/io_extensions.rb +33 -5
- data/lib/syntropy/http/server_connection.rb +6 -53
- data/lib/syntropy/{module.rb → module_loader.rb} +47 -8
- data/lib/syntropy/request/request_info.rb +3 -4
- data/lib/syntropy/request/validation.rb +1 -2
- data/lib/syntropy/test.rb +13 -1
- data/lib/syntropy/version.rb +1 -1
- data/lib/syntropy.rb +4 -2
- data/syntropy.gemspec +2 -1
- data/test/app/_hook.rb +1 -1
- data/test/app/by_method.rb +9 -0
- data/test/app_setup/_setup.rb +7 -0
- data/test/app_setup/index.rb +1 -0
- data/test/app_with_schema/_schema/2026-01-02-foo.rb +12 -0
- data/test/app_with_schema/_schema/2026-05-30-bar.rb +7 -0
- data/test/schema/2026-01-02-foo.rb +12 -0
- data/test/schema/2026-05-30-bar.rb +7 -0
- data/test/test_app.rb +58 -3
- data/test/{test_connection_pool.rb → test_db_connection_pool.rb} +7 -2
- data/test/test_db_schema.rb +96 -0
- data/test/test_db_store.rb +24 -0
- data/test/test_http_protocol.rb +250 -0
- data/test/test_http_server_connection.rb +10 -19
- data/test/test_json_api.rb +1 -1
- data/test/{test_module.rb → test_module_loader.rb} +31 -0
- data/test/test_request.rb +7 -4
- data/test/test_server.rb +9 -13
- metadata +48 -12
- data/lib/syntropy/connection_pool.rb +0 -61
data/test/test_server.rb
CHANGED
|
@@ -89,12 +89,12 @@ class ServerTest < Minitest::Test
|
|
|
89
89
|
req.respond("method: #{req.method}")
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
write_http_request "GET /foo HTTP/1.1\r\nServer: foo.com\r\n\r\
|
|
92
|
+
write_http_request "GET /foo HTTP/1.1\r\nServer: foo.com\r\n\r\nPUT /bar HTTP/1.1\r\n\r\n"
|
|
93
93
|
|
|
94
94
|
@machine.sleep(0.1)
|
|
95
95
|
response = read_client_side
|
|
96
96
|
expected = "HTTP/1.1 200\r\nTransfer-Encoding: chunked\r\n\r\nb\r\nmethod: get\r\n0\r\n\r\n" +
|
|
97
|
-
"HTTP/1.1 200\r\nTransfer-Encoding: chunked\r\n\r\
|
|
97
|
+
"HTTP/1.1 200\r\nTransfer-Encoding: chunked\r\n\r\nb\r\nmethod: put\r\n0\r\n\r\n"
|
|
98
98
|
assert_equal(expected, response)
|
|
99
99
|
end
|
|
100
100
|
|
|
@@ -107,7 +107,7 @@ class ServerTest < Minitest::Test
|
|
|
107
107
|
raise
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
write_http_request "GET /foo HTTP/1.1\r\nServer: foo.com\r\n\r\
|
|
110
|
+
write_http_request "GET /foo HTTP/1.1\r\nServer: foo.com\r\n\r\nPUT /bar HTTP/1.1\r\n\r\n"
|
|
111
111
|
|
|
112
112
|
@machine.sleep(0.01)
|
|
113
113
|
@server.stop!
|
|
@@ -132,7 +132,7 @@ class ServerTest < Minitest::Test
|
|
|
132
132
|
Server: foo.com
|
|
133
133
|
Content-Length: 3
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
abcPOST /bar HTTP/1.1
|
|
136
136
|
Server: bar.com
|
|
137
137
|
Content-Length: 6
|
|
138
138
|
|
|
@@ -148,7 +148,6 @@ class ServerTest < Minitest::Test
|
|
|
148
148
|
assert_equal({
|
|
149
149
|
':method' => 'post',
|
|
150
150
|
':path' => '/foo',
|
|
151
|
-
':protocol' => 'http/1.1',
|
|
152
151
|
'server' => 'foo.com',
|
|
153
152
|
'content-length' => '3',
|
|
154
153
|
':body-done-reading' => true,
|
|
@@ -160,13 +159,12 @@ class ServerTest < Minitest::Test
|
|
|
160
159
|
req1 = @reqs.shift
|
|
161
160
|
headers = req1.headers
|
|
162
161
|
assert_equal({
|
|
163
|
-
':method' => '
|
|
162
|
+
':method' => 'post',
|
|
164
163
|
':path' => '/bar',
|
|
165
|
-
':protocol' => 'http/1.1',
|
|
166
164
|
'server' => 'bar.com',
|
|
167
165
|
'content-length' => '6',
|
|
168
166
|
':body-done-reading' => true,
|
|
169
|
-
':tx' =>
|
|
167
|
+
':tx' => 56,
|
|
170
168
|
}, headers)
|
|
171
169
|
body = @bodies.shift
|
|
172
170
|
assert_equal 'defghi', body
|
|
@@ -196,7 +194,7 @@ class ServerTest < Minitest::Test
|
|
|
196
194
|
de
|
|
197
195
|
0
|
|
198
196
|
|
|
199
|
-
|
|
197
|
+
POST /bar HTTP/1.1
|
|
200
198
|
Server: bar.com
|
|
201
199
|
Transfer-Encoding: chunked
|
|
202
200
|
|
|
@@ -218,7 +216,6 @@ class ServerTest < Minitest::Test
|
|
|
218
216
|
assert_equal({
|
|
219
217
|
':method' => 'post',
|
|
220
218
|
':path' => '/foo',
|
|
221
|
-
':protocol' => 'http/1.1',
|
|
222
219
|
'server' => 'foo.com',
|
|
223
220
|
'transfer-encoding' => 'chunked',
|
|
224
221
|
':body-done-reading' => true,
|
|
@@ -230,13 +227,12 @@ class ServerTest < Minitest::Test
|
|
|
230
227
|
req1 = @reqs.shift
|
|
231
228
|
headers = req1.headers
|
|
232
229
|
assert_equal({
|
|
233
|
-
':method' => '
|
|
230
|
+
':method' => 'post',
|
|
234
231
|
':path' => '/bar',
|
|
235
|
-
':protocol' => 'http/1.1',
|
|
236
232
|
'server' => 'bar.com',
|
|
237
233
|
'transfer-encoding' => 'chunked',
|
|
238
234
|
':body-done-reading' => true,
|
|
239
|
-
':tx' =>
|
|
235
|
+
':tx' => 56
|
|
240
236
|
}, headers)
|
|
241
237
|
body = @bodies.shift
|
|
242
238
|
assert_equal '123456789abcdefghijklmnopqrstuv', body
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: syntropy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.32.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sharon Rosner
|
|
@@ -52,21 +52,21 @@ dependencies:
|
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: 1.0.2
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
|
-
name:
|
|
55
|
+
name: json
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
|
-
- -
|
|
58
|
+
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
60
|
+
version: '0'
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
|
-
- -
|
|
65
|
+
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
67
|
+
version: '0'
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
|
-
name:
|
|
69
|
+
name: logger
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - ">="
|
|
@@ -80,7 +80,7 @@ dependencies:
|
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
81
|
version: '0'
|
|
82
82
|
- !ruby/object:Gem::Dependency
|
|
83
|
-
name:
|
|
83
|
+
name: irb
|
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements:
|
|
86
86
|
- - ">="
|
|
@@ -121,6 +121,20 @@ dependencies:
|
|
|
121
121
|
- - "~>"
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
123
|
version: 13.3.1
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: solargraph
|
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - ">="
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '0'
|
|
131
|
+
type: :development
|
|
132
|
+
prerelease: false
|
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">="
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '0'
|
|
124
138
|
email: sharon@noteflakes.com
|
|
125
139
|
executables:
|
|
126
140
|
- syntropy
|
|
@@ -140,6 +154,7 @@ files:
|
|
|
140
154
|
- TODO.md
|
|
141
155
|
- bin/syntropy
|
|
142
156
|
- cmd/_banner.rb
|
|
157
|
+
- cmd/console.rb
|
|
143
158
|
- cmd/help.rb
|
|
144
159
|
- cmd/serve.rb
|
|
145
160
|
- cmd/setup/template/site/.gitignore
|
|
@@ -175,6 +190,15 @@ files:
|
|
|
175
190
|
- examples/basic/favicon.ico
|
|
176
191
|
- examples/basic/index.md
|
|
177
192
|
- examples/basic/templates.rb
|
|
193
|
+
- examples/blog/app/_layout/default.rb
|
|
194
|
+
- examples/blog/app/_lib/post_store.rb
|
|
195
|
+
- examples/blog/app/_schema/2026-01-01-initial.rb
|
|
196
|
+
- examples/blog/app/_setup.rb
|
|
197
|
+
- examples/blog/app/index.rb
|
|
198
|
+
- examples/blog/app/posts/[id]/edit.rb
|
|
199
|
+
- examples/blog/app/posts/[id]/index.rb
|
|
200
|
+
- examples/blog/app/posts/index.rb
|
|
201
|
+
- examples/blog/app/posts/new.rb
|
|
178
202
|
- examples/mcp-oauth/.ruby-version
|
|
179
203
|
- examples/mcp-oauth/Gemfile
|
|
180
204
|
- examples/mcp-oauth/README.md
|
|
@@ -202,7 +226,9 @@ files:
|
|
|
202
226
|
- lib/syntropy/applets/builtin/json_api.js
|
|
203
227
|
- lib/syntropy/applets/builtin/ping.rb
|
|
204
228
|
- lib/syntropy/applets/builtin/req.rb
|
|
205
|
-
- lib/syntropy/connection_pool.rb
|
|
229
|
+
- lib/syntropy/db/connection_pool.rb
|
|
230
|
+
- lib/syntropy/db/schema.rb
|
|
231
|
+
- lib/syntropy/db/store.rb
|
|
206
232
|
- lib/syntropy/dev_mode.rb
|
|
207
233
|
- lib/syntropy/errors.rb
|
|
208
234
|
- lib/syntropy/http.rb
|
|
@@ -216,7 +242,7 @@ files:
|
|
|
216
242
|
- lib/syntropy/logger.rb
|
|
217
243
|
- lib/syntropy/markdown.rb
|
|
218
244
|
- lib/syntropy/mime_types.rb
|
|
219
|
-
- lib/syntropy/
|
|
245
|
+
- lib/syntropy/module_loader.rb
|
|
220
246
|
- lib/syntropy/papercraft_extensions.rb
|
|
221
247
|
- lib/syntropy/request.rb
|
|
222
248
|
- lib/syntropy/request/mock_adapter.rb
|
|
@@ -247,6 +273,7 @@ files:
|
|
|
247
273
|
- test/app/bad_mod.rb
|
|
248
274
|
- test/app/bar.rb
|
|
249
275
|
- test/app/baz.rb
|
|
276
|
+
- test/app/by_method.rb
|
|
250
277
|
- test/app/deps.rb
|
|
251
278
|
- test/app/index.html
|
|
252
279
|
- test/app/mod/bar/index+.rb
|
|
@@ -260,20 +287,29 @@ files:
|
|
|
260
287
|
- test/app_multi_site/_site.rb
|
|
261
288
|
- test/app_multi_site/bar.baz/index.html
|
|
262
289
|
- test/app_multi_site/foo.bar/index.html
|
|
290
|
+
- test/app_setup/_setup.rb
|
|
291
|
+
- test/app_setup/index.rb
|
|
292
|
+
- test/app_with_schema/_schema/2026-01-02-foo.rb
|
|
293
|
+
- test/app_with_schema/_schema/2026-05-30-bar.rb
|
|
263
294
|
- test/bm_router_proc.rb
|
|
264
295
|
- test/bm_server.rb
|
|
265
296
|
- test/helper.rb
|
|
266
297
|
- test/run.rb
|
|
298
|
+
- test/schema/2026-01-02-foo.rb
|
|
299
|
+
- test/schema/2026-05-30-bar.rb
|
|
267
300
|
- test/test_app.rb
|
|
268
301
|
- test/test_caching.rb
|
|
269
|
-
- test/
|
|
302
|
+
- test/test_db_connection_pool.rb
|
|
303
|
+
- test/test_db_schema.rb
|
|
304
|
+
- test/test_db_store.rb
|
|
270
305
|
- test/test_errors.rb
|
|
271
306
|
- test/test_http_client.rb
|
|
272
307
|
- test/test_http_client_connection.rb
|
|
308
|
+
- test/test_http_protocol.rb
|
|
273
309
|
- test/test_http_server_connection.rb
|
|
274
310
|
- test/test_json_api.rb
|
|
275
311
|
- test/test_mock_adapter.rb
|
|
276
|
-
- test/
|
|
312
|
+
- test/test_module_loader.rb
|
|
277
313
|
- test/test_request.rb
|
|
278
314
|
- test/test_response.rb
|
|
279
315
|
- test/test_routing_tree.rb
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'extralite'
|
|
4
|
-
|
|
5
|
-
module Syntropy
|
|
6
|
-
class ConnectionPool
|
|
7
|
-
attr_reader :count
|
|
8
|
-
|
|
9
|
-
def initialize(machine, fn, max_conn)
|
|
10
|
-
@machine = machine
|
|
11
|
-
@fn = fn
|
|
12
|
-
@count = 0
|
|
13
|
-
@max_conn = max_conn
|
|
14
|
-
@queue = UM::Queue.new
|
|
15
|
-
@key = :"db_#{fn}"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def with_db
|
|
19
|
-
if (db = Thread.current[@key])
|
|
20
|
-
@machine.snooze
|
|
21
|
-
return yield(db)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
db = checkout
|
|
25
|
-
begin
|
|
26
|
-
Thread.current[@key] = db
|
|
27
|
-
yield(db)
|
|
28
|
-
ensure
|
|
29
|
-
Thread.current[@key] = nil
|
|
30
|
-
checkin(db)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def query(sql, *, **, &)
|
|
35
|
-
with_db { it.query(sql, *, **, &) }
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def execute(sql, *, **)
|
|
39
|
-
with_db { it.execute(sql, *, **) }
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
def checkout
|
|
45
|
-
return make_db_instance if @queue.count == 0 && @count < @max_conn
|
|
46
|
-
|
|
47
|
-
@machine.shift(@queue)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def checkin(db)
|
|
51
|
-
@machine.push(@queue, db)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def make_db_instance
|
|
55
|
-
Extralite::Database.new(@fn, wal: true).tap do
|
|
56
|
-
@count += 1
|
|
57
|
-
it.on_progress(mode: :at_least_once, period: 320, tick: 10) { @machine.snooze }
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|