isomorfeus-preact 10.5.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/README.md +62 -0
- data/lib/browser/delegate_native.rb +70 -0
- data/lib/browser/element.rb +176 -0
- data/lib/browser/element/canvas.rb +17 -0
- data/lib/browser/element/media.rb +78 -0
- data/lib/browser/event.rb +92 -0
- data/lib/browser/event_target.rb +39 -0
- data/lib/browser/file_list.rb +125 -0
- data/lib/browser/iterable.rb +15 -0
- data/lib/isomorfeus-preact.rb +109 -0
- data/lib/isomorfeus/preact/config.rb +189 -0
- data/lib/isomorfeus/preact/memcached_component_cache.rb +19 -0
- data/lib/isomorfeus/preact/redis_component_cache.rb +19 -0
- data/lib/isomorfeus/preact/thread_local_component_cache.rb +17 -0
- data/lib/isomorfeus/preact_view_helper.rb +188 -0
- data/lib/isomorfeus/props/validate_hash_proxy.rb +186 -0
- data/lib/isomorfeus/props/validator.rb +159 -0
- data/lib/isomorfeus/top_level.rb +101 -0
- data/lib/isomorfeus/top_level_ssr.rb +27 -0
- data/lib/isomorfeus_preact/lucid_app/api.rb +22 -0
- data/lib/isomorfeus_preact/lucid_app/base.rb +7 -0
- data/lib/isomorfeus_preact/lucid_app/mixin.rb +16 -0
- data/lib/isomorfeus_preact/lucid_app/native_component_constructor.rb +91 -0
- data/lib/isomorfeus_preact/lucid_component/api.rb +68 -0
- data/lib/isomorfeus_preact/lucid_component/app_store_proxy.rb +37 -0
- data/lib/isomorfeus_preact/lucid_component/base.rb +7 -0
- data/lib/isomorfeus_preact/lucid_component/class_store_proxy.rb +44 -0
- data/lib/isomorfeus_preact/lucid_component/initializer.rb +14 -0
- data/lib/isomorfeus_preact/lucid_component/instance_store_proxy.rb +44 -0
- data/lib/isomorfeus_preact/lucid_component/mixin.rb +15 -0
- data/lib/isomorfeus_preact/lucid_component/native_component_constructor.rb +84 -0
- data/lib/isomorfeus_preact/lucid_component/styles_api.rb +31 -0
- data/lib/isomorfeus_preact/lucid_component/styles_wrapper.rb +40 -0
- data/lib/isomorfeus_preact/lucid_func/base.rb +7 -0
- data/lib/isomorfeus_preact/lucid_func/initializer.rb +11 -0
- data/lib/isomorfeus_preact/lucid_func/mixin.rb +12 -0
- data/lib/isomorfeus_preact/lucid_func/native_component_constructor.rb +55 -0
- data/lib/isomorfeus_preact/preact/function_component/api.rb +123 -0
- data/lib/isomorfeus_preact/preact/function_component/base.rb +9 -0
- data/lib/isomorfeus_preact/preact/function_component/initializer.rb +10 -0
- data/lib/isomorfeus_preact/preact/function_component/mixin.rb +12 -0
- data/lib/isomorfeus_preact/preact/function_component/native_component_constructor.rb +48 -0
- data/lib/lucid_app/context.rb +24 -0
- data/lib/lucid_prop_declaration/mixin.rb +126 -0
- data/lib/preact.rb +309 -0
- data/lib/preact/component/api.rb +124 -0
- data/lib/preact/component/base.rb +9 -0
- data/lib/preact/component/callbacks.rb +102 -0
- data/lib/preact/component/elements.rb +64 -0
- data/lib/preact/component/initializer.rb +11 -0
- data/lib/preact/component/mixin.rb +15 -0
- data/lib/preact/component/native_component_constructor.rb +65 -0
- data/lib/preact/component/params.rb +18 -0
- data/lib/preact/component/props.rb +55 -0
- data/lib/preact/component/resolution.rb +97 -0
- data/lib/preact/component/state.rb +58 -0
- data/lib/preact/context_wrapper.rb +46 -0
- data/lib/preact/native_constant_wrapper.rb +29 -0
- data/lib/preact/options.rb +98 -0
- data/lib/preact/ref.rb +17 -0
- data/lib/preact/version.rb +3 -0
- metadata +301 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
class TopLevel
|
3
|
+
class << self
|
4
|
+
def mount!
|
5
|
+
Isomorfeus.init
|
6
|
+
Isomorfeus::TopLevel.on_ready do
|
7
|
+
root_element = `document.querySelector('div[data-iso-root]')`
|
8
|
+
Isomorfeus.raise_error(message: "Isomorfeus root element not found!") unless root_element
|
9
|
+
component_name = root_element.JS.getAttribute('data-iso-root')
|
10
|
+
Isomorfeus.env = root_element.JS.getAttribute('data-iso-env')
|
11
|
+
user_sid = root_element.JS.getAttribute('data-iso-usid')
|
12
|
+
Isomorfeus.current_user_sid =`JSON.parse(user_sid)` if user_sid
|
13
|
+
component = nil
|
14
|
+
begin
|
15
|
+
component = component_name.constantize
|
16
|
+
rescue Exception => e
|
17
|
+
`console.warn("Deferring mount: " + #{e.message})`
|
18
|
+
@timeout_start = Time.now unless @timeout_start
|
19
|
+
if (Time.now - @timeout_start) < 10
|
20
|
+
`setTimeout(Opal.Isomorfeus.TopLevel['$mount!'], 100)`
|
21
|
+
else
|
22
|
+
`console.error("Unable to mount '" + #{component_name} + "'!")`
|
23
|
+
end
|
24
|
+
end
|
25
|
+
if component
|
26
|
+
props_json = root_element.JS.getAttribute('data-iso-props')
|
27
|
+
props = `Opal.Hash.$new(JSON.parse(props_json))`
|
28
|
+
raw_hydrated = root_element.JS.getAttribute('data-iso-hydrated')
|
29
|
+
hydrated = (raw_hydrated && raw_hydrated == "true")
|
30
|
+
%x{
|
31
|
+
if (global.ServerSideRenderingStateJSON) {
|
32
|
+
var state = global.ServerSideRenderingStateJSON;
|
33
|
+
var keys = Object.keys(state);
|
34
|
+
for(var i=0; i < keys.length; i++) {
|
35
|
+
if (Object.keys(state[keys[i]]).length > 0) {
|
36
|
+
global.Opal.Isomorfeus.store.native.dispatch({ type: keys[i].toUpperCase(), set_state: state[keys[i]] });
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
Isomorfeus.execute_init_after_store_classes
|
42
|
+
begin
|
43
|
+
result = Isomorfeus::TopLevel.mount_component(component, props, root_element, hydrated)
|
44
|
+
@tried_another_time = false
|
45
|
+
result
|
46
|
+
rescue Exception => e
|
47
|
+
if !@tried_another_time
|
48
|
+
@tried_another_time = true
|
49
|
+
`console.warn("Deferring mount: " + #{e.message})`
|
50
|
+
`console.error(#{e.backtrace.join("\n")})`
|
51
|
+
`setTimeout(Opal.Isomorfeus.TopLevel['$mount!'], 250)`
|
52
|
+
else
|
53
|
+
`console.error("Unable to mount '" + #{component_name} + "'! Error: " + #{e.message} + "!")`
|
54
|
+
`console.error(#{e.backtrace.join("\n")})`
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def on_ready(&block)
|
62
|
+
%x{
|
63
|
+
function run() { block.$call() };
|
64
|
+
function ready_fun(fn) {
|
65
|
+
if (document.readyState === "complete" || document.readyState === "interactive") {
|
66
|
+
setTimeout(fn, 1);
|
67
|
+
} else {
|
68
|
+
document.addEventListener("DOMContentLoaded", fn);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
ready_fun(run);
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def on_ready_mount(component, props = nil, element_query = nil)
|
76
|
+
# init in case it hasn't been run yet
|
77
|
+
Isomorfeus.init
|
78
|
+
on_ready do
|
79
|
+
Isomorfeus::TopLevel.mount_component(component, props, element_query)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def mount_component(component, props, element_or_query, hydrated = false)
|
84
|
+
if `(typeof element_or_query === 'string')` || (`(typeof element_or_query.$class === 'function')` && element_or_query.class == String)
|
85
|
+
element = `document.body.querySelector(element_or_query)`
|
86
|
+
elsif `(typeof element_or_query.$is_a === 'function')` && element_or_query.is_a?(Browser::Element)
|
87
|
+
element = element_or_query.to_n
|
88
|
+
else
|
89
|
+
element = element_or_query
|
90
|
+
end
|
91
|
+
|
92
|
+
top = if hydrated
|
93
|
+
Preact.hydrate(Preact.create_element(component, props), element)
|
94
|
+
else
|
95
|
+
Preact.render(Preact.create_element(component, props), element)
|
96
|
+
end
|
97
|
+
Isomorfeus.top_component = top if top
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
class TopLevel
|
3
|
+
class << self
|
4
|
+
attr_accessor :ssr_route_path
|
5
|
+
attr_accessor :transport_ws_url
|
6
|
+
|
7
|
+
def mount!
|
8
|
+
# nothing, but keep it for compatibility with browser
|
9
|
+
end
|
10
|
+
|
11
|
+
def render_component_to_string(component_name, props)
|
12
|
+
component = nil
|
13
|
+
%x{
|
14
|
+
if (typeof component_name === 'string' || component_name instanceof String) {
|
15
|
+
component = component_name.split(".").reduce(function(o, x) {
|
16
|
+
return (o !== null && typeof o[x] !== "undefined" && o[x] !== null) ? o[x] : null;
|
17
|
+
}, Opal.global)
|
18
|
+
} else {
|
19
|
+
component = component_name;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
component = Isomorfeus.cached_component_class(component_name) unless component
|
23
|
+
Preact.render_to_string(Preact.create_element(component, `Opal.Hash.$new(props)`))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module LucidApp
|
2
|
+
module Api
|
3
|
+
def self.included(base)
|
4
|
+
base.instance_exec do
|
5
|
+
def theme(theme_hash = nil, &block)
|
6
|
+
theme_hash = block.call if block_given?
|
7
|
+
if theme_hash
|
8
|
+
%x{
|
9
|
+
let css;
|
10
|
+
if (typeof theme_hash.$to_n === 'function') { css = theme_hash.$to_n(); }
|
11
|
+
else { css = theme_hash; }
|
12
|
+
let nano_styles = Opal.global.NanoCSSInstance.sheet(css, "LucidAppTheme");
|
13
|
+
base.css_theme = #{::LucidComponent::StylesWrapper.new(`nano_styles`)};
|
14
|
+
}
|
15
|
+
end
|
16
|
+
`base.css_theme`
|
17
|
+
end
|
18
|
+
alias_method :theme=, :theme
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module LucidApp
|
2
|
+
module Mixin
|
3
|
+
def self.included(base)
|
4
|
+
base.include(::Native::Wrapper)
|
5
|
+
base.extend(::LucidApp::NativeComponentConstructor)
|
6
|
+
base.include(::Preact::Component::Elements)
|
7
|
+
base.extend(::LucidPropDeclaration::Mixin)
|
8
|
+
base.include(::Preact::Component::Api)
|
9
|
+
base.include(::Preact::Component::Callbacks)
|
10
|
+
base.include(::LucidComponent::Api)
|
11
|
+
base.include(::LucidComponent::StylesApi)
|
12
|
+
base.include(::LucidApp::Api)
|
13
|
+
base.include(::LucidComponent::Initializer)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module LucidApp
|
2
|
+
module NativeComponentConstructor
|
3
|
+
# for should_component_update we apply ruby semantics for comparing props
|
4
|
+
# to do so, we convert the props to ruby hashes and then compare
|
5
|
+
# this makes sure, that for example rubys Nil object gets handled properly
|
6
|
+
def self.extended(base)
|
7
|
+
component_name = base.to_s
|
8
|
+
%x{
|
9
|
+
base.css_styles = null;
|
10
|
+
base.css_theme = null;
|
11
|
+
base.preload_block = null;
|
12
|
+
base.while_loading_block = null;
|
13
|
+
|
14
|
+
base.preact_component = class extends Opal.global.Preact.Component {
|
15
|
+
constructor(props) {
|
16
|
+
super(props);
|
17
|
+
const oper = Opal.Preact;
|
18
|
+
if (base.$default_state_defined()) {
|
19
|
+
this.state = base.$state().$to_n();
|
20
|
+
} else {
|
21
|
+
this.state = {};
|
22
|
+
};
|
23
|
+
this.state.isomorfeus_store_state = Opal.Isomorfeus.store.native.getState();
|
24
|
+
var current_store_state = this.state.isomorfeus_store_state;
|
25
|
+
if (typeof current_store_state.class_state[#{component_name}] !== "undefined") {
|
26
|
+
this.state.class_state = {};
|
27
|
+
this.state.class_state[#{component_name}] = current_store_state.class_state[#{component_name}];
|
28
|
+
} else {
|
29
|
+
this.state.class_state = {};
|
30
|
+
this.state.class_state[#{component_name}] = {};
|
31
|
+
};
|
32
|
+
this.__ruby_instance = base.$new(this);
|
33
|
+
var defined_refs = #{base.defined_refs};
|
34
|
+
for (var ref in defined_refs) {
|
35
|
+
if (defined_refs[ref] != null) {
|
36
|
+
this[ref] = function(element) {
|
37
|
+
element = oper.native_element_or_component_to_ruby(element);
|
38
|
+
#{`this.__ruby_instance`.instance_exec(`element`, &`defined_refs[ref]`)}
|
39
|
+
}
|
40
|
+
this[ref] = this[ref].bind(this);
|
41
|
+
} else {
|
42
|
+
this[ref] = Opal.global.Preact.createRef();
|
43
|
+
}
|
44
|
+
}
|
45
|
+
if (base.preload_block) {
|
46
|
+
oper.active_redux_components.push(this);
|
47
|
+
this.state.preloaded = this.__ruby_instance.$execute_preload_block();
|
48
|
+
oper.active_redux_components.pop();
|
49
|
+
}
|
50
|
+
this.listener = this.listener.bind(this);
|
51
|
+
this.unsubscriber = Opal.Isomorfeus.store.native.subscribe(this.listener);
|
52
|
+
}
|
53
|
+
static get displayName() {
|
54
|
+
return #{component_name};
|
55
|
+
}
|
56
|
+
render(props, state) {
|
57
|
+
const oper = Opal.Preact;
|
58
|
+
oper.render_buffer.push([]);
|
59
|
+
// console.log("lucid app pushed", oper.render_buffer, oper.render_buffer.toString());
|
60
|
+
oper.active_components.push(this);
|
61
|
+
oper.active_redux_components.push(this);
|
62
|
+
let block_result;
|
63
|
+
if (base.while_loading_block && !state.preloaded) { block_result = #{`this.__ruby_instance`.instance_exec(&`base.while_loading_block`)}; }
|
64
|
+
else { block_result = #{`this.__ruby_instance`.instance_exec(&`base.render_block`)}; }
|
65
|
+
if (block_result && block_result !== nil) { oper.render_block_result(block_result); }
|
66
|
+
oper.active_redux_components.pop();
|
67
|
+
oper.active_components.pop();
|
68
|
+
let children = oper.render_buffer.pop();
|
69
|
+
// console.log("lucid app popping", oper.render_buffer, oper.render_buffer.toString());
|
70
|
+
return Opal.global.Preact.createElement(Opal.global.LucidApplicationContext.Provider, { value: { iso_store: this.state.isomorfeus_store_state, iso_theme: base.css_theme }}, children);
|
71
|
+
}
|
72
|
+
data_access() {
|
73
|
+
this.state.isomorfeus_store_state;
|
74
|
+
}
|
75
|
+
listener() {
|
76
|
+
let next_state = Opal.Isomorfeus.store.native.getState();
|
77
|
+
this.setState({ isomorfeus_store_state: next_state });
|
78
|
+
}
|
79
|
+
componentWillUnmount() {
|
80
|
+
if (typeof this.unsubscriber === "function") { this.unsubscriber(); }
|
81
|
+
}
|
82
|
+
validateProp(props, propName, componentName) {
|
83
|
+
try { base.$validate_prop(propName, props[propName]) }
|
84
|
+
catch (e) { return new Error(componentName + ": Error: prop validation failed: " + e.message); }
|
85
|
+
return null;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module LucidComponent
|
2
|
+
module Api
|
3
|
+
def self.included(base)
|
4
|
+
base.instance_exec do
|
5
|
+
# store
|
6
|
+
attr_accessor :app_store
|
7
|
+
attr_accessor :class_store
|
8
|
+
attr_accessor :store
|
9
|
+
|
10
|
+
def class_store
|
11
|
+
@class_store ||= ::LucidComponent::ClassStoreProxy.new(self.to_s)
|
12
|
+
end
|
13
|
+
|
14
|
+
# preloading
|
15
|
+
def preload(&block)
|
16
|
+
`base.preload_block = block`
|
17
|
+
component_did_mount do
|
18
|
+
unless self.state.preloaded
|
19
|
+
@_preload_promise.then { self.state.preloaded = true }.fail do |result|
|
20
|
+
err_text = "#{self.class.name}: preloading failed, last result: #{result.nil? ? 'nil' : result}!"
|
21
|
+
`console.error(err_text)`
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def while_loading(option = nil, &block)
|
28
|
+
wl_block = proc do
|
29
|
+
if @_preload_promise.resolved?
|
30
|
+
instance_exec(&`base.render_block`)
|
31
|
+
else
|
32
|
+
instance_exec(&block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
`base.while_loading_block = wl_block`
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# stores
|
40
|
+
def local_store
|
41
|
+
LocalStore
|
42
|
+
end
|
43
|
+
|
44
|
+
def session_store
|
45
|
+
SessionStore
|
46
|
+
end
|
47
|
+
|
48
|
+
def theme
|
49
|
+
props.theme
|
50
|
+
end
|
51
|
+
|
52
|
+
# preloading
|
53
|
+
def execute_preload_block
|
54
|
+
@_preload_promise = instance_exec(&self.class.JS[:preload_block])
|
55
|
+
@_preload_promise.resolved?
|
56
|
+
end
|
57
|
+
|
58
|
+
def preloaded?
|
59
|
+
!!state.preloaded
|
60
|
+
end
|
61
|
+
|
62
|
+
# requires transport
|
63
|
+
def current_user
|
64
|
+
Isomorfeus.current_user
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module LucidComponent
|
2
|
+
class AppStoreProxy
|
3
|
+
def initialize(component_instance)
|
4
|
+
if component_instance
|
5
|
+
@native = component_instance.to_n
|
6
|
+
@component_instance = component_instance
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](key)
|
11
|
+
method_missing(key)
|
12
|
+
end
|
13
|
+
|
14
|
+
def []=(key, value)
|
15
|
+
method_missing(key, value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(key, *args, &block)
|
19
|
+
if `args.length > 0`
|
20
|
+
# set class state, simply a dispatch
|
21
|
+
action = { type: 'APPLICATION_STATE', name: (`key.endsWith('=')` ? key.chop : key), value: args[0] }
|
22
|
+
Isomorfeus.store.collect_and_defer_dispatch(action)
|
23
|
+
else
|
24
|
+
# check if we have a component local state value
|
25
|
+
if @native && `#@native.props.iso_store`
|
26
|
+
if `#@native.props.iso_store.application_state && #@native.props.iso_store.application_state.hasOwnProperty(key)`
|
27
|
+
return @native.JS[:props].JS[:iso_store].JS[:application_state].JS[key]
|
28
|
+
end
|
29
|
+
else
|
30
|
+
return AppStore[key]
|
31
|
+
end
|
32
|
+
# otherwise return nil
|
33
|
+
return nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module LucidComponent
|
2
|
+
class ClassStoreProxy
|
3
|
+
def initialize(component_name, component_instance = nil, native = nil)
|
4
|
+
@component_name = component_name
|
5
|
+
if component_instance
|
6
|
+
@native = native
|
7
|
+
@component_instance = component_instance
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](key)
|
12
|
+
method_missing(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def []=(key, value)
|
16
|
+
method_missing(key, value)
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(key, *args, &block)
|
20
|
+
if `args.length > 0`
|
21
|
+
# set class state, simply a dispatch
|
22
|
+
action = { type: 'CLASS_STATE', class: @component_name, name: (`key.endsWith('=')` ? key.chop : key), value: args[0] }
|
23
|
+
Isomorfeus.store.collect_and_defer_dispatch(action)
|
24
|
+
else
|
25
|
+
# get class state
|
26
|
+
# check if we have a component local state value
|
27
|
+
if @native && @native.JS[:props].JS[:iso_store]
|
28
|
+
if @native.JS[:props].JS[:iso_store].JS[:class_state] &&
|
29
|
+
@native.JS[:props].JS[:iso_store].JS[:class_state].JS[@component_name] &&
|
30
|
+
@native.JS[:props].JS[:iso_store].JS[:class_state].JS[@component_name].JS.hasOwnProperty(key)
|
31
|
+
return @native.JS[:props].JS[:iso_store].JS[:class_state].JS[@component_name].JS[key]
|
32
|
+
end
|
33
|
+
else
|
34
|
+
a_state = Isomorfeus.store.get_state
|
35
|
+
if a_state.key?(:class_state) && a_state[:class_state].key?(@component_name) && a_state[:class_state][@component_name].key?(key)
|
36
|
+
return a_state[:class_state][@component_name][key]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
# otherwise return nil
|
40
|
+
return nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module LucidComponent
|
2
|
+
module Initializer
|
3
|
+
def initialize(native_component)
|
4
|
+
@native = native_component
|
5
|
+
@app_store = LucidComponent::AppStoreProxy.new(self)
|
6
|
+
@class_store = LucidComponent::ClassStoreProxy.new(self.class.to_s, self, @native)
|
7
|
+
# @iso_store = Isomorfeus::IsomorphicStoreProxy.new(self)
|
8
|
+
# @local_store = Isomorfeus::LocalStoreProxy.new(self)
|
9
|
+
@store = LucidComponent::InstanceStoreProxy.new(self)
|
10
|
+
@props = `Opal.Preact.Component.Props.$new(#@native)`
|
11
|
+
@state = `Opal.Preact.Component.State.$new(#@native)`
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|