isomorfeus-preact 10.9.0 → 22.9.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +14 -3
- data/README.md +23 -39
- data/lib/browser/delegate_native.rb +94 -72
- data/lib/browser/document.rb +38 -0
- data/lib/browser/element.rb +160 -176
- data/lib/browser/event.rb +99 -94
- data/lib/browser/history.rb +40 -20
- data/lib/browser/location.rb +59 -0
- data/lib/browser/window.rb +58 -0
- data/lib/data_uri/open_uri.rb +18 -0
- data/lib/data_uri/uri.rb +61 -0
- data/lib/data_uri.rb +4 -0
- data/lib/isomorfeus/preact/config.rb +42 -54
- data/lib/isomorfeus/preact/imports.rb +5 -20
- data/lib/isomorfeus/preact/ssr.rb +34 -0
- data/lib/isomorfeus/preact/thread_local_component_cache.rb +9 -11
- data/lib/isomorfeus/preact/version.rb +5 -0
- data/lib/isomorfeus/preact/view_helper.rb +72 -0
- data/lib/isomorfeus/props/validator.rb +19 -11
- data/lib/isomorfeus/top_level.rb +55 -33
- data/lib/isomorfeus-preact.rb +78 -103
- data/lib/link.rb +52 -0
- data/lib/lucid_app.rb +117 -0
- data/lib/lucid_component.rb +154 -0
- data/lib/nano_css.rb +282 -465
- data/lib/preact/component.rb +222 -0
- data/lib/preact/component_resolution.rb +49 -83
- data/lib/preact/context.rb +68 -0
- data/lib/preact/elements.rb +2 -9
- data/lib/preact/module_component_resolution.rb +50 -0
- data/lib/preact/prop_declaration_mixin.rb +73 -0
- data/lib/preact.rb +1548 -257
- data/lib/redirect.rb +34 -0
- data/lib/route.rb +15 -0
- data/lib/router.rb +145 -0
- data/lib/switch.rb +70 -0
- metadata +42 -309
- data/lib/isomorfeus/preact/memcached_component_cache.rb +0 -19
- data/lib/isomorfeus/preact/redis_component_cache.rb +0 -19
- data/lib/isomorfeus/preact/ssr/history.rb +0 -23
- data/lib/isomorfeus/preact/ssr/render_core.rb +0 -117
- data/lib/isomorfeus/preact/ssr/top_level.rb +0 -37
- data/lib/isomorfeus/preact_view_helper.rb +0 -129
- data/lib/isomorfeus_preact/lucid_app/api.rb +0 -38
- data/lib/isomorfeus_preact/lucid_app/base.rb +0 -7
- data/lib/isomorfeus_preact/lucid_app/mixin.rb +0 -14
- data/lib/isomorfeus_preact/lucid_app/native_component_constructor.rb +0 -101
- data/lib/isomorfeus_preact/lucid_component/api.rb +0 -123
- data/lib/isomorfeus_preact/lucid_component/app_store_proxy.rb +0 -32
- data/lib/isomorfeus_preact/lucid_component/base.rb +0 -7
- data/lib/isomorfeus_preact/lucid_component/class_store_proxy.rb +0 -37
- data/lib/isomorfeus_preact/lucid_component/initializer.rb +0 -9
- data/lib/isomorfeus_preact/lucid_component/mixin.rb +0 -13
- data/lib/isomorfeus_preact/lucid_component/native_component_constructor.rb +0 -87
- data/lib/isomorfeus_preact/lucid_component/styles_wrapper.rb +0 -40
- data/lib/isomorfeus_preact/lucid_func/base.rb +0 -7
- data/lib/isomorfeus_preact/lucid_func/initializer.rb +0 -8
- data/lib/isomorfeus_preact/lucid_func/mixin.rb +0 -10
- data/lib/isomorfeus_preact/lucid_func/native_component_constructor.rb +0 -56
- data/lib/isomorfeus_preact/preact/function_component/api.rb +0 -164
- data/lib/isomorfeus_preact/preact/function_component/base.rb +0 -7
- data/lib/isomorfeus_preact/preact/function_component/initializer.rb +0 -6
- data/lib/isomorfeus_preact/preact/function_component/mixin.rb +0 -8
- data/lib/isomorfeus_preact/preact/function_component/native_component_constructor.rb +0 -47
- data/lib/lucid_app/context.rb +0 -24
- data/lib/lucid_prop_declaration/mixin.rb +0 -126
- data/lib/preact/component/api.rb +0 -137
- data/lib/preact/component/base.rb +0 -7
- data/lib/preact/component/callbacks.rb +0 -111
- data/lib/preact/component/initializer.rb +0 -7
- data/lib/preact/component/mixin.rb +0 -11
- data/lib/preact/component/native_component_constructor.rb +0 -77
- data/lib/preact/context_wrapper.rb +0 -48
- data/lib/preact/native_constant_wrapper.rb +0 -29
- data/lib/preact/option_hooks.rb +0 -98
- data/lib/preact/params.rb +0 -16
- data/lib/preact/props.rb +0 -69
- data/lib/preact/ref.rb +0 -17
- data/lib/preact/state.rb +0 -87
- data/lib/preact/version.rb +0 -3
- data/node_modules/.package-lock.json +0 -38
- data/node_modules/preact/LICENSE +0 -21
- data/node_modules/preact/README.md +0 -188
- data/node_modules/preact/compat/LICENSE +0 -21
- data/node_modules/preact/compat/client.js +0 -19
- data/node_modules/preact/compat/client.mjs +0 -17
- data/node_modules/preact/compat/dist/compat.js +0 -2
- data/node_modules/preact/compat/dist/compat.js.map +0 -1
- data/node_modules/preact/compat/dist/compat.mjs +0 -2
- data/node_modules/preact/compat/dist/compat.module.js +0 -2
- data/node_modules/preact/compat/dist/compat.module.js.map +0 -1
- data/node_modules/preact/compat/dist/compat.umd.js +0 -2
- data/node_modules/preact/compat/dist/compat.umd.js.map +0 -1
- data/node_modules/preact/compat/jsx-dev-runtime.js +0 -3
- data/node_modules/preact/compat/jsx-dev-runtime.mjs +0 -3
- data/node_modules/preact/compat/jsx-runtime.js +0 -3
- data/node_modules/preact/compat/jsx-runtime.mjs +0 -3
- data/node_modules/preact/compat/package.json +0 -49
- data/node_modules/preact/compat/scheduler.js +0 -15
- data/node_modules/preact/compat/scheduler.mjs +0 -23
- data/node_modules/preact/compat/server.browser.js +0 -4
- data/node_modules/preact/compat/server.js +0 -15
- data/node_modules/preact/compat/server.mjs +0 -4
- data/node_modules/preact/compat/src/Children.js +0 -21
- data/node_modules/preact/compat/src/PureComponent.js +0 -15
- data/node_modules/preact/compat/src/forwardRef.js +0 -44
- data/node_modules/preact/compat/src/index.d.ts +0 -164
- data/node_modules/preact/compat/src/index.js +0 -223
- data/node_modules/preact/compat/src/internal.d.ts +0 -47
- data/node_modules/preact/compat/src/memo.js +0 -34
- data/node_modules/preact/compat/src/portals.js +0 -82
- data/node_modules/preact/compat/src/render.js +0 -238
- data/node_modules/preact/compat/src/suspense-list.d.ts +0 -14
- data/node_modules/preact/compat/src/suspense-list.js +0 -126
- data/node_modules/preact/compat/src/suspense.d.ts +0 -15
- data/node_modules/preact/compat/src/suspense.js +0 -270
- data/node_modules/preact/compat/src/util.js +0 -28
- data/node_modules/preact/compat/test-utils.js +0 -1
- data/node_modules/preact/debug/LICENSE +0 -21
- data/node_modules/preact/debug/dist/debug.js +0 -2
- data/node_modules/preact/debug/dist/debug.js.map +0 -1
- data/node_modules/preact/debug/dist/debug.mjs +0 -2
- data/node_modules/preact/debug/dist/debug.module.js +0 -2
- data/node_modules/preact/debug/dist/debug.module.js.map +0 -1
- data/node_modules/preact/debug/dist/debug.umd.js +0 -2
- data/node_modules/preact/debug/dist/debug.umd.js.map +0 -1
- data/node_modules/preact/debug/package.json +0 -26
- data/node_modules/preact/debug/src/check-props.js +0 -54
- data/node_modules/preact/debug/src/component-stack.js +0 -146
- data/node_modules/preact/debug/src/constants.js +0 -3
- data/node_modules/preact/debug/src/debug.js +0 -437
- data/node_modules/preact/debug/src/index.js +0 -6
- data/node_modules/preact/debug/src/internal.d.ts +0 -82
- data/node_modules/preact/debug/src/util.js +0 -11
- data/node_modules/preact/devtools/LICENSE +0 -21
- data/node_modules/preact/devtools/dist/devtools.js +0 -2
- data/node_modules/preact/devtools/dist/devtools.js.map +0 -1
- data/node_modules/preact/devtools/dist/devtools.mjs +0 -2
- data/node_modules/preact/devtools/dist/devtools.module.js +0 -2
- data/node_modules/preact/devtools/dist/devtools.module.js.map +0 -1
- data/node_modules/preact/devtools/dist/devtools.umd.js +0 -2
- data/node_modules/preact/devtools/dist/devtools.umd.js.map +0 -1
- data/node_modules/preact/devtools/package.json +0 -25
- data/node_modules/preact/devtools/src/devtools.js +0 -10
- data/node_modules/preact/devtools/src/index.d.ts +0 -8
- data/node_modules/preact/devtools/src/index.js +0 -15
- data/node_modules/preact/dist/preact.js +0 -2
- data/node_modules/preact/dist/preact.js.map +0 -1
- data/node_modules/preact/dist/preact.min.js +0 -2
- data/node_modules/preact/dist/preact.min.js.map +0 -1
- data/node_modules/preact/dist/preact.mjs +0 -2
- data/node_modules/preact/dist/preact.module.js +0 -2
- data/node_modules/preact/dist/preact.module.js.map +0 -1
- data/node_modules/preact/dist/preact.umd.js +0 -2
- data/node_modules/preact/dist/preact.umd.js.map +0 -1
- data/node_modules/preact/hooks/LICENSE +0 -21
- data/node_modules/preact/hooks/dist/hooks.js +0 -2
- data/node_modules/preact/hooks/dist/hooks.js.map +0 -1
- data/node_modules/preact/hooks/dist/hooks.mjs +0 -2
- data/node_modules/preact/hooks/dist/hooks.module.js +0 -2
- data/node_modules/preact/hooks/dist/hooks.module.js.map +0 -1
- data/node_modules/preact/hooks/dist/hooks.umd.js +0 -2
- data/node_modules/preact/hooks/dist/hooks.umd.js.map +0 -1
- data/node_modules/preact/hooks/package.json +0 -35
- data/node_modules/preact/hooks/src/index.d.ts +0 -139
- data/node_modules/preact/hooks/src/index.js +0 -417
- data/node_modules/preact/hooks/src/internal.d.ts +0 -78
- data/node_modules/preact/jsx-runtime/LICENSE +0 -21
- data/node_modules/preact/jsx-runtime/dist/jsxRuntime.js +0 -2
- data/node_modules/preact/jsx-runtime/dist/jsxRuntime.js.map +0 -1
- data/node_modules/preact/jsx-runtime/dist/jsxRuntime.mjs +0 -2
- data/node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js +0 -2
- data/node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js.map +0 -1
- data/node_modules/preact/jsx-runtime/dist/jsxRuntime.umd.js +0 -2
- data/node_modules/preact/jsx-runtime/dist/jsxRuntime.umd.js.map +0 -1
- data/node_modules/preact/jsx-runtime/package.json +0 -28
- data/node_modules/preact/jsx-runtime/src/index.d.ts +0 -50
- data/node_modules/preact/jsx-runtime/src/index.js +0 -77
- data/node_modules/preact/package.json +0 -304
- data/node_modules/preact/src/cjs.js +0 -3
- data/node_modules/preact/src/clone-element.js +0 -34
- data/node_modules/preact/src/component.js +0 -225
- data/node_modules/preact/src/constants.js +0 -3
- data/node_modules/preact/src/create-context.js +0 -68
- data/node_modules/preact/src/create-element.js +0 -98
- data/node_modules/preact/src/diff/catch-error.js +0 -40
- data/node_modules/preact/src/diff/children.js +0 -335
- data/node_modules/preact/src/diff/index.js +0 -533
- data/node_modules/preact/src/diff/props.js +0 -158
- data/node_modules/preact/src/index.d.ts +0 -317
- data/node_modules/preact/src/index.js +0 -13
- data/node_modules/preact/src/internal.d.ts +0 -155
- data/node_modules/preact/src/jsx.d.ts +0 -1014
- data/node_modules/preact/src/options.js +0 -16
- data/node_modules/preact/src/render.js +0 -75
- data/node_modules/preact/src/util.js +0 -27
- data/node_modules/preact/test-utils/dist/testUtils.js +0 -2
- data/node_modules/preact/test-utils/dist/testUtils.js.map +0 -1
- data/node_modules/preact/test-utils/dist/testUtils.mjs +0 -2
- data/node_modules/preact/test-utils/dist/testUtils.module.js +0 -2
- data/node_modules/preact/test-utils/dist/testUtils.module.js.map +0 -1
- data/node_modules/preact/test-utils/dist/testUtils.umd.js +0 -2
- data/node_modules/preact/test-utils/dist/testUtils.umd.js.map +0 -1
- data/node_modules/preact/test-utils/package.json +0 -28
- data/node_modules/preact/test-utils/src/index.d.ts +0 -3
- data/node_modules/preact/test-utils/src/index.js +0 -118
- data/node_modules/preact-render-to-string/LICENSE +0 -21
- data/node_modules/preact-render-to-string/README.md +0 -102
- data/node_modules/preact-render-to-string/dist/commonjs.js +0 -2
- data/node_modules/preact-render-to-string/dist/commonjs.js.map +0 -1
- data/node_modules/preact-render-to-string/dist/index.d.ts +0 -16
- data/node_modules/preact-render-to-string/dist/index.js +0 -1
- data/node_modules/preact-render-to-string/dist/index.js.map +0 -1
- data/node_modules/preact-render-to-string/dist/index.mjs +0 -2
- data/node_modules/preact-render-to-string/dist/index.module.js +0 -2
- data/node_modules/preact-render-to-string/dist/index.module.js.map +0 -1
- data/node_modules/preact-render-to-string/dist/jsx-entry.js +0 -2
- data/node_modules/preact-render-to-string/dist/jsx-entry.js.map +0 -1
- data/node_modules/preact-render-to-string/dist/jsx.d.ts +0 -13
- data/node_modules/preact-render-to-string/dist/jsx.js +0 -1
- data/node_modules/preact-render-to-string/dist/jsx.js.map +0 -1
- data/node_modules/preact-render-to-string/dist/jsx.mjs +0 -2
- data/node_modules/preact-render-to-string/dist/jsx.modern.js +0 -2
- data/node_modules/preact-render-to-string/dist/jsx.modern.js.map +0 -1
- data/node_modules/preact-render-to-string/dist/jsx.module.js +0 -2
- data/node_modules/preact-render-to-string/dist/jsx.module.js.map +0 -1
- data/node_modules/preact-render-to-string/dist/preact-render-to-string-tests.d.ts +0 -1
- data/node_modules/preact-render-to-string/jsx.js +0 -1
- data/node_modules/preact-render-to-string/package.json +0 -142
- data/node_modules/preact-render-to-string/src/index.d.ts +0 -16
- data/node_modules/preact-render-to-string/src/index.js +0 -462
- data/node_modules/preact-render-to-string/src/jsx.d.ts +0 -13
- data/node_modules/preact-render-to-string/src/jsx.js +0 -76
- data/node_modules/preact-render-to-string/src/polyfills.js +0 -8
- data/node_modules/preact-render-to-string/src/preact-render-to-string-tests.d.ts +0 -1
- data/node_modules/preact-render-to-string/src/util.js +0 -78
- data/node_modules/preact-render-to-string/typings.json +0 -5
- data/node_modules/pretty-format/.npmignore +0 -3
- data/node_modules/pretty-format/LICENSE.md +0 -15
- data/node_modules/pretty-format/README.md +0 -94
- data/node_modules/pretty-format/index.js +0 -343
- data/node_modules/pretty-format/package.json +0 -26
- data/node_modules/pretty-format/plugins/ReactElement.js +0 -74
- data/node_modules/pretty-format/plugins/ReactTestComponent.js +0 -58
- data/node_modules/pretty-format/printString.js +0 -7
- data/node_modules/wouter-preact/cjs/index.js +0 -180
- data/node_modules/wouter-preact/cjs/matcher.js +0 -72
- data/node_modules/wouter-preact/cjs/package.json +0 -1
- data/node_modules/wouter-preact/cjs/react-deps.js +0 -75
- data/node_modules/wouter-preact/cjs/static-location.js +0 -21
- data/node_modules/wouter-preact/cjs/use-location.js +0 -94
- data/node_modules/wouter-preact/index.d.ts +0 -110
- data/node_modules/wouter-preact/index.js +0 -178
- data/node_modules/wouter-preact/matcher.d.ts +0 -30
- data/node_modules/wouter-preact/matcher.js +0 -66
- data/node_modules/wouter-preact/package.json +0 -33
- data/node_modules/wouter-preact/react-deps.js +0 -15
- data/node_modules/wouter-preact/static-location.d.ts +0 -16
- data/node_modules/wouter-preact/static-location.js +0 -17
- data/node_modules/wouter-preact/use-location.d.ts +0 -43
- data/node_modules/wouter-preact/use-location.js +0 -86
- data/package.json +0 -8
@@ -0,0 +1,58 @@
|
|
1
|
+
module Browser
|
2
|
+
module Window
|
3
|
+
extend DelegateNative
|
4
|
+
extend EventTarget
|
5
|
+
|
6
|
+
@native = `window`
|
7
|
+
|
8
|
+
module_function
|
9
|
+
|
10
|
+
if `#@native.requestAnimationFrame !== undefined`
|
11
|
+
# Add the given block to the current iteration of the event loop. If this
|
12
|
+
# is called from another `animation_frame` call, the block is run in the
|
13
|
+
# following iteration of the event loop.
|
14
|
+
def animation_frame &block
|
15
|
+
`requestAnimationFrame(function(now) { #{block.call `now`} })`
|
16
|
+
self
|
17
|
+
end
|
18
|
+
else
|
19
|
+
def animation_frame &block
|
20
|
+
after(0, &block)
|
21
|
+
self
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Run the given block every `duration` seconds
|
26
|
+
#
|
27
|
+
# @param duration [Numeric] the number of seconds between runs
|
28
|
+
def set_interval duration, &block
|
29
|
+
`setInterval(function() { #{block.call} }, duration)`
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_timeout duration, &block
|
33
|
+
`setTimeout(function() { #{block.call} }, duration)`
|
34
|
+
end
|
35
|
+
|
36
|
+
# return [History] the browser's History object
|
37
|
+
def history
|
38
|
+
Browser::History.new(`window.history`)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Location] the browser's Location object
|
42
|
+
def location
|
43
|
+
Browser::Location.new(`window.location`)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Scroll to the specified (x,y) coordinates
|
47
|
+
def scroll x, y
|
48
|
+
`window.scrollTo(x, y)`
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module_function
|
53
|
+
|
54
|
+
# return [Window] the browser's Window object
|
55
|
+
def window
|
56
|
+
Window
|
57
|
+
end
|
58
|
+
end
|
data/lib/data_uri/uri.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
module URI
|
2
|
+
class Data < Generic
|
3
|
+
COMPONENT = [:scheme, :opaque]
|
4
|
+
MIME_TYPE_RE = %r{^([-\w.+]+/[-\w.+]*)}
|
5
|
+
MIME_PARAM_RE = /^;([-\w.+]+)=([^;,]+)/
|
6
|
+
|
7
|
+
attr_reader :content_type, :data
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
if args.length == 1
|
11
|
+
uri = args.first.to_s
|
12
|
+
unless uri.match(/^data:/)
|
13
|
+
raise URI::InvalidURIError.new('Invalid Data URI: ' + args.first.inspect)
|
14
|
+
end
|
15
|
+
@scheme = 'data'
|
16
|
+
@opaque = uri[5 .. -1]
|
17
|
+
else
|
18
|
+
super(*args)
|
19
|
+
end
|
20
|
+
@data = @opaque
|
21
|
+
if md = MIME_TYPE_RE.match(@data)
|
22
|
+
@content_type = md[1]
|
23
|
+
@data = @data[@content_type.length .. -1]
|
24
|
+
end
|
25
|
+
@content_type ||= 'text/plain'
|
26
|
+
@mime_params = {}
|
27
|
+
while md = MIME_PARAM_RE.match(@data)
|
28
|
+
@mime_params[md[1]] = md[2]
|
29
|
+
@data = @data[md[0].length .. -1]
|
30
|
+
end
|
31
|
+
if base64 = /^;base64/.match(@data)
|
32
|
+
@data = @data[7 .. -1]
|
33
|
+
end
|
34
|
+
unless /^,/.match(@data)
|
35
|
+
raise URI::InvalidURIError.new('Invalid data URI')
|
36
|
+
end
|
37
|
+
@data = @data[1 .. -1]
|
38
|
+
@data = base64 ? Base64.decode64(@data) : URI.decode(@data)
|
39
|
+
if @data.respond_to?(:force_encoding) && charset = @mime_params['charset']
|
40
|
+
@data.force_encoding(charset)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.build(arg)
|
45
|
+
data = nil
|
46
|
+
content_type = nil
|
47
|
+
case arg
|
48
|
+
when IO
|
49
|
+
data = arg
|
50
|
+
when Hash
|
51
|
+
data = arg[:data]
|
52
|
+
content_type = arg[:content_type]
|
53
|
+
end
|
54
|
+
raise 'Invalid build argument: ' + arg.inspect unless data
|
55
|
+
if !content_type && data.respond_to?(:content_type)
|
56
|
+
content_type = data.content_type
|
57
|
+
end
|
58
|
+
new('data', nil, nil, nil, nil, nil, "#{content_type};base64,#{Base64.encode64(data.read).chop}", nil, nil)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/data_uri.rb
ADDED
@@ -2,13 +2,13 @@ module Isomorfeus
|
|
2
2
|
if RUBY_ENGINE == 'opal'
|
3
3
|
class << self
|
4
4
|
attr_accessor :browser_history
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :browser_location
|
6
|
+
attr_accessor :current_user_sid_s
|
6
7
|
attr_accessor :initial_state_fetched
|
7
|
-
attr_accessor :top_component
|
8
8
|
attr_accessor :ssr_response_status
|
9
|
+
attr_accessor :top_component
|
9
10
|
attr_reader :initialized
|
10
11
|
attr_reader :env
|
11
|
-
attr_accessor :zeitwerk
|
12
12
|
|
13
13
|
def init
|
14
14
|
return if initialized
|
@@ -23,74 +23,63 @@ module Isomorfeus
|
|
23
23
|
execute_init_classes
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def add_client_init_after_store_class_name(init_class_name)
|
31
|
-
client_init_after_store_class_names << init_class_name
|
26
|
+
def start_app!
|
27
|
+
Isomorfeus.zeitwerk.setup
|
28
|
+
Isomorfeus::TopLevel.mount!
|
32
29
|
end
|
33
30
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
31
|
+
def force_render
|
32
|
+
root_element = `document.querySelector('div[data-iso-root]')`
|
33
|
+
Preact.unmount_component_at_node(root_element)
|
34
|
+
Isomorfeus::TopLevel.do_the_mount!(init: false)
|
35
|
+
nil
|
36
|
+
rescue Exception => e
|
37
|
+
`console.error("force_render failed'! Error: " + #{e.message} + "! Reloading page.")`
|
38
|
+
`location.reload()`
|
37
39
|
end
|
40
|
+
end
|
41
|
+
else # RUBY_ENGINE
|
42
|
+
class << self
|
43
|
+
attr_reader :component_cache_init_block
|
44
|
+
attr_accessor :server_side_rendering
|
45
|
+
attr_accessor :ssr_hot_asset_url
|
38
46
|
|
39
|
-
def
|
40
|
-
|
41
|
-
constant.constantize.send(:init)
|
42
|
-
end
|
47
|
+
def ssr_response_status
|
48
|
+
Thread.current[:@_isomorfeus_preact_ssr_response_status]
|
43
49
|
end
|
44
50
|
|
45
|
-
def
|
46
|
-
|
47
|
-
constant_name.constantize.send(:init)
|
48
|
-
end
|
51
|
+
def ssr_response_status=(s)
|
52
|
+
Thread.current[:@_isomorfeus_preact_ssr_response_status] = s
|
49
53
|
end
|
50
54
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
@test = (@env == 'test') ? true : false
|
55
|
+
def init
|
56
|
+
return if Thread.current[:@_isomorfeus_initialized]
|
57
|
+
Thread.current[:@_isomorfeus_initialized] = true
|
58
|
+
Isomorfeus.init_store
|
59
|
+
execute_init_classes
|
57
60
|
end
|
58
61
|
|
59
|
-
def
|
60
|
-
|
62
|
+
def force_init!
|
63
|
+
Thread.current[:@_isomorfeus_initialized] = true
|
64
|
+
Isomorfeus.force_init_store!
|
65
|
+
execute_init_classes
|
61
66
|
end
|
62
67
|
|
63
|
-
def
|
64
|
-
@
|
68
|
+
def browser_history
|
69
|
+
@_isomorfeus_browser_history
|
65
70
|
end
|
66
71
|
|
67
|
-
def
|
68
|
-
@
|
72
|
+
def browser_history=(h)
|
73
|
+
@_isomorfeus_browser_history = h
|
69
74
|
end
|
70
75
|
|
71
|
-
def
|
72
|
-
|
73
|
-
Isomorfeus::TopLevel.mount! unless on_ssr?
|
76
|
+
def browser_location
|
77
|
+
Thread.current[:@_isomorfeus_browser_location]
|
74
78
|
end
|
75
79
|
|
76
|
-
def
|
77
|
-
|
78
|
-
nil
|
79
|
-
rescue Exception => e
|
80
|
-
`console.error("force_render failed'! Error: " + #{e.message} + "! Reloading page.")`
|
81
|
-
`location.reload()` if on_browser?
|
80
|
+
def browser_location=(l)
|
81
|
+
Thread.current[:@_isomorfeus_browser_location] = l
|
82
82
|
end
|
83
|
-
end
|
84
|
-
|
85
|
-
self.add_client_option(:client_init_class_names, [])
|
86
|
-
self.add_client_option(:client_init_after_store_class_names, [])
|
87
|
-
else
|
88
|
-
class << self
|
89
|
-
attr_reader :component_cache_init_block
|
90
|
-
attr_accessor :server_side_rendering
|
91
|
-
attr_accessor :ssr_hot_asset_url
|
92
|
-
attr_accessor :zeitwerk
|
93
|
-
attr_accessor :zeitwerk_lock
|
94
83
|
|
95
84
|
def component_cache_init(&block)
|
96
85
|
@component_cache_init_block = block
|
@@ -114,7 +103,7 @@ module Isomorfeus
|
|
114
103
|
end
|
115
104
|
end
|
116
105
|
end
|
117
|
-
end
|
106
|
+
end # RUBY_ENGINE
|
118
107
|
|
119
108
|
class << self
|
120
109
|
def raise_error(error: nil, error_class: nil, message: nil, stack: nil)
|
@@ -122,7 +111,6 @@ module Isomorfeus
|
|
122
111
|
|
123
112
|
error_class = RuntimeError unless error_class
|
124
113
|
execution_environment = if on_browser? then 'on Browser'
|
125
|
-
elsif on_ssr? then 'in Server Side Rendering'
|
126
114
|
elsif on_server? then 'on Server'
|
127
115
|
else
|
128
116
|
'on Client'
|
@@ -1,24 +1,9 @@
|
|
1
1
|
module Isomorfeus
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
Isomorfeus.
|
6
|
-
|
7
|
-
Isomorfeus.add_common_js_import('preact/hooks', 'PreactHooks', '*')
|
8
|
-
Isomorfeus.add_common_js_import('wouter-preact', nil, ['Router', 'Link', 'Redirect', 'Route', 'Switch'])
|
9
|
-
|
10
|
-
Isomorfeus.add_ssr_js_import('preact-render-to-string', 'Preact', ['render'], nil, 'renderToString')
|
11
|
-
Isomorfeus.add_ssr_js_import('wouter-preact/static-location', 'staticLocationHook')
|
12
|
-
|
13
|
-
Isomorfeus.add_web_js_import('wouter-preact/use-location', 'locationHook')
|
14
|
-
|
15
|
-
if Dir.exist?(Isomorfeus.app_root)
|
16
|
-
if File.exist?(File.join(Isomorfeus.app_root, 'isomorfeus_loader.rb'))
|
17
|
-
Isomorfeus.add_common_ruby_import('isomorfeus_loader')
|
18
|
-
Isomorfeus.add_ssr_ruby_import('isomorfeus/preact/ssr/top_level')
|
19
|
-
Isomorfeus.add_ssr_ruby_import('isomorfeus/preact/ssr/render_core')
|
20
|
-
Isomorfeus.add_ssr_ruby_import('isomorfeus/preact/ssr/history')
|
21
|
-
end
|
2
|
+
module PreactImports
|
3
|
+
def self.add
|
4
|
+
if Dir.exist?(Isomorfeus.app_root)
|
5
|
+
if File.exist?(File.join(Isomorfeus.app_root, 'isomorfeus_loader.rb'))
|
6
|
+
Isomorfeus.add_web_ruby_import('isomorfeus_loader')
|
22
7
|
end
|
23
8
|
end
|
24
9
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
class PreactSSR
|
3
|
+
def self.mount_component(component_name, props, session_id, location, locale = nil)
|
4
|
+
rendered_tree = new(component_name, props, session_id, location, locale).render
|
5
|
+
[rendered_tree, Isomorfeus.store.get_state, NanoCSS.instance.renderer[:raw]]
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(component_name, props, session_id, location, locale = nil)
|
9
|
+
@session_id = session_id
|
10
|
+
@component_name = component_name
|
11
|
+
@props = props
|
12
|
+
@location = location
|
13
|
+
@locale = locale
|
14
|
+
end
|
15
|
+
|
16
|
+
def render
|
17
|
+
Isomorfeus.browser_location = Browser::Location.new(@location)
|
18
|
+
Isomorfeus.current_locale = @locale
|
19
|
+
NanoCSS.instance = NanoCSS.new(given_renderer: NanoCSS.global_instance.renderer.deep_dup)
|
20
|
+
Isomorfeus.init_store
|
21
|
+
Isomorfeus.store.clear!
|
22
|
+
c = Isomorfeus.current_user
|
23
|
+
if c.respond_to?(:reload)
|
24
|
+
Thread.current[:isomorfeus_user] = LocalSystem.new
|
25
|
+
begin
|
26
|
+
c.reload
|
27
|
+
ensure
|
28
|
+
Thread.current[:isomorfeus_user] = c
|
29
|
+
end
|
30
|
+
end
|
31
|
+
Isomorfeus::TopLevel.render_component_to_string(@component_name, @props)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,17 +1,15 @@
|
|
1
1
|
module Isomorfeus
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
2
|
+
class ThreadLocalComponentCache
|
3
|
+
def initialize
|
4
|
+
Thread.current[:local_cache] = {} unless Thread.current.key?(:local_cache)
|
5
|
+
end
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def fetch(key)
|
8
|
+
Thread.current[:local_cache][key]
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
11
|
+
def store(key, rendered_tree, response_status, styles)
|
12
|
+
Thread.current[:local_cache][key] = [rendered_tree, response_status, styles]
|
15
13
|
end
|
16
14
|
end
|
17
15
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Preact
|
2
|
+
module ViewHelper
|
3
|
+
def self.included(base)
|
4
|
+
base.include Isomorfeus::AssetManager::ViewHelper
|
5
|
+
end
|
6
|
+
|
7
|
+
def cached_mount_component(component_name, props = {}, skip_ssr: false, use_ssr: false, refresh: false)
|
8
|
+
key = "#{Isomorfeus.current_user}#{component_name}#{props}"
|
9
|
+
if !Isomorfeus.development? && !refresh
|
10
|
+
render_result, @_ssr_styles, status = component_cache.fetch(key)
|
11
|
+
Isomorfeus.ssr_response_status = status
|
12
|
+
return render_result if render_result
|
13
|
+
end
|
14
|
+
render_result = mount_component(component_name, props, asset_key, skip_ssr: skip_ssr, use_ssr: use_ssr)
|
15
|
+
status = ssr_response_status
|
16
|
+
component_cache.store(key, render_result, ssr_styles, status) if status >= 200 && status < 300
|
17
|
+
render_result
|
18
|
+
end
|
19
|
+
|
20
|
+
def mount_component(component_name, props = {}, skip_ssr: false, use_ssr: false)
|
21
|
+
ssr_start_time = Time.now if Isomorfeus.development?
|
22
|
+
@ssr_styles = nil
|
23
|
+
render_result = "<div data-iso-env=\"#{Isomorfeus.env}\" data-iso-root=\"#{component_name}\" data-iso-props='#{Oj.dump(props, mode: :strict)}'"
|
24
|
+
if !skip_ssr && (Isomorfeus.server_side_rendering || use_ssr)
|
25
|
+
location_host = props[:location_host] ? props[:location_host] : 'localhost'
|
26
|
+
location = "#{props[:location_scheme] || 'http:'}//#{location_host}#{props[:location]}"
|
27
|
+
|
28
|
+
rendered_tree, application_state, @_ssr_styles = Isomorfeus::PreactSSR.mount_component(component_name, props, Thread.current[:isomorfeus_session_id], location, props[:locale])
|
29
|
+
|
30
|
+
render_result << " data-iso-hydrated='true'" if rendered_tree
|
31
|
+
if Isomorfeus.respond_to?(:current_user) && Isomorfeus.current_user && !Isomorfeus.current_user.anonymous?
|
32
|
+
render_result << " data-iso-usids=#{Oj.dump(Isomorfeus.current_user.sid.to_s, mode: :strict)}"
|
33
|
+
end
|
34
|
+
render_result << " data-iso-nloc='#{props[:locale]}'>"
|
35
|
+
render_result << (rendered_tree ? rendered_tree : "SSR didn't work")
|
36
|
+
else
|
37
|
+
if Isomorfeus.respond_to?(:current_user) && Isomorfeus.current_user && !Isomorfeus.current_user.anonymous?
|
38
|
+
render_result << " data-iso-usids=#{Oj.dump(Isomorfeus.current_user.sid.to_s, mode: :strict)}"
|
39
|
+
end
|
40
|
+
render_result << " data-iso-nloc='#{props[:locale]}'>"
|
41
|
+
end
|
42
|
+
render_result << '</div>'
|
43
|
+
if Isomorfeus.server_side_rendering && !skip_ssr
|
44
|
+
render_result = "<script type='application/javascript'>\nServerSideRenderingStateJSON = #{Oj.dump(application_state, mode: :strict)}\n</script>\n" << render_result
|
45
|
+
puts "Preact::ViewHelper Server Side Rendering took ~#{((Time.now - ssr_start_time)*1000).to_i}ms" if Isomorfeus.development?
|
46
|
+
end
|
47
|
+
render_result
|
48
|
+
end
|
49
|
+
|
50
|
+
def ssr_response_status
|
51
|
+
Isomorfeus.ssr_response_status
|
52
|
+
end
|
53
|
+
|
54
|
+
def ssr_styles
|
55
|
+
@_ssr_styles || ''
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def component_cache
|
61
|
+
@_component_cache ||= Isomorfeus.component_cache_init_block.call
|
62
|
+
end
|
63
|
+
|
64
|
+
def ssr_mod
|
65
|
+
@_ssr_mod ||= Opal.compile(File.read(File.expand_path(File.join(File.dirname(__FILE__), 'ssr.rb'))), { use_strict: true })
|
66
|
+
end
|
67
|
+
|
68
|
+
def top_level_mod
|
69
|
+
@_top_level_mod ||= Opal.compile(File.read(File.expand_path(File.join(File.dirname(__FILE__), 'top_level_ssr.rb'))), { use_strict: true })
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -36,16 +36,24 @@ module Isomorfeus
|
|
36
36
|
def cast!
|
37
37
|
if @o.key?(:cast)
|
38
38
|
begin
|
39
|
-
@
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
return if @o[:is_a] && @v.is_a?(@o[:is_a])
|
40
|
+
return if @o[:class] && @v.class == @o[:class]
|
41
|
+
if @o[:type] == :boolean
|
42
|
+
@v = !!@v
|
43
|
+
return
|
44
|
+
end
|
45
|
+
cl = @o[:is_a] || @o[:class]
|
46
|
+
@v = case cl.name
|
47
|
+
when 'Integer' then @v.to_i
|
48
|
+
when 'String' then @v.to_s
|
49
|
+
when 'Float' then @v.to_f
|
50
|
+
when 'Array' then @v.to_a
|
51
|
+
when 'Hash' then @v.to_h
|
52
|
+
else
|
53
|
+
Isomorfeus.raise_error(message: "#{@c}: Dont know how to cast #{@p} to #{cl}!")
|
45
54
|
end
|
46
|
-
@v = !!@v if @o[:type] == :boolean
|
47
55
|
rescue
|
48
|
-
Isomorfeus.raise_error(message: "#{@c}: #{@p} cast failed")
|
56
|
+
Isomorfeus.raise_error(message: "#{@c}: #{@p} cast to #{cl} failed!")
|
49
57
|
end
|
50
58
|
end
|
51
59
|
end
|
@@ -105,7 +113,7 @@ module Isomorfeus
|
|
105
113
|
end
|
106
114
|
|
107
115
|
def c_size(v)
|
108
|
-
Isomorfeus.raise_error(message: "#{@c}: #{@p} length/size is not #{v}") unless @v.
|
116
|
+
Isomorfeus.raise_error(message: "#{@c}: #{@p} length/size is not #{v}") unless @v.length == v
|
109
117
|
end
|
110
118
|
|
111
119
|
def c_matches(v)
|
@@ -121,11 +129,11 @@ module Isomorfeus
|
|
121
129
|
end
|
122
130
|
|
123
131
|
def c_max_size(v)
|
124
|
-
Isomorfeus.raise_error(message: "#{@c}: #{@p} is larger than #{v}") unless @v.
|
132
|
+
Isomorfeus.raise_error(message: "#{@c}: #{@p} is larger than #{v}") unless @v.length <= v
|
125
133
|
end
|
126
134
|
|
127
135
|
def c_min_size(v)
|
128
|
-
Isomorfeus.raise_error(message: "#{@c}: #{@p} is smaller than #{v}") unless @v.
|
136
|
+
Isomorfeus.raise_error(message: "#{@c}: #{@p} is smaller than #{v}") unless @v.length >= v
|
129
137
|
end
|
130
138
|
|
131
139
|
def c_direction(v)
|
data/lib/isomorfeus/top_level.rb
CHANGED
@@ -4,20 +4,19 @@ module Isomorfeus
|
|
4
4
|
attr_accessor :hydrated
|
5
5
|
attr_accessor :first_pass
|
6
6
|
|
7
|
-
if
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
component =
|
18
|
-
|
19
|
-
|
20
|
-
rescue Exception => e
|
7
|
+
if RUBY_ENGINE == 'opal'
|
8
|
+
def do_the_mount!(init: true)
|
9
|
+
NanoCSS.instance = NanoCSS.new({ sh: `document.getElementById('css-server-side')` })
|
10
|
+
root_element = `document.querySelector('div[data-iso-root]')`
|
11
|
+
Isomorfeus.raise_error(message: "Isomorfeus root element not found!") unless root_element
|
12
|
+
component_name = root_element.JS.getAttribute('data-iso-root')
|
13
|
+
Isomorfeus.env = root_element.JS.getAttribute('data-iso-env')
|
14
|
+
Isomorfeus.current_user_sid_s = root_element.JS.getAttribute('data-iso-usids')
|
15
|
+
component = nil
|
16
|
+
begin
|
17
|
+
component = component_name.constantize
|
18
|
+
rescue Exception => e
|
19
|
+
if init
|
21
20
|
`console.warn("Deferring mount: " + #{e.message})`
|
22
21
|
@timeout_start = Time.now unless @timeout_start
|
23
22
|
if (Time.now - @timeout_start) < 10
|
@@ -25,33 +24,39 @@ module Isomorfeus
|
|
25
24
|
else
|
26
25
|
`console.error("Unable to mount '" + #{component_name} + "'!")`
|
27
26
|
end
|
27
|
+
else
|
28
|
+
raise e
|
28
29
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
end
|
31
|
+
if component
|
32
|
+
props_json = root_element.JS.getAttribute('data-iso-props')
|
33
|
+
props = JSON.parse(props_json)
|
34
|
+
if init
|
32
35
|
raw_hydrated = root_element.JS.getAttribute('data-iso-hydrated')
|
33
|
-
|
36
|
+
Isomorfeus::TopLevel.hydrated = (raw_hydrated && raw_hydrated == "true")
|
34
37
|
%x{
|
35
38
|
if (global.ServerSideRenderingStateJSON) {
|
36
39
|
var state = global.ServerSideRenderingStateJSON;
|
37
40
|
var keys = Object.keys(state);
|
38
41
|
for(var i=0; i < keys.length; i++) {
|
39
42
|
if (Object.keys(state[keys[i]]).length > 0) {
|
40
|
-
|
43
|
+
#{Isomorfeus.store.dispatch({ type: `keys[i].toUpperCase()`, set_state: Hash.new(`state[keys[i]]`) })}
|
41
44
|
}
|
42
45
|
}
|
43
46
|
}
|
44
47
|
}
|
45
48
|
Isomorfeus.execute_init_after_store_classes
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
end
|
50
|
+
begin
|
51
|
+
Isomorfeus::TopLevel.first_pass = true
|
52
|
+
result = Isomorfeus::TopLevel.mount_component(component, props, root_element, Isomorfeus::TopLevel.hydrated)
|
53
|
+
Isomorfeus::TopLevel.first_pass = false
|
54
|
+
@tried_another_time = false
|
55
|
+
result
|
56
|
+
rescue Exception => e
|
57
|
+
if init
|
58
|
+
Isomorfeus::TopLevel.first_pass = false
|
59
|
+
if !@tried_another_time
|
55
60
|
@tried_another_time = true
|
56
61
|
`console.warn("Deferring mount: " + #{e.message})`
|
57
62
|
`console.error(#{e.backtrace.join("\n")})`
|
@@ -60,11 +65,20 @@ module Isomorfeus
|
|
60
65
|
`console.error("Unable to mount '" + #{component_name} + "'! Error: " + #{e.message} + "!")`
|
61
66
|
`console.error(#{e.backtrace.join("\n")})`
|
62
67
|
end
|
68
|
+
else
|
69
|
+
raise e
|
63
70
|
end
|
64
71
|
end
|
65
72
|
end
|
66
73
|
end
|
67
74
|
|
75
|
+
def mount!
|
76
|
+
Isomorfeus.init
|
77
|
+
Isomorfeus::TopLevel.on_ready do
|
78
|
+
Isomorfeus::TopLevel.do_the_mount!
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
68
82
|
def on_ready(&block)
|
69
83
|
%x{
|
70
84
|
function run() { block.$call() };
|
@@ -88,18 +102,26 @@ module Isomorfeus
|
|
88
102
|
end
|
89
103
|
|
90
104
|
def mount_component(component, props, element_or_query, hydrated = false)
|
91
|
-
if `(
|
105
|
+
if `(element_or_query instanceof HTMLElement)`
|
106
|
+
element = element_or_query
|
107
|
+
elsif `(typeof element_or_query === 'string')` || element_or_query.is_a?(String)
|
92
108
|
element = `document.body.querySelector(element_or_query)`
|
93
|
-
elsif
|
109
|
+
elsif element_or_query.is_a?(Browser::Element)
|
94
110
|
element = element_or_query.to_n
|
95
111
|
else
|
96
112
|
element = element_or_query
|
97
113
|
end
|
98
|
-
|
99
|
-
top = Preact.create_element(component, props)
|
100
|
-
hydrated ? Preact.hydrate(top, element) : Preact.render(top, element)
|
114
|
+
raise "Element is required!" unless element
|
115
|
+
top = ::Preact.create_element(component, props)
|
116
|
+
hydrated ? ::Preact.hydrate(top, element) : ::Preact.render(top, element)
|
101
117
|
Isomorfeus.top_component = top
|
102
118
|
end
|
119
|
+
else
|
120
|
+
def render_component_to_string(component_name, props)
|
121
|
+
component = component_name.is_a?(String) ? const_get(component_name) : component_name
|
122
|
+
::Preact._vnode_id = 0
|
123
|
+
::Preact.render_to_string(::Preact.create_element(component, props))
|
124
|
+
end
|
103
125
|
end
|
104
126
|
end
|
105
127
|
end
|