tina4ruby 3.11.35 → 3.11.36

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.
@@ -714,10 +714,55 @@ module Tina4
714
714
  <span style="color:#ffeb3b;">req:#{request_id}</span>
715
715
  <span style="color:#90caf9;">#{route_count} routes</span>
716
716
  <span style="color:#888;">Ruby #{RUBY_VERSION}</span>
717
- <a href="#" onclick="(function(e){e.preventDefault();var p=document.getElementById('tina4-dev-panel');if(p){p.style.display=p.style.display==='none'?'block':'none';return;}var c=document.createElement('div');c.id='tina4-dev-panel';c.style.cssText='position:fixed;top:3rem;left:0;right:0;bottom:2rem;z-index:99998;transition:all 0.2s';var f=document.createElement('iframe');f.src='/__dev';f.style.cssText='width:100%;height:100%;border:1px solid #CC342D;border-radius:0.5rem;box-shadow:0 8px 32px rgba(0,0,0,0.5);background:#0f172a';c.appendChild(f);document.body.appendChild(c);})(event)" style="color:#ef9a9a;margin-left:auto;text-decoration:none;cursor:pointer;">Dashboard &#8599;</a>
717
+ <a href="#" onclick="window.__tina4ToggleOverlay(event)" style="color:#ef9a9a;margin-left:auto;text-decoration:none;cursor:pointer;">Dashboard &#8599;</a>
718
718
  <span onclick="this.parentElement.style.display='none'" style="cursor:pointer;color:#888;margin-left:8px;">&#10005;</span>
719
719
  </div>
720
720
  <script>
721
+ // Overlay open/toggle helper + auto-restore. Persist the dev-admin
722
+ // iframe's open/closed state across parent reloads so saving a
723
+ // file doesn't lose the user's dev-admin context. Cross-framework
724
+ // parity with PHP / Python / Node — same localStorage key.
725
+ (function(){
726
+ var STATE_KEY = 'tina4_dev_overlay_open';
727
+ function buildOverlay() {
728
+ var c = document.createElement('div');
729
+ c.id = 'tina4-dev-panel';
730
+ c.style.cssText = 'position:fixed;top:3rem;left:0;right:0;bottom:2rem;z-index:99998;transition:all 0.2s';
731
+ var f = document.createElement('iframe');
732
+ f.src = '/__dev';
733
+ f.style.cssText = 'width:100%;height:100%;border:1px solid #CC342D;border-radius:0.5rem;box-shadow:0 8px 32px rgba(0,0,0,0.5);background:#0f172a';
734
+ c.appendChild(f);
735
+ document.body.appendChild(c);
736
+ return c;
737
+ }
738
+ window.__tina4ToggleOverlay = function(e) {
739
+ if (e) e.preventDefault();
740
+ var p = document.getElementById('tina4-dev-panel');
741
+ if (p) {
742
+ var hide = p.style.display !== 'none';
743
+ p.style.display = hide ? 'none' : 'block';
744
+ try { localStorage.setItem(STATE_KEY, hide ? '0' : '1'); } catch (_) {}
745
+ return;
746
+ }
747
+ buildOverlay();
748
+ try { localStorage.setItem(STATE_KEY, '1'); } catch (_) {}
749
+ };
750
+ function restoreIfOpen() {
751
+ try {
752
+ if (location.pathname.indexOf('/__dev') === 0) return;
753
+ if (localStorage.getItem(STATE_KEY) === '1' && !document.getElementById('tina4-dev-panel')) {
754
+ buildOverlay();
755
+ }
756
+ } catch (_) {}
757
+ }
758
+ if (document.readyState === 'loading') {
759
+ document.addEventListener('DOMContentLoaded', restoreIfOpen);
760
+ } else {
761
+ restoreIfOpen();
762
+ }
763
+ })();
764
+ </script>
765
+ <script>
721
766
  function tina4VersionModal(){
722
767
  var m=document.getElementById('tina4-ver-modal');
723
768
  if(m.style.display==='block'){m.style.display='none';return;}
@@ -151,6 +151,9 @@ module Tina4
151
151
  self
152
152
  end
153
153
 
154
+ # Render a Frond/Twig template file with data and return self. Tries
155
+ # the user template directory first, falling back to the framework's
156
+ # built-in templates. Sets the response body to the rendered HTML.
154
157
  def render(template_path, data = {}, status: 200, template_dir: nil)
155
158
  @status_code = status
156
159
  @headers["content-type"] = HTML_CONTENT_TYPE
@@ -53,6 +53,16 @@ module Tina4
53
53
  end
54
54
  end
55
55
 
56
+ # Stop background tasks
57
+ if defined?(Tina4::Background)
58
+ begin
59
+ Tina4::Background.stop_all
60
+ Tina4::Log.info("Background tasks stopped")
61
+ rescue => e
62
+ Tina4::Log.error("Error stopping background tasks: #{e.message}")
63
+ end
64
+ end
65
+
56
66
  # Close database connections
57
67
  if Tina4.database
58
68
  begin
data/lib/tina4/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tina4
4
- VERSION = "3.11.35"
4
+ VERSION = "3.11.36"
5
5
  end
data/lib/tina4.rb CHANGED
@@ -35,11 +35,14 @@ require_relative "tina4/cors"
35
35
  require_relative "tina4/rate_limiter"
36
36
  require_relative "tina4/health"
37
37
  require_relative "tina4/shutdown"
38
+ require_relative "tina4/background"
38
39
  require_relative "tina4/localization"
39
40
  require_relative "tina4/container"
40
41
  require_relative "tina4/queue"
41
42
  require_relative "tina4/service_runner"
42
43
  require_relative "tina4/events"
44
+ require_relative "tina4/plan"
45
+ require_relative "tina4/project_index"
43
46
  require_relative "tina4/dev_admin"
44
47
  require_relative "tina4/messenger"
45
48
  require_relative "tina4/dev_mailbox"
@@ -50,6 +53,7 @@ require_relative "tina4/response_cache"
50
53
  require_relative "tina4/html_element"
51
54
  require_relative "tina4/error_overlay"
52
55
  require_relative "tina4/test_client"
56
+ require_relative "tina4/docs"
53
57
  require_relative "tina4/mcp"
54
58
 
55
59
  module Tina4
@@ -383,6 +387,16 @@ module Tina4
383
387
  Tina4::ServiceRunner.register(name, nil, options, &block)
384
388
  end
385
389
 
390
+ # Register a periodic background task.
391
+ # Mirrors Python's tina4_python.core.server.background(fn, interval) and
392
+ # PHP's $app->background($callback, $interval).
393
+ #
394
+ # Tina4.background(interval: 5.0) { drain_queue }
395
+ # Tina4.background(method(:health_check), interval: 30.0)
396
+ def background(callback = nil, interval: 1.0, &block)
397
+ Tina4::Background.register(callback, interval: interval, &block)
398
+ end
399
+
386
400
  # DI container shortcuts
387
401
  def register(name, instance = nil, &block)
388
402
  Tina4::Container.register(name, instance, &block)
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.35
4
+ version: 3.11.36
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tina4 Team
@@ -281,6 +281,7 @@ files:
281
281
  - lib/tina4/api.rb
282
282
  - lib/tina4/auth.rb
283
283
  - lib/tina4/auto_crud.rb
284
+ - lib/tina4/background.rb
284
285
  - lib/tina4/cache.rb
285
286
  - lib/tina4/cli.rb
286
287
  - lib/tina4/constants.rb
@@ -294,6 +295,7 @@ files:
294
295
  - lib/tina4/dev.rb
295
296
  - lib/tina4/dev_admin.rb
296
297
  - lib/tina4/dev_mailbox.rb
298
+ - lib/tina4/docs.rb
297
299
  - lib/tina4/drivers/firebird_driver.rb
298
300
  - lib/tina4/drivers/mongodb_driver.rb
299
301
  - lib/tina4/drivers/mssql_driver.rb
@@ -333,6 +335,8 @@ files:
333
335
  - lib/tina4/middleware.rb
334
336
  - lib/tina4/migration.rb
335
337
  - lib/tina4/orm.rb
338
+ - lib/tina4/plan.rb
339
+ - lib/tina4/project_index.rb
336
340
  - lib/tina4/public/css/tina4.css
337
341
  - lib/tina4/public/css/tina4.min.css
338
342
  - lib/tina4/public/favicon.ico