zui 0.0.6 → 0.0.8
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/ControlNode.qml +2 -909
- data/Desktop.qml +3 -0
- data/README.md +391 -66
- data/Service.qml +14 -2
- data/lib/zui/application_runtime.rb +43 -0
- data/lib/zui/cli.rb +62 -12
- data/lib/zui/component_registry.rb +14 -1
- data/lib/zui/dist_config.rb +180 -0
- data/lib/zui/dist_packager.rb +366 -0
- data/lib/zui/distribution.rb +184 -18
- data/lib/zui/full_runtime.rb +241 -0
- data/lib/zui/generator.rb +49 -0
- data/lib/zui/lite_entry.rb +11 -0
- data/lib/zui/lite_runtime.rb +119 -0
- data/lib/zui/lite_source.rb +38 -0
- data/lib/zui/lite_support.rb +21 -0
- data/lib/zui/node.rb +23 -2
- data/lib/zui/tree_shaker.rb +527 -0
- data/lib/zui.rb +8 -1
- metadata +10 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
module Zui
|
|
7
|
+
class LiteRuntime < Client
|
|
8
|
+
FORMAT = 1
|
|
9
|
+
MRUBY_VERSION = "4.0.0"
|
|
10
|
+
MRUBY_REVISION = "831da26b9021de0369d17b71b5667e2941a1a32d"
|
|
11
|
+
MRUBY_JSON_REVISION = "f99d9428025469f2400f93c53b185f65f963e507"
|
|
12
|
+
|
|
13
|
+
def root
|
|
14
|
+
override = @environment["ZUI_LITE_RUNTIME_ROOT"]
|
|
15
|
+
return File.expand_path(override) if override && !override.empty?
|
|
16
|
+
|
|
17
|
+
File.join(cache_root, "zui", "runtimes", version, platform.id, "lite")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def archive_name = "zui-runtime-lite-#{platform.id}.tar.gz"
|
|
21
|
+
|
|
22
|
+
def configure!
|
|
23
|
+
return root if configured?
|
|
24
|
+
if client_root_override?
|
|
25
|
+
raise ArgumentError, "ZUI_LITE_RUNTIME_ROOT is not a valid configured lite runtime: #{root}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def archive_url
|
|
32
|
+
override = @environment["ZUI_LITE_RUNTIME_ARCHIVE"]
|
|
33
|
+
return File.expand_path(override) if override && !override.empty?
|
|
34
|
+
|
|
35
|
+
URI.join("#{release_base_url}/", archive_name)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def checksum_url
|
|
39
|
+
override = @environment["ZUI_LITE_RUNTIME_CHECKSUM"]
|
|
40
|
+
return File.expand_path(override) if override && !override.empty?
|
|
41
|
+
|
|
42
|
+
source = archive_url
|
|
43
|
+
source.is_a?(URI) ? URI("#{source}.sha256") : "#{source}.sha256"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def install(project:, destination:)
|
|
47
|
+
unless configured?
|
|
48
|
+
raise ArgumentError,
|
|
49
|
+
"Zui lite runtime is not configured for #{platform.id}; run `zui doctor --fix` before bundling"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
copy_to(destination)
|
|
53
|
+
File.write(File.join(destination, "app.rb"), LiteSource.new(project:).call)
|
|
54
|
+
ApplicationRuntime.new(
|
|
55
|
+
engine: "mruby", version: manifest.fetch("engine_version"),
|
|
56
|
+
executable: manifest.fetch("executable"), program: "app.rb", load_path: ""
|
|
57
|
+
).write(destination)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def validate!(directory)
|
|
63
|
+
manifest_path = File.join(directory, "lite-runtime.json")
|
|
64
|
+
raise ArgumentError, "Zui lite runtime manifest not found: #{manifest_path}" unless File.file?(manifest_path)
|
|
65
|
+
raise ArgumentError, "Zui lite runtime manifest is too large" if File.size(manifest_path) > 65_536
|
|
66
|
+
|
|
67
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
68
|
+
raise ArgumentError, "invalid Zui lite runtime manifest root" unless manifest.is_a?(Hash)
|
|
69
|
+
expected = {
|
|
70
|
+
"format" => FORMAT,
|
|
71
|
+
"framework" => "zui",
|
|
72
|
+
"zui_version" => version,
|
|
73
|
+
"platform" => platform.id,
|
|
74
|
+
"engine" => "mruby",
|
|
75
|
+
"engine_version" => MRUBY_VERSION,
|
|
76
|
+
"engine_revision" => MRUBY_REVISION,
|
|
77
|
+
"json_revision" => MRUBY_JSON_REVISION,
|
|
78
|
+
"payload" => ["mruby"]
|
|
79
|
+
}
|
|
80
|
+
expected.each do |key, value|
|
|
81
|
+
actual = manifest[key]
|
|
82
|
+
unless actual == value
|
|
83
|
+
raise ArgumentError,
|
|
84
|
+
"invalid Zui lite runtime #{key}: expected #{value.inspect}, got #{actual.inspect}"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
required_paths = manifest["required_paths"]
|
|
89
|
+
unless required_paths.is_a?(Array) && !required_paths.empty? &&
|
|
90
|
+
required_paths.all? { |path| path.is_a?(String) }
|
|
91
|
+
raise ArgumentError, "invalid Zui lite runtime required paths"
|
|
92
|
+
end
|
|
93
|
+
required_paths.each do |path|
|
|
94
|
+
relative = safe_manifest_path!(path, "lite runtime required path")
|
|
95
|
+
resolved = File.join(directory, relative)
|
|
96
|
+
raise ArgumentError, "Zui lite runtime required path is missing: #{resolved}" unless File.exist?(resolved)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
relative = safe_manifest_path!(manifest["executable"], "lite runtime executable")
|
|
100
|
+
executable = File.join(directory, relative)
|
|
101
|
+
unless File.file?(executable) && executable_for_target?(executable)
|
|
102
|
+
raise ArgumentError, "Zui lite runtime executable is missing or not executable: #{executable}"
|
|
103
|
+
end
|
|
104
|
+
manifest
|
|
105
|
+
rescue JSON::ParserError => error
|
|
106
|
+
raise ArgumentError, "invalid Zui lite runtime manifest: #{error.message}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def release_base_url
|
|
110
|
+
@release_base_url || @environment["ZUI_LITE_RUNTIME_BASE_URL"] ||
|
|
111
|
+
"https://github.com/AdamMusa/zui/releases/download/v#{version}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def client_root_override?
|
|
115
|
+
value = @environment["ZUI_LITE_RUNTIME_ROOT"]
|
|
116
|
+
value && !value.empty?
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Zui
|
|
4
|
+
class LiteSource
|
|
5
|
+
RUNTIME_FILES = %w[
|
|
6
|
+
lite_support.rb protocol.rb value.rb state_store.rb node.rb animation.rb scheduler.rb
|
|
7
|
+
component_registry.rb components.rb builder.rb application.rb lite_entry.rb
|
|
8
|
+
].freeze
|
|
9
|
+
REQUIRE = /^\s*require\s*(?:\(\s*)?["']([^"']+)["']/
|
|
10
|
+
|
|
11
|
+
def initialize(project:, framework_root: FRAMEWORK_ROOT)
|
|
12
|
+
@project = File.expand_path(project)
|
|
13
|
+
@framework_root = File.expand_path(framework_root)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
application = SourceBundle.new(
|
|
18
|
+
File.join(@project, "main.rb"), root: @project, embedded_frameworks: ["zui"]
|
|
19
|
+
).call
|
|
20
|
+
external = application.scan(REQUIRE).flatten.uniq
|
|
21
|
+
unless external.empty?
|
|
22
|
+
raise ArgumentError,
|
|
23
|
+
"--lite does not support CRuby gem requires (#{external.join(', ')}); use --full"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
runtime = RUNTIME_FILES.map do |name|
|
|
27
|
+
path = File.join(@framework_root, "lib", "zui", name)
|
|
28
|
+
raise ArgumentError, "lite runtime source is missing: #{path}" unless File.file?(path)
|
|
29
|
+
|
|
30
|
+
source = File.readlines(path).reject { |line| REQUIRE.match?(line) }.join
|
|
31
|
+
"# runtime: #{name}\n#{source}"
|
|
32
|
+
end
|
|
33
|
+
runtime << "module Zui\n VERSION = #{VERSION.dump}\nend"
|
|
34
|
+
runtime << application
|
|
35
|
+
"#{runtime.join("\n\n")}\n"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
unless Object.const_defined?(:Mutex)
|
|
4
|
+
class Mutex
|
|
5
|
+
def synchronize
|
|
6
|
+
yield
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
unless Object.const_defined?(:ConditionVariable)
|
|
12
|
+
class ConditionVariable
|
|
13
|
+
def wait(_mutex, _seconds = nil)
|
|
14
|
+
self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def broadcast
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/zui/node.rb
CHANGED
|
@@ -25,6 +25,27 @@ module Zui
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
Binding
|
|
29
|
-
|
|
28
|
+
class Binding
|
|
29
|
+
attr_accessor :last_value
|
|
30
|
+
attr_reader :node, :property, :reader, :animation
|
|
31
|
+
|
|
32
|
+
def initialize(node:, property:, reader:, last_value:, animation:)
|
|
33
|
+
@node = node
|
|
34
|
+
@property = property
|
|
35
|
+
@reader = reader
|
|
36
|
+
@last_value = last_value
|
|
37
|
+
@animation = animation
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class StructuralBinding
|
|
42
|
+
attr_accessor :last_children
|
|
43
|
+
attr_reader :node, :renderer
|
|
44
|
+
|
|
45
|
+
def initialize(node:, renderer:, last_children:)
|
|
46
|
+
@node = node
|
|
47
|
+
@renderer = renderer
|
|
48
|
+
@last_children = last_children
|
|
49
|
+
end
|
|
50
|
+
end
|
|
30
51
|
end
|