tina4ruby 0.5.2 → 3.0.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/README.md +360 -559
  4. data/exe/{tina4 → tina4ruby} +1 -0
  5. data/lib/tina4/ai.rb +312 -0
  6. data/lib/tina4/auth.rb +44 -3
  7. data/lib/tina4/auto_crud.rb +163 -0
  8. data/lib/tina4/cli.rb +242 -77
  9. data/lib/tina4/constants.rb +46 -0
  10. data/lib/tina4/cors.rb +74 -0
  11. data/lib/tina4/database/sqlite3_adapter.rb +139 -0
  12. data/lib/tina4/database.rb +43 -7
  13. data/lib/tina4/debug.rb +4 -79
  14. data/lib/tina4/dev_admin.rb +1162 -0
  15. data/lib/tina4/dev_mailbox.rb +191 -0
  16. data/lib/tina4/dev_reload.rb +9 -9
  17. data/lib/tina4/drivers/firebird_driver.rb +19 -3
  18. data/lib/tina4/drivers/mssql_driver.rb +3 -3
  19. data/lib/tina4/drivers/mysql_driver.rb +4 -4
  20. data/lib/tina4/drivers/postgres_driver.rb +9 -2
  21. data/lib/tina4/drivers/sqlite_driver.rb +1 -1
  22. data/lib/tina4/env.rb +42 -2
  23. data/lib/tina4/error_overlay.rb +252 -0
  24. data/lib/tina4/events.rb +90 -0
  25. data/lib/tina4/field_types.rb +4 -0
  26. data/lib/tina4/frond.rb +1336 -0
  27. data/lib/tina4/gallery/auth/meta.json +1 -0
  28. data/lib/tina4/gallery/auth/src/routes/api/gallery_auth.rb +114 -0
  29. data/lib/tina4/gallery/database/meta.json +1 -0
  30. data/lib/tina4/gallery/database/src/routes/api/gallery_db.rb +43 -0
  31. data/lib/tina4/gallery/error-overlay/meta.json +1 -0
  32. data/lib/tina4/gallery/error-overlay/src/routes/api/gallery_crash.rb +17 -0
  33. data/lib/tina4/gallery/orm/meta.json +1 -0
  34. data/lib/tina4/gallery/orm/src/routes/api/gallery_products.rb +16 -0
  35. data/lib/tina4/gallery/queue/meta.json +1 -0
  36. data/lib/tina4/gallery/queue/src/routes/api/gallery_queue.rb +27 -0
  37. data/lib/tina4/gallery/rest-api/meta.json +1 -0
  38. data/lib/tina4/gallery/rest-api/src/routes/api/gallery_hello.rb +14 -0
  39. data/lib/tina4/gallery/templates/meta.json +1 -0
  40. data/lib/tina4/gallery/templates/src/routes/gallery_page.rb +12 -0
  41. data/lib/tina4/gallery/templates/src/templates/gallery_page.twig +257 -0
  42. data/lib/tina4/health.rb +39 -0
  43. data/lib/tina4/html_element.rb +148 -0
  44. data/lib/tina4/localization.rb +2 -2
  45. data/lib/tina4/log.rb +203 -0
  46. data/lib/tina4/messenger.rb +484 -0
  47. data/lib/tina4/migration.rb +132 -29
  48. data/lib/tina4/orm.rb +337 -31
  49. data/lib/tina4/public/css/tina4.css +178 -1
  50. data/lib/tina4/public/css/tina4.min.css +1 -2
  51. data/lib/tina4/public/favicon.ico +0 -0
  52. data/lib/tina4/public/images/logo.svg +5 -0
  53. data/lib/tina4/public/images/tina4-logo-icon.webp +0 -0
  54. data/lib/tina4/public/js/frond.min.js +420 -0
  55. data/lib/tina4/public/js/tina4-dev-admin.min.js +367 -0
  56. data/lib/tina4/public/js/tina4.min.js +93 -0
  57. data/lib/tina4/public/swagger/index.html +90 -0
  58. data/lib/tina4/public/swagger/oauth2-redirect.html +63 -0
  59. data/lib/tina4/queue.rb +40 -4
  60. data/lib/tina4/queue_backends/lite_backend.rb +88 -0
  61. data/lib/tina4/rack_app.rb +314 -23
  62. data/lib/tina4/rate_limiter.rb +123 -0
  63. data/lib/tina4/request.rb +61 -15
  64. data/lib/tina4/response.rb +54 -24
  65. data/lib/tina4/response_cache.rb +134 -0
  66. data/lib/tina4/router.rb +90 -15
  67. data/lib/tina4/scss_compiler.rb +2 -2
  68. data/lib/tina4/seeder.rb +56 -61
  69. data/lib/tina4/service_runner.rb +303 -0
  70. data/lib/tina4/session.rb +85 -0
  71. data/lib/tina4/session_handlers/mongo_handler.rb +1 -1
  72. data/lib/tina4/session_handlers/valkey_handler.rb +43 -0
  73. data/lib/tina4/shutdown.rb +84 -0
  74. data/lib/tina4/sql_translation.rb +295 -0
  75. data/lib/tina4/template.rb +36 -6
  76. data/lib/tina4/templates/base.twig +2 -2
  77. data/lib/tina4/templates/errors/302.twig +14 -0
  78. data/lib/tina4/templates/errors/401.twig +9 -0
  79. data/lib/tina4/templates/errors/403.twig +22 -15
  80. data/lib/tina4/templates/errors/404.twig +22 -15
  81. data/lib/tina4/templates/errors/500.twig +31 -15
  82. data/lib/tina4/templates/errors/502.twig +9 -0
  83. data/lib/tina4/templates/errors/503.twig +12 -0
  84. data/lib/tina4/templates/errors/base.twig +37 -0
  85. data/lib/tina4/version.rb +1 -1
  86. data/lib/tina4/webserver.rb +28 -18
  87. data/lib/tina4.rb +57 -21
  88. metadata +51 -19
  89. data/lib/tina4/public/js/tina4.js +0 -134
  90. data/lib/tina4/public/js/tina4helper.js +0 -387
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Tina4 Events — Simple observer pattern for decoupled communication.
4
+ #
5
+ # Zero-dependency event system. Fire events, register listeners.
6
+ #
7
+ # Tina4::Events.on("user.created") { |user| puts "Welcome #{user[:name]}!" }
8
+ # Tina4::Events.on("user.created") { |user| puts "New signup: #{user[:email]}" }
9
+ # Tina4::Events.emit("user.created", { name: "Alice", email: "alice@example.com" })
10
+ #
11
+ # One-time listeners:
12
+ #
13
+ # Tina4::Events.once("app.ready") { puts "App started!" }
14
+ #
15
+ module Tina4
16
+ class Events
17
+ @listeners = Hash.new { |h, k| h[k] = [] }
18
+
19
+ class << self
20
+ # Register a listener for an event.
21
+ #
22
+ # Tina4::Events.on("user.created") { |user| ... }
23
+ # Tina4::Events.on("user.created", priority: 10) { |user| ... }
24
+ #
25
+ # Higher priority runs first.
26
+ def on(event, priority: 0, &block)
27
+ raise ArgumentError, "block required" unless block_given?
28
+
29
+ @listeners[event] << { priority: priority, callback: block, once: false }
30
+ @listeners[event].sort_by! { |entry| -entry[:priority] }
31
+ block
32
+ end
33
+
34
+ # Register a listener that fires only once then auto-removes.
35
+ #
36
+ # Tina4::Events.once("app.ready") { puts "App started!" }
37
+ #
38
+ def once(event, priority: 0, &block)
39
+ raise ArgumentError, "block required" unless block_given?
40
+
41
+ @listeners[event] << { priority: priority, callback: block, once: true }
42
+ @listeners[event].sort_by! { |entry| -entry[:priority] }
43
+ block
44
+ end
45
+
46
+ # Remove a specific listener, or all listeners for an event.
47
+ #
48
+ # Tina4::Events.off("user.created", handler) # remove specific
49
+ # Tina4::Events.off("user.created") # remove all for event
50
+ #
51
+ def off(event, callback = nil)
52
+ if callback.nil?
53
+ @listeners.delete(event)
54
+ else
55
+ @listeners[event].reject! { |entry| entry[:callback] == callback }
56
+ end
57
+ end
58
+
59
+ # Fire an event synchronously. Returns array of listener results.
60
+ #
61
+ # results = Tina4::Events.emit("user.created", user_data)
62
+ #
63
+ def emit(event, *args)
64
+ entries = @listeners[event].dup
65
+ results = []
66
+ entries.each do |entry|
67
+ # Remove one-time listeners before calling so re-entrant emits are safe
68
+ @listeners[event].delete(entry) if entry[:once]
69
+ results << entry[:callback].call(*args)
70
+ end
71
+ results
72
+ end
73
+
74
+ # Get all listener callbacks for an event (in priority order).
75
+ def listeners(event)
76
+ @listeners[event].map { |entry| entry[:callback] }
77
+ end
78
+
79
+ # List all registered event names.
80
+ def events
81
+ @listeners.keys
82
+ end
83
+
84
+ # Remove all listeners for all events.
85
+ def clear
86
+ @listeners.clear
87
+ end
88
+ end
89
+ end
90
+ end
@@ -46,6 +46,10 @@ module Tina4
46
46
  nullable: nullable, default: default)
47
47
  end
48
48
 
49
+ def numeric_field(name, nullable: true, default: nil)
50
+ register_field(name, :float, nullable: nullable, default: default)
51
+ end
52
+
49
53
  def boolean_field(name, nullable: true, default: nil)
50
54
  register_field(name, :boolean, nullable: nullable, default: default)
51
55
  end