pakyow-core 1.0.0.rc5 → 1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/pakyow/{environment/actions → actions}/dispatch.rb +0 -0
- data/lib/pakyow/{environment/actions → actions}/input_parser.rb +0 -0
- data/lib/pakyow/{environment/actions → actions}/logger.rb +0 -0
- data/lib/pakyow/{environment/actions → actions}/normalizer.rb +0 -0
- data/lib/pakyow/{app.rb → application.rb} +26 -26
- data/lib/pakyow/application/behavior/aspects.rb +51 -0
- data/lib/pakyow/application/behavior/endpoints.rb +43 -0
- data/lib/pakyow/application/behavior/frameworks.rb +47 -0
- data/lib/pakyow/application/behavior/helpers.rb +107 -0
- data/lib/pakyow/{environment → application}/behavior/initializers.rb +4 -4
- data/lib/pakyow/application/behavior/isolating.rb +71 -0
- data/lib/pakyow/application/behavior/operations.rb +49 -0
- data/lib/pakyow/application/behavior/pipeline.rb +60 -0
- data/lib/pakyow/application/behavior/plugins.rb +151 -0
- data/lib/pakyow/application/behavior/rescuing.rb +53 -0
- data/lib/pakyow/application/behavior/restarting.rb +72 -0
- data/lib/pakyow/application/behavior/sessions.rb +38 -0
- data/lib/pakyow/{behavior → application}/config.rb +1 -1
- data/lib/pakyow/{app → application}/connection.rb +4 -4
- data/lib/pakyow/{app → application}/connection/behavior/session.rb +1 -1
- data/lib/pakyow/{app → application}/connection/behavior/values.rb +1 -1
- data/lib/pakyow/{app → application}/connection/behavior/verifier.rb +1 -1
- data/lib/pakyow/{app → application}/connection/session/base.rb +1 -1
- data/lib/pakyow/{app → application}/connection/session/cookie.rb +2 -2
- data/lib/pakyow/application/helpers/app.rb +30 -0
- data/lib/pakyow/application/helpers/connection.rb +47 -0
- data/lib/pakyow/behavior/initializers.rb +3 -3
- data/lib/pakyow/behavior/input_parsing.rb +55 -0
- data/lib/pakyow/behavior/plugins.rb +3 -130
- data/lib/pakyow/behavior/restarting.rb +28 -46
- data/lib/pakyow/behavior/running.rb +127 -0
- data/lib/pakyow/behavior/silencing.rb +21 -0
- data/lib/pakyow/behavior/timezone.rb +19 -0
- data/lib/pakyow/behavior/verification.rb +1 -1
- data/lib/pakyow/behavior/verifier.rb +30 -0
- data/lib/pakyow/behavior/watching.rb +73 -0
- data/lib/pakyow/config.rb +168 -0
- data/lib/pakyow/environment.rb +31 -31
- data/lib/pakyow/helper.rb +9 -0
- data/lib/pakyow/loader.rb +7 -1
- data/lib/pakyow/plugin.rb +22 -21
- metadata +42 -42
- data/lib/pakyow/behavior/aspects.rb +0 -49
- data/lib/pakyow/behavior/endpoints.rb +0 -41
- data/lib/pakyow/behavior/frameworks.rb +0 -45
- data/lib/pakyow/behavior/helpers.rb +0 -108
- data/lib/pakyow/behavior/isolating.rb +0 -69
- data/lib/pakyow/behavior/operations.rb +0 -47
- data/lib/pakyow/behavior/pipeline.rb +0 -58
- data/lib/pakyow/behavior/rescuing.rb +0 -51
- data/lib/pakyow/behavior/sessions.rb +0 -36
- data/lib/pakyow/environment/behavior/config.rb +0 -172
- data/lib/pakyow/environment/behavior/input_parsing.rb +0 -57
- data/lib/pakyow/environment/behavior/plugins.rb +0 -23
- data/lib/pakyow/environment/behavior/restarting.rb +0 -54
- data/lib/pakyow/environment/behavior/running.rb +0 -129
- data/lib/pakyow/environment/behavior/silencing.rb +0 -23
- data/lib/pakyow/environment/behavior/timezone.rb +0 -21
- data/lib/pakyow/environment/behavior/verifier.rb +0 -32
- data/lib/pakyow/environment/behavior/watching.rb +0 -75
- data/lib/pakyow/helpers/app.rb +0 -28
- data/lib/pakyow/helpers/connection.rb +0 -45
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
require "pakyow/operation"
|
6
|
+
|
7
|
+
module Pakyow
|
8
|
+
class Application
|
9
|
+
module Behavior
|
10
|
+
# Adds support for operations.
|
11
|
+
#
|
12
|
+
module Operations
|
13
|
+
class Lookup
|
14
|
+
def initialize(operations:, app:)
|
15
|
+
operations.each do |operation|
|
16
|
+
define_singleton_method operation.__object_name.name do |values = {}, &block|
|
17
|
+
(block ? Class.new(operation, &block) : operation).new(app: app, **values).perform
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
extend Support::Extension
|
24
|
+
|
25
|
+
apply_extension do
|
26
|
+
on "load" do
|
27
|
+
load_aspect(:operations)
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :operations
|
31
|
+
after "initialize" do
|
32
|
+
@operations = Lookup.new(operations: state(:operation), app: self)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class_methods do
|
37
|
+
# Define operations as stateful when an app is defined.
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
def make(*)
|
41
|
+
super.tap do |new_class|
|
42
|
+
new_class.stateful :operation, Operation
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
class Application
|
7
|
+
module Behavior
|
8
|
+
# Loads default pipeline actions based on included frameworks.
|
9
|
+
#
|
10
|
+
module Pipeline
|
11
|
+
extend Support::Extension
|
12
|
+
|
13
|
+
apply_extension do
|
14
|
+
# We set the priority very low here in case initialize hooks in other frameworks define
|
15
|
+
# state that should be loaded into the pipeline (e.g. controllers).
|
16
|
+
#
|
17
|
+
after "initialize", "initialize.pipeline", priority: -10 do
|
18
|
+
self.class.__pipeline.dup.tap do |pipeline|
|
19
|
+
load_pipeline_defaults(pipeline)
|
20
|
+
@__pipeline = pipeline.callable(self)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def load_pipeline_defaults(pipeline)
|
28
|
+
if self.class.includes_framework?(:assets)
|
29
|
+
pipeline.action(Actions::Assets::Public, self)
|
30
|
+
pipeline.action(Actions::Assets::Process)
|
31
|
+
end
|
32
|
+
|
33
|
+
if self.class.includes_framework?(:realtime) && Pakyow.config.realtime.server && !is_a?(Plugin)
|
34
|
+
pipeline.action(Actions::Realtime::Upgrader)
|
35
|
+
end
|
36
|
+
|
37
|
+
if self.class.includes_framework?(:routing) && !Pakyow.env?(:prototype)
|
38
|
+
state(:controller).each do |controller|
|
39
|
+
pipeline.action(controller, self)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if instance_variable_defined?(:@plugs)
|
44
|
+
@plugs.each do |plug_instance|
|
45
|
+
pipeline.action(plug_instance)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if self.class.includes_framework?(:presenter)
|
50
|
+
pipeline.action(Actions::Presenter::AutoRender)
|
51
|
+
end
|
52
|
+
|
53
|
+
if self.class.includes_framework?(:routing) && !Pakyow.env?(:prototype) && !is_a?(Plugin)
|
54
|
+
pipeline.action(Actions::Routing::RespondMissing)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/errors"
|
4
|
+
|
5
|
+
require "pakyow/support/deep_dup"
|
6
|
+
require "pakyow/support/extension"
|
7
|
+
|
8
|
+
require "pakyow/plugin/lookup"
|
9
|
+
|
10
|
+
module Pakyow
|
11
|
+
class Application
|
12
|
+
module Behavior
|
13
|
+
# @api private
|
14
|
+
module Plugins
|
15
|
+
extend Support::Extension
|
16
|
+
|
17
|
+
using Support::DeepDup
|
18
|
+
|
19
|
+
attr_reader :plugs
|
20
|
+
|
21
|
+
def plug(name, instance = :default)
|
22
|
+
@plugs.find { |plug|
|
23
|
+
plug.class.plugin_name == name && plug.class.__object_name.namespace.parts.last == instance
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
apply_extension do
|
28
|
+
class_state :__plugs, default: [], inheritable: true
|
29
|
+
|
30
|
+
# Create a dynamic helper that allows plugin helpers to be called in context of a specific plug.
|
31
|
+
#
|
32
|
+
on "initialize" do
|
33
|
+
self.class.register_helper :passive, Module.new {
|
34
|
+
Pakyow.plugins.keys.map.each do |plugin_name|
|
35
|
+
define_method plugin_name do |plug = :default|
|
36
|
+
app.plugs.send(plugin_name, plug).helper_caller(
|
37
|
+
app.class.included_helper_context(self),
|
38
|
+
@connection,
|
39
|
+
self
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
# Setting priority to low gives the app a chance to do any pre-loading
|
47
|
+
# that might affect how plugins are setup.
|
48
|
+
#
|
49
|
+
after "initialize", "load.plugins", priority: :low do
|
50
|
+
@plugs = Plugin::Lookup.new([])
|
51
|
+
|
52
|
+
self.class.__plugs.each do |plug|
|
53
|
+
if self.class.includes_framework?(:presenter)
|
54
|
+
require "pakyow/plugin/helpers/presenter/rendering"
|
55
|
+
plug.register_helper :passive, Plugin::Helpers::Presenter::Rendering
|
56
|
+
end
|
57
|
+
|
58
|
+
# Include frameworks from app.
|
59
|
+
#
|
60
|
+
plug.include_frameworks(
|
61
|
+
*self.class.config.loaded_frameworks
|
62
|
+
)
|
63
|
+
|
64
|
+
# Copy settings from the app config.
|
65
|
+
#
|
66
|
+
plug.config.instance_variable_set(
|
67
|
+
:@__settings, config.__settings.deep_dup.merge(plug.config.__settings)
|
68
|
+
)
|
69
|
+
|
70
|
+
# Copy defaults from the app config.
|
71
|
+
#
|
72
|
+
plug.config.instance_variable_set(
|
73
|
+
:@__defaults, config.__defaults.deep_dup.merge(plug.config.__defaults)
|
74
|
+
)
|
75
|
+
|
76
|
+
# Copy groups from the app config.
|
77
|
+
#
|
78
|
+
plug.config.instance_variable_set(
|
79
|
+
:@__groups, config.__groups.deep_dup.merge(plug.config.__groups)
|
80
|
+
)
|
81
|
+
|
82
|
+
# Override config values that require a specific value.
|
83
|
+
#
|
84
|
+
full_name = [plug.plugin_name]
|
85
|
+
unless plug.__object_name.namespace.parts.last == :default
|
86
|
+
full_name << plug.__object_name.namespace.parts.last
|
87
|
+
end
|
88
|
+
|
89
|
+
plug.config.name = full_name.join("_").to_sym
|
90
|
+
|
91
|
+
# Create a dynamic helper that allows plugin helpers to be called in context of a specific plug.
|
92
|
+
#
|
93
|
+
plug.register_helper :passive, Module.new {
|
94
|
+
Pakyow.plugins.keys.map.each do |plugin_name|
|
95
|
+
define_method plugin_name do |instance_name = :default|
|
96
|
+
app.parent.plugs.send(plugin_name, instance_name).helper_caller(
|
97
|
+
app.class.included_helper_context(self),
|
98
|
+
@connection,
|
99
|
+
self
|
100
|
+
)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
}
|
104
|
+
|
105
|
+
# Finally, create the plugin instance.
|
106
|
+
#
|
107
|
+
@plugs << plug.new(self)
|
108
|
+
end
|
109
|
+
|
110
|
+
@plugs.finalize
|
111
|
+
end
|
112
|
+
|
113
|
+
after "boot" do
|
114
|
+
@plugs.each(&:booted)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class_methods do
|
119
|
+
attr_reader :__plugs
|
120
|
+
|
121
|
+
def plug(plugin_name, at: "/", as: :default, &block)
|
122
|
+
plugin_name = plugin_name.to_sym
|
123
|
+
|
124
|
+
unless plugin = Pakyow.plugins[plugin_name]
|
125
|
+
raise UnknownPlugin.new_with_message(
|
126
|
+
plugin: plugin_name
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
app = self
|
131
|
+
plug = plugin.make(
|
132
|
+
"plug",
|
133
|
+
within: Support::ObjectNamespace.new(
|
134
|
+
*__object_name.namespace.parts + [plugin_name, as]
|
135
|
+
),
|
136
|
+
mount_path: at,
|
137
|
+
) do
|
138
|
+
# Creates a connection subclass that other frameworks can safely extend.
|
139
|
+
#
|
140
|
+
isolate(app.isolated(:Connection))
|
141
|
+
|
142
|
+
instance_exec(&block) if block
|
143
|
+
end
|
144
|
+
|
145
|
+
@__plugs << plug
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
class Application
|
7
|
+
module Behavior
|
8
|
+
# Lets an app to be rescued from errors encountered during boot. Once rescued,
|
9
|
+
# an app returns a 500 response with the error that caused it to fail.
|
10
|
+
#
|
11
|
+
module Rescuing
|
12
|
+
extend Support::Extension
|
13
|
+
|
14
|
+
# Error the app was rescued from.
|
15
|
+
#
|
16
|
+
attr_reader :rescued
|
17
|
+
|
18
|
+
# Returns true if the app has been rescued.
|
19
|
+
#
|
20
|
+
def rescued?
|
21
|
+
instance_variable_defined?(:@rescued) && !!@rescued
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Enters rescue mode after logging the error.
|
27
|
+
#
|
28
|
+
def rescue!(error)
|
29
|
+
@rescued = error
|
30
|
+
|
31
|
+
performing :rescue do
|
32
|
+
Pakyow.logger.error(error)
|
33
|
+
|
34
|
+
message = <<~ERROR
|
35
|
+
#{self.class} failed to initialize.
|
36
|
+
|
37
|
+
#{error.message}
|
38
|
+
#{error.backtrace.join("\n")}
|
39
|
+
ERROR
|
40
|
+
|
41
|
+
# Override call to always return an errored response.
|
42
|
+
#
|
43
|
+
define_singleton_method :call do |connection|
|
44
|
+
connection.status = 500
|
45
|
+
connection.body = StringIO.new(message)
|
46
|
+
connection.halt
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
require "pakyow/support/silenceable"
|
6
|
+
Pakyow::Support::Silenceable.silence_warnings do
|
7
|
+
require "filewatcher"
|
8
|
+
end
|
9
|
+
|
10
|
+
require "pakyow/support/extension"
|
11
|
+
|
12
|
+
module Pakyow
|
13
|
+
class Application
|
14
|
+
module Behavior
|
15
|
+
# Handles triggering restarts in the parent process.
|
16
|
+
#
|
17
|
+
module Restarting
|
18
|
+
extend Support::Extension
|
19
|
+
|
20
|
+
apply_extension do
|
21
|
+
configurable :process do
|
22
|
+
setting :watched_paths, []
|
23
|
+
setting :excluded_paths, []
|
24
|
+
setting :restartable, false
|
25
|
+
|
26
|
+
defaults :development do
|
27
|
+
setting :restartable, true
|
28
|
+
end
|
29
|
+
|
30
|
+
defaults :prototype do
|
31
|
+
setting :restartable, true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
after "initialize" do
|
36
|
+
setup_for_restarting
|
37
|
+
end
|
38
|
+
|
39
|
+
# Setting up for restarting even after the app fails to initialize lets
|
40
|
+
# the developer fix the problem and let the server restart on its own.
|
41
|
+
#
|
42
|
+
after "rescue" do
|
43
|
+
setup_for_restarting
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def setup_for_restarting
|
50
|
+
if config.process.restartable
|
51
|
+
config.process.watched_paths << File.join(config.src, "**/*.rb")
|
52
|
+
config.process.watched_paths << File.join(config.lib, "**/*.rb")
|
53
|
+
|
54
|
+
# FIXME: this doesn't need to be hardcoded, but instead determined
|
55
|
+
# from the source location when registered with the environment
|
56
|
+
config.process.watched_paths << "./config/application.rb"
|
57
|
+
|
58
|
+
Thread.new do
|
59
|
+
Filewatcher.new(
|
60
|
+
config.process.watched_paths,
|
61
|
+
exclude: config.process.excluded_paths
|
62
|
+
).watch do |_path, _event|
|
63
|
+
FileUtils.mkdir_p "./tmp"
|
64
|
+
FileUtils.touch "./tmp/restart.txt"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
require "pakyow/support/inflector"
|
5
|
+
|
6
|
+
module Pakyow
|
7
|
+
class Application
|
8
|
+
module Behavior
|
9
|
+
module Sessions
|
10
|
+
extend Support::Extension
|
11
|
+
|
12
|
+
apply_extension do
|
13
|
+
attr_reader :session_object, :session_options
|
14
|
+
|
15
|
+
after "configure" do
|
16
|
+
if config.session.enabled
|
17
|
+
require "pakyow/application/connection/session/#{config.session.object}"
|
18
|
+
|
19
|
+
@session_object = Pakyow::Application::Connection::Session.const_get(
|
20
|
+
Support.inflector.classify(config.session.object)
|
21
|
+
)
|
22
|
+
|
23
|
+
@session_options = if config.session.respond_to?(config.session.object)
|
24
|
+
config.session.public_send(config.session.object)
|
25
|
+
else
|
26
|
+
{}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
rescue LoadError => error
|
30
|
+
# TODO: Improve this with a specific "session object missing" error.
|
31
|
+
#
|
32
|
+
raise error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -5,16 +5,16 @@ require "delegate"
|
|
5
5
|
require "pakyow/support/hookable"
|
6
6
|
|
7
7
|
module Pakyow
|
8
|
-
class
|
8
|
+
class Application
|
9
9
|
class Connection < SimpleDelegator
|
10
10
|
attr_reader :app
|
11
11
|
|
12
12
|
include Support::Hookable
|
13
13
|
events :initialize, :dup
|
14
14
|
|
15
|
-
require "pakyow/
|
16
|
-
require "pakyow/
|
17
|
-
require "pakyow/
|
15
|
+
require "pakyow/application/connection/behavior/session"
|
16
|
+
require "pakyow/application/connection/behavior/verifier"
|
17
|
+
require "pakyow/application/connection/behavior/values"
|
18
18
|
|
19
19
|
include Behavior::Session
|
20
20
|
include Behavior::Verifier
|