turbo_reflex 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +23 -18
- data/README.md +1 -1
- data/Rakefile +7 -1
- data/app/assets/builds/turbo_reflex.js +1 -1
- data/app/assets/builds/turbo_reflex.js.map +4 -4
- data/app/controllers/concerns/turbo_reflex/controller.rb +14 -0
- data/app/javascript/drivers/window.js +12 -4
- data/app/javascript/elements.js +1 -1
- data/app/javascript/events.js +30 -0
- data/app/javascript/index.js +10 -5
- data/app/javascript/lifecycle.js +2 -33
- data/app/javascript/logger.js +6 -10
- data/app/javascript/meta.js +0 -21
- data/app/javascript/state/index.js +52 -0
- data/app/javascript/state/observable.js +36 -0
- data/app/javascript/turbo.js +15 -4
- data/lib/turbo_reflex/base.rb +25 -21
- data/lib/turbo_reflex/controller_pack.rb +1 -1
- data/lib/turbo_reflex/errors.rb +12 -0
- data/lib/turbo_reflex/runner.rb +39 -18
- data/lib/turbo_reflex/state.rb +114 -0
- data/lib/turbo_reflex/state_manager.rb +102 -0
- data/lib/turbo_reflex/version.rb +1 -1
- data/package.json +1 -1
- data/tags +2902 -2985
- data/yarn.lock +32 -43
- metadata +8 -4
- data/Dockerfile.orig +0 -49
- data/lib/turbo_reflex/ui_state.rb +0 -118
data/yarn.lock
CHANGED
@@ -43,11 +43,11 @@
|
|
43
43
|
integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==
|
44
44
|
|
45
45
|
"@babel/runtime@^7.8.7":
|
46
|
-
version "7.
|
47
|
-
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.
|
48
|
-
integrity sha512-
|
46
|
+
version "7.20.1"
|
47
|
+
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9"
|
48
|
+
integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==
|
49
49
|
dependencies:
|
50
|
-
regenerator-runtime "^0.13.
|
50
|
+
regenerator-runtime "^0.13.10"
|
51
51
|
|
52
52
|
"@esbuild/android-arm@0.15.12":
|
53
53
|
version "0.15.12"
|
@@ -94,14 +94,14 @@
|
|
94
94
|
resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.41.4.tgz#508fd82ca40305416e130f0da7b537295ded7989"
|
95
95
|
integrity sha512-DwS94K+M0vtG+cymxH0rslJr09qpdjyOLdCjmpKcG/nNiZQfMA1ybAaFEmwk9UaVlUG9STENFeQwyrLevJB+7g==
|
96
96
|
|
97
|
-
"@humanwhocodes/config-array@^0.
|
98
|
-
version "0.
|
99
|
-
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.
|
100
|
-
integrity sha512-
|
97
|
+
"@humanwhocodes/config-array@^0.11.6":
|
98
|
+
version "0.11.7"
|
99
|
+
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f"
|
100
|
+
integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==
|
101
101
|
dependencies:
|
102
102
|
"@humanwhocodes/object-schema" "^1.2.1"
|
103
103
|
debug "^4.1.1"
|
104
|
-
minimatch "^3.0.
|
104
|
+
minimatch "^3.0.5"
|
105
105
|
|
106
106
|
"@humanwhocodes/module-importer@^1.0.1":
|
107
107
|
version "1.0.1"
|
@@ -131,7 +131,7 @@
|
|
131
131
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
|
132
132
|
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
133
133
|
|
134
|
-
"@nodelib/fs.walk@^1.2.3":
|
134
|
+
"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8":
|
135
135
|
version "1.2.8"
|
136
136
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
|
137
137
|
integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
|
@@ -165,9 +165,9 @@
|
|
165
165
|
integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==
|
166
166
|
|
167
167
|
"@types/node@*":
|
168
|
-
version "18.11.
|
169
|
-
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.
|
170
|
-
integrity sha512-
|
168
|
+
version "18.11.9"
|
169
|
+
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4"
|
170
|
+
integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==
|
171
171
|
|
172
172
|
"@types/unist@^2.0.0", "@types/unist@^2.0.2":
|
173
173
|
version "2.0.6"
|
@@ -197,9 +197,9 @@ acorn@^7.1.1:
|
|
197
197
|
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
198
198
|
|
199
199
|
acorn@^8.8.0:
|
200
|
-
version "8.8.
|
201
|
-
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.
|
202
|
-
integrity sha512-
|
200
|
+
version "8.8.1"
|
201
|
+
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
|
202
|
+
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
|
203
203
|
|
204
204
|
agent-base@5:
|
205
205
|
version "5.1.1"
|
@@ -909,13 +909,14 @@ eslint@^6.8.0:
|
|
909
909
|
v8-compile-cache "^2.0.3"
|
910
910
|
|
911
911
|
eslint@^8.19.0:
|
912
|
-
version "8.
|
913
|
-
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.
|
914
|
-
integrity sha512-
|
912
|
+
version "8.26.0"
|
913
|
+
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.26.0.tgz#2bcc8836e6c424c4ac26a5674a70d44d84f2181d"
|
914
|
+
integrity sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==
|
915
915
|
dependencies:
|
916
916
|
"@eslint/eslintrc" "^1.3.3"
|
917
|
-
"@humanwhocodes/config-array" "^0.
|
917
|
+
"@humanwhocodes/config-array" "^0.11.6"
|
918
918
|
"@humanwhocodes/module-importer" "^1.0.1"
|
919
|
+
"@nodelib/fs.walk" "^1.2.8"
|
919
920
|
ajv "^6.10.0"
|
920
921
|
chalk "^4.0.0"
|
921
922
|
cross-spawn "^7.0.2"
|
@@ -931,14 +932,14 @@ eslint@^8.19.0:
|
|
931
932
|
fast-deep-equal "^3.1.3"
|
932
933
|
file-entry-cache "^6.0.1"
|
933
934
|
find-up "^5.0.0"
|
934
|
-
glob-parent "^6.0.
|
935
|
+
glob-parent "^6.0.2"
|
935
936
|
globals "^13.15.0"
|
936
|
-
globby "^11.1.0"
|
937
937
|
grapheme-splitter "^1.0.4"
|
938
938
|
ignore "^5.2.0"
|
939
939
|
import-fresh "^3.0.0"
|
940
940
|
imurmurhash "^0.1.4"
|
941
941
|
is-glob "^4.0.0"
|
942
|
+
is-path-inside "^3.0.3"
|
942
943
|
js-sdsl "^4.1.4"
|
943
944
|
js-yaml "^4.1.0"
|
944
945
|
json-stable-stringify-without-jsonify "^1.0.1"
|
@@ -1038,7 +1039,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
|
1038
1039
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
1039
1040
|
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
1040
1041
|
|
1041
|
-
fast-glob@^3.0.3
|
1042
|
+
fast-glob@^3.0.3:
|
1042
1043
|
version "3.2.12"
|
1043
1044
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
|
1044
1045
|
integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
|
@@ -1221,7 +1222,7 @@ glob-parent@^5.0.0, glob-parent@^5.1.2:
|
|
1221
1222
|
dependencies:
|
1222
1223
|
is-glob "^4.0.1"
|
1223
1224
|
|
1224
|
-
glob-parent@^6.0.
|
1225
|
+
glob-parent@^6.0.2:
|
1225
1226
|
version "6.0.2"
|
1226
1227
|
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
1227
1228
|
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
|
@@ -1279,18 +1280,6 @@ globby@^10.0.1:
|
|
1279
1280
|
merge2 "^1.2.3"
|
1280
1281
|
slash "^3.0.0"
|
1281
1282
|
|
1282
|
-
globby@^11.1.0:
|
1283
|
-
version "11.1.0"
|
1284
|
-
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
|
1285
|
-
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
|
1286
|
-
dependencies:
|
1287
|
-
array-union "^2.1.0"
|
1288
|
-
dir-glob "^3.0.1"
|
1289
|
-
fast-glob "^3.2.9"
|
1290
|
-
ignore "^5.2.0"
|
1291
|
-
merge2 "^1.4.1"
|
1292
|
-
slash "^3.0.0"
|
1293
|
-
|
1294
1283
|
graceful-fs@^4.2.2:
|
1295
1284
|
version "4.2.10"
|
1296
1285
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
|
@@ -1551,7 +1540,7 @@ is-path-cwd@^2.2.0:
|
|
1551
1540
|
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
|
1552
1541
|
integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==
|
1553
1542
|
|
1554
|
-
is-path-inside@^3.0.1:
|
1543
|
+
is-path-inside@^3.0.1, is-path-inside@^3.0.3:
|
1555
1544
|
version "3.0.3"
|
1556
1545
|
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
|
1557
1546
|
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
|
@@ -1861,7 +1850,7 @@ merge-stream@^2.0.0:
|
|
1861
1850
|
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
1862
1851
|
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
1863
1852
|
|
1864
|
-
merge2@^1.2.3, merge2@^1.3.0
|
1853
|
+
merge2@^1.2.3, merge2@^1.3.0:
|
1865
1854
|
version "1.4.1"
|
1866
1855
|
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
1867
1856
|
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
@@ -1896,7 +1885,7 @@ minimatch@3.0.4:
|
|
1896
1885
|
dependencies:
|
1897
1886
|
brace-expansion "^1.1.7"
|
1898
1887
|
|
1899
|
-
minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
1888
|
+
minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
|
1900
1889
|
version "3.1.2"
|
1901
1890
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
1902
1891
|
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
@@ -2373,7 +2362,7 @@ queue-microtask@^1.2.2:
|
|
2373
2362
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
2374
2363
|
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
2375
2364
|
|
2376
|
-
regenerator-runtime@^0.13.
|
2365
|
+
regenerator-runtime@^0.13.10:
|
2377
2366
|
version "0.13.10"
|
2378
2367
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee"
|
2379
2368
|
integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==
|
@@ -2823,9 +2812,9 @@ type-fest@^0.8.1:
|
|
2823
2812
|
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
2824
2813
|
|
2825
2814
|
uglify-js@^3.1.4:
|
2826
|
-
version "3.17.
|
2827
|
-
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.
|
2828
|
-
integrity sha512-
|
2815
|
+
version "3.17.4"
|
2816
|
+
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c"
|
2817
|
+
integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==
|
2829
2818
|
|
2830
2819
|
unherit@^1.0.4:
|
2831
2820
|
version "1.1.3"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo_reflex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Hopkins (hopsoft)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -356,7 +356,6 @@ extra_rdoc_files: []
|
|
356
356
|
files:
|
357
357
|
- CODE_OF_CONDUCT.md
|
358
358
|
- Dockerfile
|
359
|
-
- Dockerfile.orig
|
360
359
|
- Gemfile
|
361
360
|
- Gemfile.lock
|
362
361
|
- MIT-LICENSE
|
@@ -377,12 +376,15 @@ files:
|
|
377
376
|
- app/javascript/drivers/turbo_form.js
|
378
377
|
- app/javascript/drivers/window.js
|
379
378
|
- app/javascript/elements.js
|
379
|
+
- app/javascript/events.js
|
380
380
|
- app/javascript/index.js
|
381
381
|
- app/javascript/lifecycle.js
|
382
382
|
- app/javascript/logger.js
|
383
383
|
- app/javascript/meta.js
|
384
384
|
- app/javascript/renderer.js
|
385
385
|
- app/javascript/schema.js
|
386
|
+
- app/javascript/state/index.js
|
387
|
+
- app/javascript/state/observable.js
|
386
388
|
- app/javascript/turbo.js
|
387
389
|
- app/javascript/urls.js
|
388
390
|
- app/javascript/uuids.js
|
@@ -395,9 +397,11 @@ files:
|
|
395
397
|
- lib/turbo_reflex/base.rb
|
396
398
|
- lib/turbo_reflex/controller_pack.rb
|
397
399
|
- lib/turbo_reflex/engine.rb
|
400
|
+
- lib/turbo_reflex/errors.rb
|
398
401
|
- lib/turbo_reflex/runner.rb
|
399
402
|
- lib/turbo_reflex/sanitizer.rb
|
400
|
-
- lib/turbo_reflex/
|
403
|
+
- lib/turbo_reflex/state.rb
|
404
|
+
- lib/turbo_reflex/state_manager.rb
|
401
405
|
- lib/turbo_reflex/version.rb
|
402
406
|
- package.json
|
403
407
|
- tags
|
data/Dockerfile.orig
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
FROM ruby:3.1.2
|
2
|
-
|
3
|
-
RUN apt-get -y update && \
|
4
|
-
apt-get -y upgrade && \
|
5
|
-
apt-get -y --allow-downgrades --allow-remove-essential --allow-change-held-packages install \
|
6
|
-
build-essential \
|
7
|
-
git \
|
8
|
-
nodejs \
|
9
|
-
npm \
|
10
|
-
sqlite3 \
|
11
|
-
tzdata && \
|
12
|
-
apt-get clean
|
13
|
-
|
14
|
-
<<<<<<< HEAD
|
15
|
-
# prepare the environment
|
16
|
-
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true RAILS_SERVE_STATIC_FILES=true
|
17
|
-
|
18
|
-
=======
|
19
|
-
>>>>>>> main
|
20
|
-
# setup ruby gems
|
21
|
-
RUN gem update --system && \
|
22
|
-
gem install bundler && \
|
23
|
-
bundle config set --global --without test
|
24
|
-
|
25
|
-
# setup yarn
|
26
|
-
RUN npm install -g yarn
|
27
|
-
|
28
|
-
# get application code
|
29
|
-
RUN git clone --origin github --branch main --depth 1 https://github.com/hopsoft/turbo_reflex.git /opt/turbo_reflex
|
30
|
-
|
31
|
-
# install application dependencies 1st time
|
32
|
-
WORKDIR /opt/turbo_reflex
|
33
|
-
RUN yarn
|
34
|
-
WORKDIR /opt/turbo_reflex/test/dummy
|
35
|
-
RUN bundle
|
36
|
-
|
37
|
-
# prepare the environment
|
38
|
-
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true RAILS_SERVE_STATIC_FILES=true
|
39
|
-
|
40
|
-
# prepare and run the application
|
41
|
-
CMD git pull --no-rebase github && \
|
42
|
-
git checkout hopsoft/hijack && \
|
43
|
-
cd /opt/turbo_reflex && yarn && \
|
44
|
-
cd /opt/turbo_reflex/test/dummy && bundle && \
|
45
|
-
rm -f tmp/pids/server.pid && \
|
46
|
-
bin/rails db:create db:migrate && \
|
47
|
-
bin/rails assets:clobber && \
|
48
|
-
bin/rails assets:precompile && \
|
49
|
-
bin/rails s --binding=0.0.0.0 --port=3000
|
@@ -1,118 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Class used to hold ephemeral state related to the rendered UI.
|
4
|
-
#
|
5
|
-
# Examples:
|
6
|
-
#
|
7
|
-
# - Sidebar open/closed state
|
8
|
-
# - Tree view open/closed state
|
9
|
-
# - Accordion collapsed/expanded state
|
10
|
-
# - Customized layout / presentation
|
11
|
-
# - Applied data filters
|
12
|
-
# - Number of data rows to display etc.
|
13
|
-
#
|
14
|
-
class TurboReflex::UiState
|
15
|
-
include ActiveModel::Dirty
|
16
|
-
|
17
|
-
class << self
|
18
|
-
def serialize(hash, message_verifier: nil)
|
19
|
-
return message_verifier.generate(hash.to_hash.to_json) if message_verifier
|
20
|
-
Base64.urlsafe_encode64 hash.to_hash.to_json, padding: false
|
21
|
-
end
|
22
|
-
|
23
|
-
def deserialize(value, message_verifier: nil)
|
24
|
-
return JSON.parse(message_verifier.verify(value)) if message_verifier&.valid_message?(value)
|
25
|
-
JSON.parse Base64.urlsafe_decode64(value)
|
26
|
-
rescue => e
|
27
|
-
Rails.logger.error "TurboReflex was unable to deserialize UI State! value=#{value.inspect} error=#{e.inspect}"
|
28
|
-
{}
|
29
|
-
end
|
30
|
-
|
31
|
-
def key_for(*keys)
|
32
|
-
keys.map { |key| key.try(:cache_key) || key.to_s }.join("/")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
attr_reader :hash
|
37
|
-
define_attribute_methods :hash
|
38
|
-
delegate :key_for, to: :"self.class"
|
39
|
-
delegate :request, :response, to: :controller
|
40
|
-
|
41
|
-
def initialize(controller)
|
42
|
-
@controller = controller
|
43
|
-
self.hash = cookies_hash
|
44
|
-
end
|
45
|
-
|
46
|
-
def hash=(hash)
|
47
|
-
@hash = hash.with_indifferent_access
|
48
|
-
end
|
49
|
-
|
50
|
-
def [](*keys)
|
51
|
-
hash[key_for(*keys)]
|
52
|
-
end
|
53
|
-
|
54
|
-
def []=(*keys, value)
|
55
|
-
hash_will_change! if value != self[*keys]
|
56
|
-
hash[key_for(*keys)] = value
|
57
|
-
value
|
58
|
-
end
|
59
|
-
|
60
|
-
def fetch(*keys, default)
|
61
|
-
value = self[*keys]
|
62
|
-
if value.nil? && default
|
63
|
-
hash_will_change!
|
64
|
-
value = self[*keys] = default
|
65
|
-
end
|
66
|
-
value
|
67
|
-
end
|
68
|
-
|
69
|
-
def serialize(signed: false)
|
70
|
-
return self.class.serialize(hash, message_verifier: message_verifier) if signed
|
71
|
-
self.class.serialize hash
|
72
|
-
end
|
73
|
-
|
74
|
-
def set_cookie
|
75
|
-
return unless changed?
|
76
|
-
cookies.each { |(key, _)| response.delete_cookie key.to_sym }
|
77
|
-
serialized_chunks(signed: true).each_with_index do |chunk, index|
|
78
|
-
key = :"turboreflex_uistate_#{index.to_s.rjust(6, "0")}"
|
79
|
-
response.set_cookie key, value: chunk
|
80
|
-
end
|
81
|
-
changes_applied
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
attr_reader :controller
|
87
|
-
|
88
|
-
# UI state gets split into chunks and saved in an HTTP cookie.
|
89
|
-
# Max size for an HTTP cookie is around 4k or 4,000 bytes.
|
90
|
-
# A Base64 character is an 8-bit-padded ASCII character... or 1 byte
|
91
|
-
def serialized_chunks(signed: false)
|
92
|
-
serialize(signed: signed).scan(/.{1,2000}/)
|
93
|
-
end
|
94
|
-
|
95
|
-
def headers
|
96
|
-
request.headers.select { |(key, _)| key.match?(/TURBOREFLEX_UISTATE/i) }.sort
|
97
|
-
end
|
98
|
-
|
99
|
-
# UI State that exists on the client.
|
100
|
-
def headers_hash
|
101
|
-
value = headers.map(&:last).join
|
102
|
-
value.present? ? self.class.deserialize(value) : {}
|
103
|
-
end
|
104
|
-
|
105
|
-
def cookies
|
106
|
-
request.cookies.select { |(key, _)| key.match?(/TURBOREFLEX_UISTATE/i) }.sort
|
107
|
-
end
|
108
|
-
|
109
|
-
# UI State the server already knows about.
|
110
|
-
def cookies_hash
|
111
|
-
value = cookies.map(&:last).join
|
112
|
-
value.present? ? self.class.deserialize(value, message_verifier: message_verifier) : {}
|
113
|
-
end
|
114
|
-
|
115
|
-
def message_verifier
|
116
|
-
ActiveSupport::MessageVerifier.new Rails.application.secret_key_base, digest: "SHA256"
|
117
|
-
end
|
118
|
-
end
|