syntropy 0.17 → 0.18
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/CHANGELOG.md +12 -8
- data/README.md +2 -2
- data/TODO.md +9 -132
- data/bin/syntropy +2 -2
- data/lib/syntropy/app.rb +5 -5
- data/lib/syntropy/dev_mode.rb +1 -1
- data/lib/syntropy/module.rb +7 -7
- data/lib/syntropy/{p2_extensions.rb → papercraft_extensions.rb} +2 -2
- data/lib/syntropy/version.rb +1 -1
- data/lib/syntropy.rb +2 -2
- data/syntropy.gemspec +1 -1
- data/test/bm_server.rb +16 -0
- data/test/test_routing_tree.rb +5 -5
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fccb5bf3768ed14e90b4bb5e67fd5cb87b2cf4290fd2b17474a9cb1e06678d34
|
4
|
+
data.tar.gz: bd23da91cb9ad10ab3bb2efcd7c7e48359809b4e21305303f8b1c02138745e7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0ad7ab962b0dee33b3a3d4b8c67392f3230c274921e584192330743fec83abbdbfb03af86dacc4e4104348c854337838db209fa310e259d21a076b5c2e2bb9a
|
7
|
+
data.tar.gz: b3ecca8901ff9743ee26200ee713ed08fe9a5ed23dd299cfefa2f0f9f49210bd21ad3c9a389f42c4b34bc8c396325a7050e31f281d8392edec4621043b843433
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# 0.18 2025-09-11
|
2
|
+
|
3
|
+
- Rename P2 back to Papercraft
|
4
|
+
|
1
5
|
# 0.17 2025-09-11
|
2
6
|
|
3
7
|
- Move repo to [digital-fabric](https://github.com/digital-fabric/syntropy)
|
@@ -16,8 +20,8 @@
|
|
16
20
|
- home page with links to examples
|
17
21
|
- Implement applet mounting and loading
|
18
22
|
- Remove Papercraft dependency
|
19
|
-
- Add support for
|
20
|
-
- Update
|
23
|
+
- Add support for Papercraft XML templates, using `#template_xml`
|
24
|
+
- Update Papercraft, TPapercraft
|
21
25
|
|
22
26
|
# 0.15 2025-08-31
|
23
27
|
|
@@ -46,16 +50,16 @@
|
|
46
50
|
|
47
51
|
## 0.11 2025-08-17
|
48
52
|
|
49
|
-
- Upgrade to
|
53
|
+
- Upgrade to Papercraft 2.8
|
50
54
|
|
51
55
|
## 0.10.1 2025-08-10
|
52
56
|
|
53
|
-
- Fix ModuleLoader.wrap_module to work correctly with
|
57
|
+
- Fix ModuleLoader.wrap_module to work correctly with Papercraft::Template
|
54
58
|
|
55
59
|
## 0.10 2025-08-10
|
56
60
|
|
57
61
|
- Add query, execute methods to ConnectionPool
|
58
|
-
- Switch from Papercraft to
|
62
|
+
- Switch from Papercraft to Papercraft
|
59
63
|
|
60
64
|
## 0.9.2 2025-07-24
|
61
65
|
|
@@ -63,17 +67,17 @@
|
|
63
67
|
|
64
68
|
## 0.9.1 2025-07-08
|
65
69
|
|
66
|
-
- Update
|
70
|
+
- Update TPapercraft
|
67
71
|
|
68
72
|
## 0.9 2025-07-08
|
69
73
|
|
70
|
-
- Update
|
74
|
+
- Update TPapercraft
|
71
75
|
- Add `Module.app` method for loading arbitrary apps
|
72
76
|
- Set `Module@machine`
|
73
77
|
|
74
78
|
## 0.8.4 2025-07-07
|
75
79
|
|
76
|
-
- Update
|
80
|
+
- Update TPapercraft
|
77
81
|
- Fix Router#path_parent to not break on double slash
|
78
82
|
|
79
83
|
## 0.8.3 2025-07-06
|
data/README.md
CHANGED
@@ -38,11 +38,11 @@ Syntropy is based on:
|
|
38
38
|
|
39
39
|
- [UringMachine](https://github.com/digital-fabric/uringmachine) - a lean mean
|
40
40
|
[io_uring](https://unixism.net/loti/what_is_io_uring.html) machine for Ruby.
|
41
|
-
- [
|
41
|
+
- [TPapercraft](https://github.com/digital-fabric/tp2) - an io_uring-based web server for
|
42
42
|
concurrent Ruby apps.
|
43
43
|
- [Qeweney](https://github.com/digital-fabric/qeweney) a uniform interface for
|
44
44
|
working with HTTP requests and responses.
|
45
|
-
- [
|
45
|
+
- [Papercraft](https://github.com/digital-fabric/papercraft) HTML templating with plain Ruby.
|
46
46
|
- [Extralite](https://github.com/digital-fabric/extralite) a fast and innovative
|
47
47
|
SQLite wrapper for Ruby.
|
48
48
|
|
data/TODO.md
CHANGED
@@ -23,7 +23,8 @@
|
|
23
23
|
article.render_proc #=> (load layout, apply article)
|
24
24
|
article.render #=> (render to HTML)
|
25
25
|
|
26
|
-
# there should also be methods for creating, updating and deleting of
|
26
|
+
# there should also be methods for creating, updating and deleting of
|
27
|
+
# articles/items.
|
27
28
|
...
|
28
29
|
```
|
29
30
|
|
@@ -32,140 +33,15 @@
|
|
32
33
|
- [ ] support for caching headers
|
33
34
|
- [ ] add `Request#render_static_file(route, fn)
|
34
35
|
|
35
|
-
- [ ] Serving of built-in assets (mostly JS)
|
36
|
-
- [ ] JS lib for RPC API
|
37
|
-
|
38
36
|
## Missing for a first public release
|
39
37
|
|
40
38
|
- [ ] Logo
|
41
39
|
- [ ] Website
|
42
|
-
- [
|
40
|
+
- [v] Frontend part of JSON API
|
43
41
|
- [v] Auto-refresh page when file changes
|
44
|
-
- [
|
45
|
-
- [
|
46
|
-
|
47
|
-
|
48
|
-
## Counter example
|
49
|
-
|
50
|
-
Here's a react component (from https://fresh.deno.dev/):
|
51
|
-
|
52
|
-
```jsx
|
53
|
-
// islands/Counter.tsx
|
54
|
-
import { useSignal } from "@preact/signals";
|
55
|
-
|
56
|
-
export default function Counter(props) {
|
57
|
-
const count = useSignal(props.start);
|
58
|
-
|
59
|
-
return (
|
60
|
-
<div>
|
61
|
-
<h3>Interactive island</h3>
|
62
|
-
<p>The server supplied the initial value of {props.start}.</p>
|
63
|
-
<div>
|
64
|
-
<button onClick={() => count.value -= 1}>-</button>
|
65
|
-
<div>{count}</div>
|
66
|
-
<button onClick={() => count.value += 1}>+</button>
|
67
|
-
</div>
|
68
|
-
</div>
|
69
|
-
);
|
70
|
-
}
|
71
|
-
```
|
72
|
-
|
73
|
-
How do we do this with Syntropy? Can we make a component that does the
|
74
|
-
templating and the reactivity in a single file? Can we wrap reactivity in a
|
75
|
-
component that has its own state? And where does the state live?
|
76
|
-
|
77
|
-
```ruby
|
78
|
-
class Counter < Syntropy::Component
|
79
|
-
def initialize(start:, **props)
|
80
|
-
@count = reactive()
|
81
|
-
end
|
82
|
-
|
83
|
-
def template
|
84
|
-
div {
|
85
|
-
h3 'Interactive island'
|
86
|
-
p "The server supplied the initial value of #props[:start]}"
|
87
|
-
div {
|
88
|
-
button '-', on_click: -> { @count.value -= 1 }
|
89
|
-
div @count.value
|
90
|
-
button '+', on_click: -> { @count.value += 1 }
|
91
|
-
}
|
92
|
-
}
|
93
|
-
end
|
94
|
-
end
|
95
|
-
```
|
96
|
-
|
97
|
-
Hmm, don't know if the complexity is worth it. It's an abstraction that's very
|
98
|
-
costly - both in terms of complexity of computation, and in terms of having a
|
99
|
-
clear mental model of what's happening under the hood.
|
100
|
-
|
101
|
-
I think a more logical approach is to stay with well-defined boundaries between
|
102
|
-
computation on the frontend and computation on the backend, and a having a clear
|
103
|
-
understanding of where things happen:
|
104
|
-
|
105
|
-
```ruby
|
106
|
-
class Counter < Syntropy::Component
|
107
|
-
def incr
|
108
|
-
update(value: @props[:value] + 1)
|
109
|
-
end
|
110
|
-
|
111
|
-
def decr
|
112
|
-
update(value: @props[:value] - 1)
|
113
|
-
end
|
114
|
-
|
115
|
-
def template
|
116
|
-
div {
|
117
|
-
h3 'Interactive island'
|
118
|
-
div {
|
119
|
-
button '-', syn_click: 'decr'
|
120
|
-
div @props[:value]
|
121
|
-
button '+', syn_click: 'incr'
|
122
|
-
}
|
123
|
-
}
|
124
|
-
end
|
125
|
-
end
|
126
|
-
```
|
127
|
-
|
128
|
-
Now, we can do all kinds of wrapping with scripts and ids and stuff to make this
|
129
|
-
work, but still, it would be preferable for the interactivity to be expressed in
|
130
|
-
JS. Maybe we just need a way to include a script that acts on the local HTML
|
131
|
-
code. How can we do this without writing a web component etc?
|
132
|
-
|
133
|
-
One way is to assign a random id to the template, then have a script that works
|
134
|
-
on it locally.
|
135
|
-
|
136
|
-
```ruby
|
137
|
-
export template { |**props|
|
138
|
-
id = SecureRandom.hex(4)
|
139
|
-
div(id: id) {
|
140
|
-
h3 'Interactive island'
|
141
|
-
div {
|
142
|
-
button '-', syn_action: "decr"
|
143
|
-
div props[:value], syn_value: "value"
|
144
|
-
button '+', syn_action: "incr"
|
145
|
-
}
|
146
|
-
script <<~JS
|
147
|
-
const state = { value: #{props[:value]} }
|
148
|
-
const root = document.querySelector('##{id}')
|
149
|
-
const decr = root.querySelector('[syn-action="decr"]')
|
150
|
-
const incr = root.querySelector('[syn-action="incr"]')
|
151
|
-
const value = root.querySelector('[syn-value="value"]')
|
152
|
-
const updateValue = (v) => { state.value = v; value.innerText = String(v) }
|
153
|
-
|
154
|
-
decr.addEventListener('click', (e) => { updateValue(state.value - 1) })
|
155
|
-
incr.addEventListener('click', (e) => { updateValue(state.value + 1) })
|
156
|
-
JS
|
157
|
-
}
|
158
|
-
}
|
159
|
-
```
|
160
|
-
|
161
|
-
How can we make this less verbose, less painful, less error-prone?
|
162
|
-
|
163
|
-
One way is to say - we don't worry about this on the backend, we just write
|
164
|
-
normal JS for the frontend and forget about the whole thing. Another way is to
|
165
|
-
provide a set of tools for making this less painful:
|
166
|
-
|
167
|
-
- Add some fancier abstractions on top of the JS RPC lib
|
168
|
-
- Add some template extensions that inject JS into the generated HTML
|
42
|
+
- [v] Examples
|
43
|
+
- [v] Reactive app - counter or some other simple app showing interaction with
|
44
|
+
server
|
169
45
|
|
170
46
|
## Testing facilities
|
171
47
|
|
@@ -184,7 +60,8 @@ provide a set of tools for making this less painful:
|
|
184
60
|
- session hook
|
185
61
|
- session persistence
|
186
62
|
- login page
|
187
|
-
- support for custom behaviour and custom workflows (2FA, signin using OTP
|
63
|
+
- support for custom behaviour and custom workflows (2FA, signin using OTP
|
64
|
+
etc.)
|
188
65
|
|
189
66
|
Example usage:
|
190
67
|
|
@@ -211,7 +88,7 @@ end
|
|
211
88
|
## Response: cookies and headers
|
212
89
|
|
213
90
|
We need a way to inject cookies into the response. This probably should be done
|
214
|
-
in the
|
91
|
+
in the TPapercraft code:
|
215
92
|
|
216
93
|
```ruby
|
217
94
|
@@default_set_cookie_attr = 'HttpOnly'
|
data/bin/syntropy
CHANGED
@@ -75,11 +75,11 @@ env[:banner] = false
|
|
75
75
|
|
76
76
|
# We set Syntropy.machine so we can reference it from anywhere
|
77
77
|
env[:machine] = Syntropy.machine = UM.new
|
78
|
-
env[:logger] = env[:logger] &&
|
78
|
+
env[:logger] = env[:logger] && TPapercraft::Logger.new(env[:machine], **env)
|
79
79
|
|
80
80
|
require 'syntropy/version'
|
81
81
|
require 'syntropy/dev_mode' if env[:dev_mode]
|
82
82
|
|
83
83
|
env[:logger]&.info(message: "Running Syntropy version #{Syntropy::VERSION}")
|
84
84
|
app = Syntropy::App.load(env)
|
85
|
-
|
85
|
+
TPapercraft.run(env) { app.call(it) }
|
data/lib/syntropy/app.rb
CHANGED
@@ -4,7 +4,7 @@ require 'json'
|
|
4
4
|
require 'yaml'
|
5
5
|
|
6
6
|
require 'qeweney'
|
7
|
-
require '
|
7
|
+
require 'papercraft'
|
8
8
|
|
9
9
|
require 'syntropy/errors'
|
10
10
|
require 'syntropy/file_watch'
|
@@ -197,14 +197,14 @@ module Syntropy
|
|
197
197
|
|
198
198
|
def compute_module_proc(mod)
|
199
199
|
case mod
|
200
|
-
when
|
201
|
-
|
200
|
+
when Papercraft::Template
|
201
|
+
papercraft_template_proc(mod)
|
202
202
|
else
|
203
203
|
mod
|
204
204
|
end
|
205
205
|
end
|
206
206
|
|
207
|
-
def
|
207
|
+
def papercraft_template_proc(template)
|
208
208
|
xml_mode = template.mode == :xml
|
209
209
|
template = template.proc
|
210
210
|
mime_type = xml_mode ? 'text/xml; charset=UTF-8' : 'text/html; charset=UTF-8'
|
@@ -302,7 +302,7 @@ module Syntropy
|
|
302
302
|
# @return [void]
|
303
303
|
def start
|
304
304
|
@machine.spin do
|
305
|
-
# we do startup stuff asynchronously, in order to first let
|
305
|
+
# we do startup stuff asynchronously, in order to first let TPapercraft do its
|
306
306
|
# setup tasks
|
307
307
|
@machine.sleep 0.2
|
308
308
|
route_count = @routing_tree.static_map.size + @routing_tree.dynamic_map.size
|
data/lib/syntropy/dev_mode.rb
CHANGED
data/lib/syntropy/module.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'papercraft'
|
4
4
|
|
5
5
|
module Syntropy
|
6
6
|
# The ModuleLoader class implemenets a module loader. It handles loading of
|
@@ -204,28 +204,28 @@ module Syntropy
|
|
204
204
|
}
|
205
205
|
end
|
206
206
|
|
207
|
-
# Creates and returns a
|
207
|
+
# Creates and returns a Papercraft template created with the given block.
|
208
208
|
#
|
209
209
|
# @param proc [Proc, nil] template proc or nil
|
210
210
|
# @param block [Proc] template block
|
211
|
-
# @return [
|
211
|
+
# @return [Papercraft::Template] template
|
212
212
|
def template(proc = nil, &block)
|
213
213
|
proc ||= block
|
214
214
|
raise "No template block/proc given" if !proc
|
215
215
|
|
216
|
-
|
216
|
+
Papercraft::Template.new(proc)
|
217
217
|
end
|
218
218
|
|
219
|
-
# Creates and returns a
|
219
|
+
# Creates and returns a Papercraft XML template created with the given block.
|
220
220
|
#
|
221
221
|
# @param proc [Proc, nil] template proc or nil
|
222
222
|
# @param block [Proc] template block
|
223
|
-
# @return [
|
223
|
+
# @return [Papercraft::Template] template
|
224
224
|
def template_xml(proc = nil, &block)
|
225
225
|
proc ||= block
|
226
226
|
raise "No template block/proc given" if !proc
|
227
227
|
|
228
|
-
|
228
|
+
Papercraft::Template.new(proc, mode: :xml)
|
229
229
|
rescue => e
|
230
230
|
p e
|
231
231
|
p e.backtrace
|
data/lib/syntropy/version.rb
CHANGED
data/lib/syntropy.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'qeweney'
|
4
4
|
require 'uringmachine'
|
5
5
|
require 'tp2'
|
6
|
-
require '
|
6
|
+
require 'papercraft'
|
7
7
|
|
8
8
|
require 'syntropy/app'
|
9
9
|
require 'syntropy/connection_pool'
|
@@ -11,7 +11,7 @@ require 'syntropy/errors'
|
|
11
11
|
require 'syntropy/markdown'
|
12
12
|
require 'syntropy/module'
|
13
13
|
require 'syntropy/request_extensions'
|
14
|
-
require 'syntropy/
|
14
|
+
require 'syntropy/papercraft_extensions'
|
15
15
|
require 'syntropy/routing_tree'
|
16
16
|
require 'syntropy/json_api'
|
17
17
|
require 'syntropy/side_run'
|
data/syntropy.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
|
24
24
|
s.add_dependency 'extralite', '2.13'
|
25
25
|
s.add_dependency 'json', '2.13.2'
|
26
|
-
s.add_dependency '
|
26
|
+
s.add_dependency 'papercraft', '2.13'
|
27
27
|
s.add_dependency 'qeweney', '0.22'
|
28
28
|
s.add_dependency 'tp2', '0.16'
|
29
29
|
s.add_dependency 'uringmachine', '0.18'
|
data/test/bm_server.rb
ADDED
data/test/test_routing_tree.rb
CHANGED
@@ -205,8 +205,8 @@ class RoutingTreeTest < Minitest::Test
|
|
205
205
|
router = @rt.router_proc
|
206
206
|
|
207
207
|
params = {}
|
208
|
-
route = router.('/docs/df/
|
209
|
-
assert_equal ({ 'org' => 'df', 'repo' => '
|
208
|
+
route = router.('/docs/df/papercraft/issues/14', params)
|
209
|
+
assert_equal ({ 'org' => 'df', 'repo' => 'papercraft', 'id' => '14'}), params
|
210
210
|
refute_nil route
|
211
211
|
assert_equal '/docs/[org]/[repo]/issues/[id]', route[:path]
|
212
212
|
|
@@ -292,13 +292,13 @@ class RoutingTreeTest < Minitest::Test
|
|
292
292
|
rt = Syntropy::RoutingTree.new(root_dir: File.join(@root_dir, 'site'), mount_path: '/')
|
293
293
|
router = rt.router_proc
|
294
294
|
|
295
|
-
route = router.('/docs/df/
|
295
|
+
route = router.('/docs/df/papercraft/issues/14', {})
|
296
296
|
assert_nil route
|
297
297
|
|
298
298
|
params = {}
|
299
|
-
route = router.('/df/
|
299
|
+
route = router.('/df/papercraft/issues/14', params)
|
300
300
|
refute_nil route
|
301
|
-
assert_equal ({ 'org' => 'df', 'repo' => '
|
301
|
+
assert_equal ({ 'org' => 'df', 'repo' => 'papercraft', 'id' => '14'}), params
|
302
302
|
assert_equal '/[org]/[repo]/issues/[id]', route[:path]
|
303
303
|
|
304
304
|
route = router.('/assets', {})
|
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.18'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
@@ -38,7 +38,7 @@ dependencies:
|
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: 2.13.2
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
|
-
name:
|
41
|
+
name: papercraft
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - '='
|
@@ -212,7 +212,7 @@ files:
|
|
212
212
|
- lib/syntropy/json_api.rb
|
213
213
|
- lib/syntropy/markdown.rb
|
214
214
|
- lib/syntropy/module.rb
|
215
|
-
- lib/syntropy/
|
215
|
+
- lib/syntropy/papercraft_extensions.rb
|
216
216
|
- lib/syntropy/request_extensions.rb
|
217
217
|
- lib/syntropy/routing_tree.rb
|
218
218
|
- lib/syntropy/side_run.rb
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- test/app_multi_site/bar.baz/index.html
|
245
245
|
- test/app_multi_site/foo.bar/index.html
|
246
246
|
- test/bm_router_proc.rb
|
247
|
+
- test/bm_server.rb
|
247
248
|
- test/helper.rb
|
248
249
|
- test/run.rb
|
249
250
|
- test/test_app.rb
|