openui-rails 0.1.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 +7 -0
- data/AUDIT.md +102 -0
- data/CHANGELOG.md +71 -0
- data/CODE_OF_CONDUCT.md +37 -0
- data/CONFIGURATION.md +79 -0
- data/CONTRIBUTING.md +66 -0
- data/LICENSE +22 -0
- data/README.md +471 -0
- data/RELEASING.md +90 -0
- data/SECURITY.md +48 -0
- data/THIRD_PARTY_NOTICES.md +45 -0
- data/UPGRADING.md +26 -0
- data/app/controllers/openui/rails/actions_controller.rb +77 -0
- data/app/controllers/openui/rails/application_controller.rb +10 -0
- data/app/javascript/openui/rails/openui_controller.js +347 -0
- data/app/javascript/openui/rails/openui_envelope_controller.js +38 -0
- data/config/routes.rb +5 -0
- data/lib/generators/openui/install/install_generator.rb +62 -0
- data/lib/generators/openui/install/templates/config/initializers/openui.rb.tt +30 -0
- data/lib/generators/openui/install/templates/config/openui/README.md +24 -0
- data/lib/openui/rails/actions/dispatcher.rb +194 -0
- data/lib/openui/rails/actions/idempotency/memory_store.rb +64 -0
- data/lib/openui/rails/actions/invocation.rb +16 -0
- data/lib/openui/rails/actions/registry.rb +113 -0
- data/lib/openui/rails/actions/schema.rb +115 -0
- data/lib/openui/rails/actions/submission.rb +102 -0
- data/lib/openui/rails/actions.rb +18 -0
- data/lib/openui/rails/adapters/ruby_llm.rb +113 -0
- data/lib/openui/rails/configuration.rb +282 -0
- data/lib/openui/rails/engine.rb +46 -0
- data/lib/openui/rails/errors.rb +41 -0
- data/lib/openui/rails/json_value.rb +33 -0
- data/lib/openui/rails/library_manifest.rb +234 -0
- data/lib/openui/rails/message.rb +139 -0
- data/lib/openui/rails/prompt_builder.rb +115 -0
- data/lib/openui/rails/runtime_asset.rb +65 -0
- data/lib/openui/rails/runtime_package.rb +74 -0
- data/lib/openui/rails/stream/accumulator.rb +86 -0
- data/lib/openui/rails/stream/bridge.rb +193 -0
- data/lib/openui/rails/stream/broadcaster.rb +106 -0
- data/lib/openui/rails/stream/envelope.rb +159 -0
- data/lib/openui/rails/stream/transports/action_cable.rb +50 -0
- data/lib/openui/rails/stream/transports/memory.rb +33 -0
- data/lib/openui/rails/stream/transports/turbo_streams.rb +61 -0
- data/lib/openui/rails/stream/transports.rb +41 -0
- data/lib/openui/rails/surface.rb +150 -0
- data/lib/openui/rails/version.rb +5 -0
- data/lib/openui/rails/view_helper.rb +56 -0
- data/lib/openui/rails.rb +33 -0
- data/lib/tasks/openui.rake +16 -0
- metadata +125 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openui/rails/stream/transports/memory"
|
|
4
|
+
require "openui/rails/stream/transports/action_cable"
|
|
5
|
+
require "openui/rails/stream/transports/turbo_streams"
|
|
6
|
+
|
|
7
|
+
module OpenUI
|
|
8
|
+
module Rails
|
|
9
|
+
module Stream
|
|
10
|
+
# Transport wrappers for {Broadcaster}. Each responds to
|
|
11
|
+
# `#broadcast(envelope)` and is intentionally thin: sequencing, coalescing
|
|
12
|
+
# and size limits live in {Bridge}, not here.
|
|
13
|
+
module Transports
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
# Build a transport from a configured name.
|
|
17
|
+
#
|
|
18
|
+
# @param name [Symbol] :action_cable, :turbo / :turbo_streams or :memory
|
|
19
|
+
#
|
|
20
|
+
# @param options [Hash] forwarded to the transport constructor
|
|
21
|
+
#
|
|
22
|
+
# @return [ActionCable, TurboStreams, Memory]
|
|
23
|
+
#
|
|
24
|
+
# @raise [ConfigurationError] when the name is unsupported
|
|
25
|
+
def build(name, **options)
|
|
26
|
+
case name.to_sym
|
|
27
|
+
when :action_cable
|
|
28
|
+
ActionCable.new(options.delete(:stream_name), **options)
|
|
29
|
+
when :turbo, :turbo_streams
|
|
30
|
+
TurboStreams.new(options.delete(:stream), **options)
|
|
31
|
+
when :memory
|
|
32
|
+
Memory.new(**options)
|
|
33
|
+
else
|
|
34
|
+
raise ConfigurationError,
|
|
35
|
+
"unsupported transport #{name.inspect}; expected one of [:action_cable, :turbo, :memory]"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenUI
|
|
4
|
+
module Rails
|
|
5
|
+
# Immutable description of one mounted OpenUI surface.
|
|
6
|
+
#
|
|
7
|
+
# The host Rails app owns persistence; the Gem only needs a stable,
|
|
8
|
+
# opaque identifier plus the current revision and the source to render.
|
|
9
|
+
# A surface can be built explicitly or coerced from a host record that
|
|
10
|
+
# exposes `id` (and, optionally, `version`, `library_version`, `response`,
|
|
11
|
+
# `context`, `message_id`).
|
|
12
|
+
class Surface
|
|
13
|
+
# Surface values copied from an explicit object, hash, or host record.
|
|
14
|
+
ATTRIBUTES = %i[id version library_version response context streaming message_id].freeze
|
|
15
|
+
|
|
16
|
+
attr_reader(*ATTRIBUTES)
|
|
17
|
+
|
|
18
|
+
# Coerce a host record, hash, or existing surface into a new Surface.
|
|
19
|
+
# Non-nil overrides replace values extracted from the input.
|
|
20
|
+
#
|
|
21
|
+
# @param value [Surface, Hash, #id, nil]
|
|
22
|
+
#
|
|
23
|
+
# @param overrides [Hash] surface attribute overrides
|
|
24
|
+
#
|
|
25
|
+
# @return [Surface]
|
|
26
|
+
def self.coerce(value = nil, **overrides)
|
|
27
|
+
attributes = extract(value).merge(overrides.compact)
|
|
28
|
+
new(**attributes)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.extract(value)
|
|
32
|
+
case value
|
|
33
|
+
when nil then {}
|
|
34
|
+
when Surface then value.to_h
|
|
35
|
+
when Hash
|
|
36
|
+
ATTRIBUTES.each_with_object({}) do |key, attributes|
|
|
37
|
+
if value.key?(key)
|
|
38
|
+
attributes[key] = value[key]
|
|
39
|
+
elsif value.key?(key.to_s)
|
|
40
|
+
attributes[key] = value[key.to_s]
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
else extract_record(value)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
private_class_method :extract
|
|
47
|
+
|
|
48
|
+
def self.extract_record(record)
|
|
49
|
+
unless record.respond_to?(:id)
|
|
50
|
+
raise ArgumentError, "surface must respond to #id or be a Hash/#{name}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
ATTRIBUTES.each_with_object({ id: record.id }) do |attribute, memo|
|
|
54
|
+
memo[attribute] = record.public_send(attribute) if attribute != :id && record.respond_to?(attribute)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
private_class_method :extract_record
|
|
58
|
+
|
|
59
|
+
# Build an immutable surface snapshot for the browser mount.
|
|
60
|
+
#
|
|
61
|
+
# @param id [String, #to_s] stable opaque identifier
|
|
62
|
+
#
|
|
63
|
+
# @param version [Integer, nil] non-negative revision used for stale-action checks
|
|
64
|
+
#
|
|
65
|
+
# @param library_version [String, nil] fingerprint of the browser library manifest
|
|
66
|
+
#
|
|
67
|
+
# @param response [String, nil] OpenUI Lang source rendered by the browser
|
|
68
|
+
#
|
|
69
|
+
# @param context [Object, nil] JSON-compatible initial state
|
|
70
|
+
#
|
|
71
|
+
# @param streaming [Boolean] whether a response is still streaming
|
|
72
|
+
#
|
|
73
|
+
# @param message_id [String, nil] stream identity; defaults to id
|
|
74
|
+
#
|
|
75
|
+
# @return [Surface]
|
|
76
|
+
def initialize(id:, version: 0, library_version: nil, response: nil, context: nil,
|
|
77
|
+
streaming: false, message_id: nil)
|
|
78
|
+
raise ArgumentError, "surface id is required" if id.nil? || id.to_s.empty?
|
|
79
|
+
unless version.nil? || (version.is_a?(Integer) && version >= 0)
|
|
80
|
+
raise ArgumentError, "surface version must be a non-negative Integer"
|
|
81
|
+
end
|
|
82
|
+
raise ArgumentError, "surface response must be a String" unless response.nil? || response.is_a?(String)
|
|
83
|
+
|
|
84
|
+
@id = id.to_s.dup.freeze
|
|
85
|
+
@version = version || 0
|
|
86
|
+
@library_version = library_version&.to_s&.dup&.freeze
|
|
87
|
+
@response = response&.dup&.freeze
|
|
88
|
+
@context = JsonValue.copy(context)
|
|
89
|
+
@streaming = streaming ? true : false
|
|
90
|
+
@message_id = (message_id&.to_s || @id).dup.freeze
|
|
91
|
+
freeze
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Whether the host says this surface is still receiving a response.
|
|
95
|
+
#
|
|
96
|
+
# @return [Boolean]
|
|
97
|
+
def streaming? = @streaming
|
|
98
|
+
|
|
99
|
+
# Return the surface fields as a symbol-keyed hash.
|
|
100
|
+
#
|
|
101
|
+
# @return [Hash]
|
|
102
|
+
def to_h
|
|
103
|
+
{
|
|
104
|
+
id: id, version: version, library_version: library_version,
|
|
105
|
+
response: response, context: context, streaming: streaming, message_id: message_id
|
|
106
|
+
}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# The flat `data:` hash for the Stimulus mount element. Keys use
|
|
110
|
+
# underscores so Rails renders them as `data-openui-*` attributes; nil
|
|
111
|
+
# values are omitted so the controller can rely on presence.
|
|
112
|
+
#
|
|
113
|
+
# Every value is deliberately a String. DOM data attributes are strings,
|
|
114
|
+
# and Rails only JSON-coerces *non-String* values. This path broke on
|
|
115
|
+
# Rails 8.0 with json >= 3.1 (ActiveSupport passes a `quirks_mode:`
|
|
116
|
+
# keyword the gem removed). Emitting strings keeps rendering independent
|
|
117
|
+
# of ActiveSupport's JSON encoder.
|
|
118
|
+
#
|
|
119
|
+
# @param stream [Boolean] mark this mount as streaming
|
|
120
|
+
#
|
|
121
|
+
# @param actions_endpoint [String] host engine action URL
|
|
122
|
+
#
|
|
123
|
+
# @param initial_state [Object, nil] JSON-compatible state override
|
|
124
|
+
#
|
|
125
|
+
# @return [Hash] HTML data attributes with string values
|
|
126
|
+
def to_mount_data(stream: false, actions_endpoint:, initial_state: nil)
|
|
127
|
+
{
|
|
128
|
+
controller: "openui",
|
|
129
|
+
openui_surface_id: id,
|
|
130
|
+
openui_message_id: message_id,
|
|
131
|
+
openui_version: version.to_s,
|
|
132
|
+
openui_library_version: library_version,
|
|
133
|
+
openui_streaming: (streaming? || stream) ? "true" : "false",
|
|
134
|
+
openui_actions_url: actions_endpoint,
|
|
135
|
+
openui_response: response,
|
|
136
|
+
openui_stream_byte_limit: OpenUI::Rails.configuration.stream_byte_limit.to_s,
|
|
137
|
+
openui_initial_state: encode_state(initial_state || context)
|
|
138
|
+
}.compact
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
private
|
|
142
|
+
|
|
143
|
+
def encode_state(state)
|
|
144
|
+
return nil if state.nil?
|
|
145
|
+
|
|
146
|
+
state.is_a?(String) ? state : JSON.generate(state)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenUI
|
|
4
|
+
module Rails
|
|
5
|
+
# View helper that emits the escaped DOM mount the Stimulus controller
|
|
6
|
+
# connects to. It renders no OpenUI UI itself: the browser runtime owns
|
|
7
|
+
# rendering, Rails owns the opaque identifier and revision.
|
|
8
|
+
module ViewHelper
|
|
9
|
+
# Include once in the host layout's head. The pinned bundle requires its
|
|
10
|
+
# stylesheet; it is not injected by JavaScript or repeated per surface.
|
|
11
|
+
def openui_stylesheet_tag
|
|
12
|
+
stylesheet_link_tag RuntimeAsset.stylesheet_url,
|
|
13
|
+
integrity: RuntimeAsset.stylesheet_integrity, crossorigin: "anonymous"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Render a mount element for a surface.
|
|
17
|
+
#
|
|
18
|
+
# @param surface [Surface, #id, nil] a Surface, a host record, or nil when
|
|
19
|
+
# `response`/`id` are supplied directly
|
|
20
|
+
# @param stream [Boolean] mark the surface as still streaming
|
|
21
|
+
# @param label [String, nil] accessible name; when given the mount is
|
|
22
|
+
# exposed as a `region` landmark so assistive tech can find it
|
|
23
|
+
# @param options [Hash] overrides forwarded to {Surface.coerce}
|
|
24
|
+
# @return [ActiveSupport::SafeBuffer]
|
|
25
|
+
def openui_surface(surface = nil, stream: false, dom_id: nil, initial_state: nil, label: nil, **options)
|
|
26
|
+
surface ||= options.delete(:surface)
|
|
27
|
+
surface = Surface.coerce(surface, **options)
|
|
28
|
+
fingerprint = OpenUI::Rails.configuration.library_fingerprint
|
|
29
|
+
if fingerprint && surface.library_version && fingerprint != surface.library_version
|
|
30
|
+
raise LibraryVersionError, "surface targets a different library; regenerate it with the configured library"
|
|
31
|
+
end
|
|
32
|
+
data = surface.to_mount_data(
|
|
33
|
+
stream: stream,
|
|
34
|
+
actions_endpoint: OpenUI::Rails.configuration.actions_endpoint,
|
|
35
|
+
initial_state: initial_state
|
|
36
|
+
).merge(RuntimeAsset.mount_data)
|
|
37
|
+
data[:openui_library_fingerprint] = fingerprint if fingerprint
|
|
38
|
+
|
|
39
|
+
# `aria-busy` tells assistive tech the region is still being updated, so
|
|
40
|
+
# a streaming surface is not announced mid-flight. The controller keeps
|
|
41
|
+
# it in sync as envelopes complete.
|
|
42
|
+
aria = { busy: surface.streaming? || stream }
|
|
43
|
+
aria[:label] = label if label
|
|
44
|
+
|
|
45
|
+
tag.div(
|
|
46
|
+
"",
|
|
47
|
+
id: dom_id || "openui-surface-#{surface.id}",
|
|
48
|
+
class: "openui-surface",
|
|
49
|
+
role: label ? "region" : nil,
|
|
50
|
+
data: data,
|
|
51
|
+
aria: aria
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/openui/rails.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openui/rails/version"
|
|
4
|
+
|
|
5
|
+
module OpenUI
|
|
6
|
+
# Rails integration for Thesys OpenUI Lang.
|
|
7
|
+
#
|
|
8
|
+
# This is an *unofficial* integration: it does not port or fork the OpenUI
|
|
9
|
+
# parser/renderer, it wires the official, version-pinned JavaScript runtime
|
|
10
|
+
# into a Rails engine and keeps Rails authoritative for auth, tenancy and
|
|
11
|
+
# persistence.
|
|
12
|
+
module Rails
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
require "openui/rails/errors"
|
|
17
|
+
require "openui/rails/json_value"
|
|
18
|
+
require "openui/rails/library_manifest"
|
|
19
|
+
require "openui/rails/prompt_builder"
|
|
20
|
+
require "openui/rails/message"
|
|
21
|
+
require "openui/rails/stream/envelope"
|
|
22
|
+
require "openui/rails/stream/accumulator"
|
|
23
|
+
require "openui/rails/stream/bridge"
|
|
24
|
+
require "openui/rails/stream/broadcaster"
|
|
25
|
+
require "openui/rails/stream/transports"
|
|
26
|
+
require "openui/rails/actions"
|
|
27
|
+
require "openui/rails/adapters/ruby_llm"
|
|
28
|
+
require "openui/rails/runtime_asset"
|
|
29
|
+
require "openui/rails/runtime_package"
|
|
30
|
+
require "openui/rails/surface"
|
|
31
|
+
require "openui/rails/view_helper"
|
|
32
|
+
require "openui/rails/configuration"
|
|
33
|
+
require "openui/rails/engine"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :openui do
|
|
4
|
+
namespace :runtime do
|
|
5
|
+
desc "Vendor the checksum-locked OpenUI JS, CSS and license (requires npm)"
|
|
6
|
+
task :fetch, [ :destination ] => :environment do |_task, args|
|
|
7
|
+
configuration = OpenUI::Rails.configuration
|
|
8
|
+
destination = args[:destination] || ::Rails.root.join("public", configuration.local_runtime_path.delete_prefix("/"))
|
|
9
|
+
paths = OpenUI::Rails::RuntimePackage.fetch(
|
|
10
|
+
destination: destination, version: OpenUI::Rails::RuntimeAsset.version(configuration)
|
|
11
|
+
)
|
|
12
|
+
paths.each { |path| puts "Vendored #{path}" }
|
|
13
|
+
puts "Checksums verified; include <%= openui_stylesheet_tag %> in your layout."
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: openui-rails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Andy Wang
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-10-18 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rails
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '8.0'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '9.0'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '8.0'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '9.0'
|
|
33
|
+
description: |
|
|
34
|
+
Render model-generated, streaming, interactive OpenUI Lang UI inside an
|
|
35
|
+
existing Rails application without migrating the whole frontend to a
|
|
36
|
+
React/Next.js SPA. Reuses the official, version-pinned OpenUI JavaScript
|
|
37
|
+
runtime, keeps Rails authoritative for authentication, authorization and
|
|
38
|
+
persistence, and ships an optional RubyLLM adapter. This is an unofficial
|
|
39
|
+
integration and is not affiliated with, endorsed by, or maintained by
|
|
40
|
+
Thesys.
|
|
41
|
+
email:
|
|
42
|
+
- wangyaodi@gmail.com
|
|
43
|
+
executables: []
|
|
44
|
+
extensions: []
|
|
45
|
+
extra_rdoc_files: []
|
|
46
|
+
files:
|
|
47
|
+
- AUDIT.md
|
|
48
|
+
- CHANGELOG.md
|
|
49
|
+
- CODE_OF_CONDUCT.md
|
|
50
|
+
- CONFIGURATION.md
|
|
51
|
+
- CONTRIBUTING.md
|
|
52
|
+
- LICENSE
|
|
53
|
+
- README.md
|
|
54
|
+
- RELEASING.md
|
|
55
|
+
- SECURITY.md
|
|
56
|
+
- THIRD_PARTY_NOTICES.md
|
|
57
|
+
- UPGRADING.md
|
|
58
|
+
- app/controllers/openui/rails/actions_controller.rb
|
|
59
|
+
- app/controllers/openui/rails/application_controller.rb
|
|
60
|
+
- app/javascript/openui/rails/openui_controller.js
|
|
61
|
+
- app/javascript/openui/rails/openui_envelope_controller.js
|
|
62
|
+
- config/routes.rb
|
|
63
|
+
- lib/generators/openui/install/install_generator.rb
|
|
64
|
+
- lib/generators/openui/install/templates/config/initializers/openui.rb.tt
|
|
65
|
+
- lib/generators/openui/install/templates/config/openui/README.md
|
|
66
|
+
- lib/openui/rails.rb
|
|
67
|
+
- lib/openui/rails/actions.rb
|
|
68
|
+
- lib/openui/rails/actions/dispatcher.rb
|
|
69
|
+
- lib/openui/rails/actions/idempotency/memory_store.rb
|
|
70
|
+
- lib/openui/rails/actions/invocation.rb
|
|
71
|
+
- lib/openui/rails/actions/registry.rb
|
|
72
|
+
- lib/openui/rails/actions/schema.rb
|
|
73
|
+
- lib/openui/rails/actions/submission.rb
|
|
74
|
+
- lib/openui/rails/adapters/ruby_llm.rb
|
|
75
|
+
- lib/openui/rails/configuration.rb
|
|
76
|
+
- lib/openui/rails/engine.rb
|
|
77
|
+
- lib/openui/rails/errors.rb
|
|
78
|
+
- lib/openui/rails/json_value.rb
|
|
79
|
+
- lib/openui/rails/library_manifest.rb
|
|
80
|
+
- lib/openui/rails/message.rb
|
|
81
|
+
- lib/openui/rails/prompt_builder.rb
|
|
82
|
+
- lib/openui/rails/runtime_asset.rb
|
|
83
|
+
- lib/openui/rails/runtime_package.rb
|
|
84
|
+
- lib/openui/rails/stream/accumulator.rb
|
|
85
|
+
- lib/openui/rails/stream/bridge.rb
|
|
86
|
+
- lib/openui/rails/stream/broadcaster.rb
|
|
87
|
+
- lib/openui/rails/stream/envelope.rb
|
|
88
|
+
- lib/openui/rails/stream/transports.rb
|
|
89
|
+
- lib/openui/rails/stream/transports/action_cable.rb
|
|
90
|
+
- lib/openui/rails/stream/transports/memory.rb
|
|
91
|
+
- lib/openui/rails/stream/transports/turbo_streams.rb
|
|
92
|
+
- lib/openui/rails/surface.rb
|
|
93
|
+
- lib/openui/rails/version.rb
|
|
94
|
+
- lib/openui/rails/view_helper.rb
|
|
95
|
+
- lib/tasks/openui.rake
|
|
96
|
+
homepage: https://github.com/yorzi/openui-rails
|
|
97
|
+
licenses:
|
|
98
|
+
- MIT
|
|
99
|
+
metadata:
|
|
100
|
+
source_code_uri: https://github.com/yorzi/openui-rails
|
|
101
|
+
changelog_uri: https://github.com/yorzi/openui-rails/blob/main/CHANGELOG.md
|
|
102
|
+
bug_tracker_uri: https://github.com/yorzi/openui-rails/issues
|
|
103
|
+
documentation_uri: https://openui-rails.wangyaodi.com
|
|
104
|
+
rubygems_mfa_required: 'true'
|
|
105
|
+
allowed_push_host: https://rubygems.org
|
|
106
|
+
post_install_message:
|
|
107
|
+
rdoc_options: []
|
|
108
|
+
require_paths:
|
|
109
|
+
- lib
|
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
|
+
requirements:
|
|
112
|
+
- - ">="
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: 3.2.0
|
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
|
+
requirements:
|
|
117
|
+
- - ">="
|
|
118
|
+
- !ruby/object:Gem::Version
|
|
119
|
+
version: '0'
|
|
120
|
+
requirements: []
|
|
121
|
+
rubygems_version: 3.5.22
|
|
122
|
+
signing_key:
|
|
123
|
+
specification_version: 4
|
|
124
|
+
summary: Unofficial Rails integration for Thesys OpenUI Lang.
|
|
125
|
+
test_files: []
|