hyper-mesh 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +396 -0
- data/Rakefile +6 -0
- data/app/controllers/reactive_record/application_controller.rb +4 -0
- data/app/controllers/reactive_record/reactive_record_controller.rb +49 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/codeship.database.yml +18 -0
- data/config/routes.rb +7 -0
- data/docs/action_cable_quickstart.md +151 -0
- data/docs/authorization-policies.md +449 -0
- data/docs/client_side_scoping.md +103 -0
- data/docs/pusher_quickstart.md +0 -0
- data/docs/simple_poller_quickstart.md +121 -0
- data/docs/todo-example.md +116 -0
- data/docs/words-example.md +65 -0
- data/examples/action-cable/.gitignore +21 -0
- data/examples/action-cable/Gemfile +58 -0
- data/examples/action-cable/Gemfile.lock +247 -0
- data/examples/action-cable/README.md +24 -0
- data/examples/action-cable/Rakefile +6 -0
- data/examples/action-cable/app/assets/config/manifest.js +3 -0
- data/examples/action-cable/app/assets/javascripts/application.js +18 -0
- data/examples/action-cable/app/assets/stylesheets/application.css +15 -0
- data/examples/action-cable/app/controllers/application_controller.rb +3 -0
- data/examples/action-cable/app/controllers/test_controller.rb +6 -0
- data/examples/action-cable/app/models/models.rb +2 -0
- data/examples/action-cable/app/models/public/application_record.rb +3 -0
- data/examples/action-cable/app/models/public/word.rb +2 -0
- data/examples/action-cable/app/policies/application_policy.rb +6 -0
- data/examples/action-cable/app/views/components.rb +17 -0
- data/examples/action-cable/app/views/components/app.rb +18 -0
- data/examples/action-cable/app/views/layouts/application.html.erb +14 -0
- data/examples/action-cable/app/views/layouts/mailer.html.erb +13 -0
- data/examples/action-cable/app/views/layouts/mailer.text.erb +1 -0
- data/examples/action-cable/bin/bundle +3 -0
- data/examples/action-cable/bin/rails +9 -0
- data/examples/action-cable/bin/rake +9 -0
- data/examples/action-cable/bin/setup +34 -0
- data/examples/action-cable/bin/spring +15 -0
- data/examples/action-cable/bin/update +29 -0
- data/examples/action-cable/config.ru +5 -0
- data/examples/action-cable/config/application.rb +30 -0
- data/examples/action-cable/config/boot.rb +3 -0
- data/examples/action-cable/config/cable.yml +9 -0
- data/examples/action-cable/config/database.yml +25 -0
- data/examples/action-cable/config/environment.rb +5 -0
- data/examples/action-cable/config/environments/development.rb +45 -0
- data/examples/action-cable/config/environments/production.rb +86 -0
- data/examples/action-cable/config/environments/test.rb +42 -0
- data/examples/action-cable/config/initializers/application_controller_renderer.rb +6 -0
- data/examples/action-cable/config/initializers/assets.rb +11 -0
- data/examples/action-cable/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/action-cable/config/initializers/cookies_serializer.rb +5 -0
- data/examples/action-cable/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/action-cable/config/initializers/inflections.rb +16 -0
- data/examples/action-cable/config/initializers/mime_types.rb +4 -0
- data/examples/action-cable/config/initializers/new_framework_defaults.rb +24 -0
- data/examples/action-cable/config/initializers/session_store.rb +3 -0
- data/examples/action-cable/config/initializers/synchromesh.rb +5 -0
- data/examples/action-cable/config/initializers/wrap_parameters.rb +14 -0
- data/examples/action-cable/config/locales/en.yml +23 -0
- data/examples/action-cable/config/puma.rb +47 -0
- data/examples/action-cable/config/routes.rb +5 -0
- data/examples/action-cable/config/secrets.yml +22 -0
- data/examples/action-cable/config/spring.rb +6 -0
- data/examples/action-cable/db/migrate/20160921223808_create_words.rb +9 -0
- data/examples/action-cable/db/schema.rb +21 -0
- data/examples/action-cable/log/.keep +0 -0
- data/examples/action-cable/public/404.html +67 -0
- data/examples/action-cable/public/422.html +67 -0
- data/examples/action-cable/public/500.html +66 -0
- data/examples/action-cable/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/action-cable/public/apple-touch-icon.png +0 -0
- data/examples/action-cable/public/favicon.ico +0 -0
- data/examples/action-cable/public/robots.txt +5 -0
- data/examples/action-cable/rails_cache_dir2/C91/480/synchromesh_active_connections +0 -0
- data/examples/action-cable/tmp/.keep +0 -0
- data/examples/action-cable/vendor/assets/javascripts/.keep +0 -0
- data/examples/action-cable/vendor/assets/stylesheets/.keep +0 -0
- data/examples/simple-poller/.gitignore +21 -0
- data/examples/simple-poller/Gemfile +64 -0
- data/examples/simple-poller/Gemfile.lock +272 -0
- data/examples/simple-poller/README.md +24 -0
- data/examples/simple-poller/Rakefile +6 -0
- data/examples/simple-poller/app/assets/config/manifest.js +3 -0
- data/examples/simple-poller/app/assets/images/.keep +0 -0
- data/examples/simple-poller/app/assets/javascripts/application.js +20 -0
- data/examples/simple-poller/app/assets/javascripts/channels/.keep +0 -0
- data/examples/simple-poller/app/assets/stylesheets/application.css +15 -0
- data/examples/simple-poller/app/channels/application_cable/channel.rb +4 -0
- data/examples/simple-poller/app/channels/application_cable/connection.rb +4 -0
- data/examples/simple-poller/app/controllers/application_controller.rb +3 -0
- data/examples/simple-poller/app/controllers/concerns/.keep +0 -0
- data/examples/simple-poller/app/controllers/test_controller.rb +6 -0
- data/examples/simple-poller/app/helpers/application_helper.rb +2 -0
- data/examples/simple-poller/app/jobs/application_job.rb +2 -0
- data/examples/simple-poller/app/mailers/application_mailer.rb +4 -0
- data/examples/simple-poller/app/models/concerns/.keep +0 -0
- data/examples/simple-poller/app/models/models.rb +2 -0
- data/examples/simple-poller/app/models/public/.keep +0 -0
- data/examples/simple-poller/app/models/public/application_record.rb +3 -0
- data/examples/simple-poller/app/models/public/word.rb +2 -0
- data/examples/simple-poller/app/policies/application_policy.rb +5 -0
- data/examples/simple-poller/app/views/components.rb +18 -0
- data/examples/simple-poller/app/views/components/.keep +0 -0
- data/examples/simple-poller/app/views/components/app.rb +40 -0
- data/examples/simple-poller/app/views/layouts/application.html.erb +14 -0
- data/examples/simple-poller/app/views/layouts/mailer.html.erb +13 -0
- data/examples/simple-poller/app/views/layouts/mailer.text.erb +1 -0
- data/examples/simple-poller/bin/bundle +3 -0
- data/examples/simple-poller/bin/rails +9 -0
- data/examples/simple-poller/bin/rake +9 -0
- data/examples/simple-poller/bin/setup +34 -0
- data/examples/simple-poller/bin/spring +16 -0
- data/examples/simple-poller/bin/update +29 -0
- data/examples/simple-poller/config.ru +5 -0
- data/examples/simple-poller/config/application.rb +20 -0
- data/examples/simple-poller/config/boot.rb +3 -0
- data/examples/simple-poller/config/cable.yml +9 -0
- data/examples/simple-poller/config/database.yml +25 -0
- data/examples/simple-poller/config/environment.rb +5 -0
- data/examples/simple-poller/config/environments/development.rb +44 -0
- data/examples/simple-poller/config/environments/production.rb +86 -0
- data/examples/simple-poller/config/environments/test.rb +42 -0
- data/examples/simple-poller/config/initializers/application_controller_renderer.rb +6 -0
- data/examples/simple-poller/config/initializers/assets.rb +11 -0
- data/examples/simple-poller/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/simple-poller/config/initializers/cookies_serializer.rb +5 -0
- data/examples/simple-poller/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/simple-poller/config/initializers/inflections.rb +16 -0
- data/examples/simple-poller/config/initializers/mime_types.rb +4 -0
- data/examples/simple-poller/config/initializers/new_framework_defaults.rb +24 -0
- data/examples/simple-poller/config/initializers/session_store.rb +3 -0
- data/examples/simple-poller/config/initializers/synchromesh.rb +15 -0
- data/examples/simple-poller/config/initializers/wrap_parameters.rb +14 -0
- data/examples/simple-poller/config/locales/en.yml +23 -0
- data/examples/simple-poller/config/puma.rb +47 -0
- data/examples/simple-poller/config/routes.rb +5 -0
- data/examples/simple-poller/config/secrets.yml +22 -0
- data/examples/simple-poller/config/spring.rb +6 -0
- data/examples/simple-poller/db/migrate/20161013220135_create_words.rb +9 -0
- data/examples/simple-poller/db/schema.rb +21 -0
- data/examples/simple-poller/db/seeds.rb +7 -0
- data/examples/simple-poller/lib/assets/.keep +0 -0
- data/examples/simple-poller/lib/tasks/.keep +0 -0
- data/examples/simple-poller/log/.keep +0 -0
- data/examples/simple-poller/public/404.html +67 -0
- data/examples/simple-poller/public/422.html +67 -0
- data/examples/simple-poller/public/500.html +66 -0
- data/examples/simple-poller/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/simple-poller/public/apple-touch-icon.png +0 -0
- data/examples/simple-poller/public/favicon.ico +0 -0
- data/examples/simple-poller/public/robots.txt +5 -0
- data/examples/simple-poller/test/controllers/.keep +0 -0
- data/examples/simple-poller/test/fixtures/.keep +0 -0
- data/examples/simple-poller/test/fixtures/files/.keep +0 -0
- data/examples/simple-poller/test/fixtures/words.yml +7 -0
- data/examples/simple-poller/test/helpers/.keep +0 -0
- data/examples/simple-poller/test/integration/.keep +0 -0
- data/examples/simple-poller/test/mailers/.keep +0 -0
- data/examples/simple-poller/test/models/.keep +0 -0
- data/examples/simple-poller/test/models/word_test.rb +7 -0
- data/examples/simple-poller/test/test_helper.rb +10 -0
- data/examples/simple-poller/tmp/.keep +0 -0
- data/examples/simple-poller/vendor/assets/javascripts/.keep +0 -0
- data/examples/simple-poller/vendor/assets/stylesheets/.keep +0 -0
- data/examples/words/.gitignore +21 -0
- data/examples/words/Gemfile +58 -0
- data/examples/words/Gemfile.lock +247 -0
- data/examples/words/README.md +24 -0
- data/examples/words/Rakefile +6 -0
- data/examples/words/app/assets/config/manifest.js +3 -0
- data/examples/words/app/assets/javascripts/application.js +18 -0
- data/examples/words/app/assets/stylesheets/application.css +15 -0
- data/examples/words/app/controllers/application_controller.rb +3 -0
- data/examples/words/app/controllers/test_controller.rb +6 -0
- data/examples/words/app/models/models.rb +2 -0
- data/examples/words/app/models/public/application_record.rb +3 -0
- data/examples/words/app/models/public/word.rb +10 -0
- data/examples/words/app/policies/application_policy.rb +6 -0
- data/examples/words/app/views/components.rb +16 -0
- data/examples/words/app/views/components/app.rb +31 -0
- data/examples/words/app/views/layouts/application.html.erb +14 -0
- data/examples/words/app/views/layouts/mailer.html.erb +13 -0
- data/examples/words/app/views/layouts/mailer.text.erb +1 -0
- data/examples/words/bin/bundle +3 -0
- data/examples/words/bin/rails +9 -0
- data/examples/words/bin/rake +9 -0
- data/examples/words/bin/setup +34 -0
- data/examples/words/bin/spring +15 -0
- data/examples/words/bin/update +29 -0
- data/examples/words/config.ru +5 -0
- data/examples/words/config/application.rb +30 -0
- data/examples/words/config/boot.rb +3 -0
- data/examples/words/config/cable.yml +9 -0
- data/examples/words/config/database.yml +25 -0
- data/examples/words/config/environment.rb +5 -0
- data/examples/words/config/environments/development.rb +45 -0
- data/examples/words/config/environments/production.rb +86 -0
- data/examples/words/config/environments/test.rb +42 -0
- data/examples/words/config/initializers/application_controller_renderer.rb +6 -0
- data/examples/words/config/initializers/assets.rb +11 -0
- data/examples/words/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/words/config/initializers/cookies_serializer.rb +5 -0
- data/examples/words/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/words/config/initializers/inflections.rb +16 -0
- data/examples/words/config/initializers/mime_types.rb +4 -0
- data/examples/words/config/initializers/new_framework_defaults.rb +24 -0
- data/examples/words/config/initializers/session_store.rb +3 -0
- data/examples/words/config/initializers/synchromesh.rb +5 -0
- data/examples/words/config/initializers/wrap_parameters.rb +14 -0
- data/examples/words/config/locales/en.yml +23 -0
- data/examples/words/config/puma.rb +47 -0
- data/examples/words/config/routes.rb +5 -0
- data/examples/words/config/secrets.yml +22 -0
- data/examples/words/config/spring.rb +6 -0
- data/examples/words/db/migrate/20160921223808_create_words.rb +9 -0
- data/examples/words/db/schema.rb +28 -0
- data/examples/words/log/.keep +0 -0
- data/examples/words/public/404.html +67 -0
- data/examples/words/public/422.html +67 -0
- data/examples/words/public/500.html +66 -0
- data/examples/words/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/words/public/apple-touch-icon.png +0 -0
- data/examples/words/public/favicon.ico +0 -0
- data/examples/words/public/robots.txt +5 -0
- data/examples/words/tmp/.keep +0 -0
- data/examples/words/vendor/assets/javascripts/.keep +0 -0
- data/examples/words/vendor/assets/stylesheets/.keep +0 -0
- data/hyper-mesh.gemspec +82 -0
- data/lib/active_record_base.rb +152 -0
- data/lib/enumerable/pluck.rb +6 -0
- data/lib/hyper-mesh.rb +62 -0
- data/lib/hypermesh/version.rb +3 -0
- data/lib/opal/equality_patches.rb +15 -0
- data/lib/opal/parse_patch.rb +14 -0
- data/lib/opal/set_patches.rb +8 -0
- data/lib/reactive_record/active_record/aggregations.rb +69 -0
- data/lib/reactive_record/active_record/associations.rb +111 -0
- data/lib/reactive_record/active_record/base.rb +9 -0
- data/lib/reactive_record/active_record/class_methods.rb +177 -0
- data/lib/reactive_record/active_record/error.rb +26 -0
- data/lib/reactive_record/active_record/instance_methods.rb +129 -0
- data/lib/reactive_record/active_record/public_columns_hash.rb +19 -0
- data/lib/reactive_record/active_record/reactive_record/base.rb +520 -0
- data/lib/reactive_record/active_record/reactive_record/collection.rb +517 -0
- data/lib/reactive_record/active_record/reactive_record/column_types.rb +67 -0
- data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +218 -0
- data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +532 -0
- data/lib/reactive_record/active_record/reactive_record/reactive_set_relationship_helpers.rb +189 -0
- data/lib/reactive_record/active_record/reactive_record/scoped_collection.rb +62 -0
- data/lib/reactive_record/active_record/reactive_record/unscoped_collection.rb +16 -0
- data/lib/reactive_record/active_record/reactive_record/while_loading.rb +299 -0
- data/lib/reactive_record/engine.rb +13 -0
- data/lib/reactive_record/interval.rb +190 -0
- data/lib/reactive_record/permissions.rb +102 -0
- data/lib/reactive_record/pry.rb +13 -0
- data/lib/reactive_record/reactive_scope.rb +18 -0
- data/lib/reactive_record/scope_description.rb +108 -0
- data/lib/reactive_record/serializers.rb +7 -0
- data/lib/reactive_record/server_data_cache.rb +347 -0
- data/lib/reactive_record/version.rb +3 -0
- data/lib/sources/hyper-mesh/pusher.js +98 -0
- data/lib/synchromesh/action_cable.rb +39 -0
- data/lib/synchromesh/client_drivers.rb +357 -0
- data/lib/synchromesh/configuration.rb +40 -0
- data/lib/synchromesh/connection.rb +144 -0
- data/lib/synchromesh/policy.rb +504 -0
- data/lib/synchromesh/reactive_record/permission_patches.rb +43 -0
- data/lib/synchromesh/synchromesh.rb +155 -0
- data/lib/synchromesh/synchromesh_controller.rb +154 -0
- data/logo.jpg +0 -0
- data/path_release_steps.md +0 -0
- data/reactive_record_test_app/Gemfile +15 -0
- data/reactive_record_test_app/Gemfile.lock +209 -0
- data/reactive_record_test_app/README.rdoc +261 -0
- data/reactive_record_test_app/Rakefile +7 -0
- data/reactive_record_test_app/app/assets/javascripts/application.rb +5 -0
- data/reactive_record_test_app/app/assets/javascripts/components/another_component.rb +24 -0
- data/reactive_record_test_app/app/assets/javascripts/components/empty_component.rb +6 -0
- data/reactive_record_test_app/app/assets/javascripts/components/todo_item_component.js.rb +16 -0
- data/reactive_record_test_app/app/assets/javascripts/components/todos_component.js.rb +42 -0
- data/reactive_record_test_app/app/assets/javascripts/components/todos_main_component.rb +49 -0
- data/reactive_record_test_app/app/assets/javascripts/react_js_test_only.js +21618 -0
- data/reactive_record_test_app/app/assets/javascripts/reactive_record_config.js +2 -0
- data/reactive_record_test_app/app/assets/javascripts/spec/reactive_record_xspec.js.rb +42 -0
- data/reactive_record_test_app/app/assets/stylesheets/application.css +13 -0
- data/reactive_record_test_app/app/controllers/application_controller.rb +8 -0
- data/reactive_record_test_app/app/controllers/home_controller.rb +7 -0
- data/reactive_record_test_app/app/controllers/test_controller.rb +7 -0
- data/reactive_record_test_app/app/helpers/application_helper.rb +2 -0
- data/reactive_record_test_app/app/mailers/.gitkeep +0 -0
- data/reactive_record_test_app/app/models/.gitkeep +0 -0
- data/reactive_record_test_app/app/policies/application_policy.rb +5 -0
- data/reactive_record_test_app/app/views/components.rb +4 -0
- data/reactive_record_test_app/app/views/components/test.rb +18 -0
- data/reactive_record_test_app/app/views/home/index.html.erb +1 -0
- data/reactive_record_test_app/app/views/layouts/application.html.erb +17 -0
- data/reactive_record_test_app/app/views/models.rb +1 -0
- data/reactive_record_test_app/app/views/models/address.rb +13 -0
- data/reactive_record_test_app/app/views/models/comment.rb +19 -0
- data/reactive_record_test_app/app/views/models/todo_item.rb +36 -0
- data/reactive_record_test_app/app/views/models/user.rb +78 -0
- data/reactive_record_test_app/config.ru +33 -0
- data/reactive_record_test_app/config/application.rb +73 -0
- data/reactive_record_test_app/config/boot.rb +10 -0
- data/reactive_record_test_app/config/database.yml +25 -0
- data/reactive_record_test_app/config/environment.rb +5 -0
- data/reactive_record_test_app/config/environments/development.rb +43 -0
- data/reactive_record_test_app/config/environments/production.rb +70 -0
- data/reactive_record_test_app/config/environments/test.rb +41 -0
- data/reactive_record_test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/reactive_record_test_app/config/initializers/inflections.rb +15 -0
- data/reactive_record_test_app/config/initializers/mime_types.rb +5 -0
- data/reactive_record_test_app/config/initializers/secret_token.rb +7 -0
- data/reactive_record_test_app/config/initializers/session_store.rb +8 -0
- data/reactive_record_test_app/config/initializers/wrap_parameters.rb +14 -0
- data/reactive_record_test_app/config/locales/en.yml +5 -0
- data/reactive_record_test_app/config/routes.rb +7 -0
- data/reactive_record_test_app/db/migrate/20150617002932_create_todo_items.rb +11 -0
- data/reactive_record_test_app/db/migrate/20150617134028_create_users.rb +14 -0
- data/reactive_record_test_app/db/migrate/20150729195556_add_address_to_user.rb +20 -0
- data/reactive_record_test_app/db/migrate/20150826142045_create_comments.rb +10 -0
- data/reactive_record_test_app/db/migrate/20150828172008_add_single_comment_to_todo_item.rb +5 -0
- data/reactive_record_test_app/db/migrate/20150908184118_add_address_id_to_user.rb +5 -0
- data/reactive_record_test_app/db/migrate/20150917220236_add_second_address_to_user.rb +10 -0
- data/reactive_record_test_app/db/migrate/20151009000111_add_test_data_attributes_to_user.rb +6 -0
- data/reactive_record_test_app/db/migrate/20160129182544_add_test_enum_to_user.rb +5 -0
- data/reactive_record_test_app/db/schema.rb +63 -0
- data/reactive_record_test_app/db/seeds.rb +60 -0
- data/reactive_record_test_app/public/404.html +26 -0
- data/reactive_record_test_app/public/422.html +26 -0
- data/reactive_record_test_app/public/500.html +25 -0
- data/reactive_record_test_app/public/favicon.ico +0 -0
- data/reactive_record_test_app/script/rails +6 -0
- data/reactive_record_test_app/spec-opal/active-record/aggregations_spec.rb +41 -0
- data/reactive_record_test_app/spec-opal/active-record/associations_spec.rb +75 -0
- data/reactive_record_test_app/spec-opal/active-record/base_spec.rb +126 -0
- data/reactive_record_test_app/spec-opal/active-record/dummy_value_spec.rb +27 -0
- data/reactive_record_test_app/spec-opal/active-record/edge_cases_spec.rb +116 -0
- data/reactive_record_test_app/spec-opal/active-record/enum_spec.rb +43 -0
- data/reactive_record_test_app/spec-opal/active-record/instance_methods_spec.rb +53 -0
- data/reactive_record_test_app/spec-opal/active-record/non_ar_aggregations_spec.rb +74 -0
- data/reactive_record_test_app/spec-opal/active-record/permissions_spec.rb +170 -0
- data/reactive_record_test_app/spec-opal/active-record/prerendering_spec.rb +49 -0
- data/reactive_record_test_app/spec-opal/active-record/reactive_record_load_spec.rb +23 -0
- data/reactive_record_test_app/spec-opal/active-record/rendering_spec.rb +221 -0
- data/reactive_record_test_app/spec-opal/active-record/save_spec.rb +125 -0
- data/reactive_record_test_app/spec-opal/active-record/scope_spec.rb +85 -0
- data/reactive_record_test_app/spec-opal/active-record/update_aggregations_spec.rb +76 -0
- data/reactive_record_test_app/spec-opal/active-record/update_attributes_spec.rb +186 -0
- data/reactive_record_test_app/spec-opal/active-record/virtual_methods_spec.rb +71 -0
- data/reactive_record_test_app/spec-opal/index.html.erb +11 -0
- data/reactive_record_test_app/spec-opal/spec_helper.js.rb +268 -0
- data/reactive_record_test_app/spec-opal/vendor/es5-shim.min.js +6 -0
- data/reactive_record_test_app/spec_dont_run/README.md +26 -0
- data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzmany_to_many_spec_moved_to_main_suite.rb +30 -0
- data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzrevert_record_spec_moved.rb +78 -0
- data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzupdate_associations_spec_moved.rb +142 -0
- data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzupdate_scopes_movedspec.rb +48 -0
- data/remote.md +115 -0
- data/spec/bin/firebug-2.0.13-fx.xpi +0 -0
- data/spec/component_helpers_xspec.rb +49 -0
- data/spec/factories/child_model.rb +5 -0
- data/spec/factories/comment.rb +5 -0
- data/spec/factories/test_models.rb +5 -0
- data/spec/factories/todo.rb +5 -0
- data/spec/factories/user.rb +5 -0
- data/spec/reactive_record/edge_cases_spec.rb +31 -0
- data/spec/reactive_record/factory.rb +62 -0
- data/spec/reactive_record/many_to_many_spec.rb +50 -0
- data/spec/reactive_record/play.rb +64 -0
- data/spec/reactive_record/pry_rescue_xspec.rb +48 -0
- data/spec/reactive_record/revert_spec.rb +112 -0
- data/spec/reactive_record/update_associations_spec.rb +189 -0
- data/spec/reactive_record/update_scopes_spec.rb +53 -0
- data/spec/spec_helper.rb +366 -0
- data/spec/support/component_helpers.rb +351 -0
- data/spec/synchromesh/column_types/column_type_spec.rb +302 -0
- data/spec/synchromesh/connection_spec.rb +144 -0
- data/spec/synchromesh/crud_access_regulation/broadcast_controls_access_spec.rb +105 -0
- data/spec/synchromesh/crud_access_regulation/model_policies_spec.rb +131 -0
- data/spec/synchromesh/examples/dictionary.rb +239 -0
- data/spec/synchromesh/examples/dictionary_with_client_scopes.rb +196 -0
- data/spec/synchromesh/examples/random_examples.rb +100 -0
- data/spec/synchromesh/examples/scoped_todos_spec.rb +167 -0
- data/spec/synchromesh/integration/authorization_spec.rb +111 -0
- data/spec/synchromesh/integration/default_scope_spec.rb +121 -0
- data/spec/synchromesh/integration/has_many_through_spec.rb +173 -0
- data/spec/synchromesh/integration/relationships_spec.rb +263 -0
- data/spec/synchromesh/integration/scope_spec.rb +553 -0
- data/spec/synchromesh/integration/synchromesh_spec.rb +80 -0
- data/spec/synchromesh/integration/test_components.rb +18 -0
- data/spec/synchromesh/integration/transports_spec.rb +308 -0
- data/spec/synchromesh/policies/auto_connect_spec.rb +60 -0
- data/spec/synchromesh/policies/auto_loader_spec.rb +34 -0
- data/spec/synchromesh/policies/policy_methods_spec.rb +85 -0
- data/spec/synchromesh/policies/regulate_all_broadcasts_spec.rb +315 -0
- data/spec/synchromesh/policies/regulate_broadcast_spec.rb +370 -0
- data/spec/synchromesh/policies/regulate_class_connection_spec.rb +50 -0
- data/spec/synchromesh/policies/regulate_instance_connection_spec.rb +66 -0
- data/spec/test_app/Gemfile +61 -0
- data/spec/test_app/Gemfile.lock +253 -0
- data/spec/test_app/Rakefile +6 -0
- data/spec/test_app/app/assets/javascripts/application.js +6 -0
- data/spec/test_app/app/assets/stylesheets/application.css +15 -0
- data/spec/test_app/app/controllers/application_controller.rb +13 -0
- data/spec/test_app/app/controllers/test_controller.rb +5 -0
- data/spec/test_app/app/models/_react_public_models.rb +2 -0
- data/spec/test_app/app/models/public/address.rb +13 -0
- data/spec/test_app/app/models/public/child_model.rb +3 -0
- data/spec/test_app/app/models/public/comment.rb +25 -0
- data/spec/test_app/app/models/public/test_model.rb +5 -0
- data/spec/test_app/app/models/public/todo.rb +6 -0
- data/spec/test_app/app/models/public/todo_item.rb +36 -0
- data/spec/test_app/app/models/public/user.rb +88 -0
- data/spec/test_app/app/policies/auto_loader_test_classa_policy.rb +3 -0
- data/spec/test_app/app/policies/auto_loader_test_classb_policy.rb +3 -0
- data/spec/test_app/app/policies/auto_loader_test_classc_policy.rb +3 -0
- data/spec/test_app/app/policies/auto_loader_test_classd_policy.rb +3 -0
- data/spec/test_app/app/views/components.rb +14 -0
- data/spec/test_app/app/views/components/show.rb +5 -0
- data/spec/test_app/app/views/layouts/application.html.erb +14 -0
- data/spec/test_app/bin/bundle +3 -0
- data/spec/test_app/bin/rails +4 -0
- data/spec/test_app/bin/rake +4 -0
- data/spec/test_app/bin/setup +29 -0
- data/spec/test_app/config.ru +4 -0
- data/spec/test_app/config/application.rb +42 -0
- data/spec/test_app/config/boot.rb +6 -0
- data/spec/test_app/config/cable.yml +10 -0
- data/spec/test_app/config/database.yml +47 -0
- data/spec/test_app/config/environment.rb +5 -0
- data/spec/test_app/config/environments/development.rb +41 -0
- data/spec/test_app/config/environments/production.rb +79 -0
- data/spec/test_app/config/environments/test.rb +42 -0
- data/spec/test_app/config/initializers/assets.rb +11 -0
- data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
- data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/test_app/config/initializers/inflections.rb +16 -0
- data/spec/test_app/config/initializers/mime_types.rb +4 -0
- data/spec/test_app/config/initializers/session_store.rb +3 -0
- data/spec/test_app/config/initializers/synchromesh.rb +11 -0
- data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/test_app/config/locales/en.yml +23 -0
- data/spec/test_app/config/routes.rb +61 -0
- data/spec/test_app/config/secrets.yml +22 -0
- data/spec/test_app/db/development.sqlite3 +0 -0
- data/spec/test_app/db/migrate/20160731182106_create_test_models.rb +75 -0
- data/spec/test_app/db/schema.rb +88 -0
- data/spec/test_app/db/seeds.rb +7 -0
- data/spec/test_app/lib/assets/.keep +0 -0
- data/spec/test_app/log/.keep +0 -0
- data/spec/test_app/public/404.html +67 -0
- data/spec/test_app/public/422.html +67 -0
- data/spec/test_app/public/500.html +66 -0
- data/spec/test_app/public/favicon.ico +0 -0
- data/spec/vendor/es5-shim.min.js +6 -0
- data/terminal.md +66 -0
- metadata +1175 -0
@@ -0,0 +1,189 @@
|
|
1
|
+
module ReactiveRecord
|
2
|
+
# methods to update aggregrations and relations, called from reactive_set!
|
3
|
+
class Base
|
4
|
+
def update_aggregate(attribute, value)
|
5
|
+
# if attribute is an aggregate then
|
6
|
+
# match and update all fields in the aggregate from value and return true
|
7
|
+
# otherwise return false
|
8
|
+
aggregation = @model.reflect_on_aggregation(attribute)
|
9
|
+
return false unless aggregation && (aggregation.klass < ActiveRecord::Base)
|
10
|
+
if value
|
11
|
+
value_attributes = value.backing_record.attributes
|
12
|
+
update_mapped_attributes(aggregation) { |attr| value_attributes[attr] }
|
13
|
+
else
|
14
|
+
update_mapped_attributes(aggregation) { nil }
|
15
|
+
end
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def update_mapped_attributes(aggregation)
|
20
|
+
# insure the aggregate attr is initialized, clear the virt flag, the caller
|
21
|
+
# will yield each of the matching attribute values
|
22
|
+
attr = aggregation.attribute
|
23
|
+
attributes[attr] ||= aggregation.klass.new if new?
|
24
|
+
aggregate_record = attributes[attr]
|
25
|
+
raise 'uninitialized aggregate attribute - should never happen' unless aggregate_record
|
26
|
+
aggregate_backing_record = aggregate_record.backing_record
|
27
|
+
aggregate_backing_record.virgin = false
|
28
|
+
aggregation.mapped_attributes.each do |mapped_attribute|
|
29
|
+
aggregate_backing_record.update_attribute(mapped_attribute, yield(mapped_attribute))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_relationships(attr, value)
|
34
|
+
# update the inverse relationship, and any through relationships
|
35
|
+
# return either the value, or in the case of updating a collection
|
36
|
+
# return the new collection after value is overwritten into it.
|
37
|
+
association = @model.reflect_on_association(attr)
|
38
|
+
return value unless association
|
39
|
+
if association.collection?
|
40
|
+
overwrite_has_many_collection(association, value)
|
41
|
+
else
|
42
|
+
update_belongs_to_association(association, value)
|
43
|
+
value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def overwrite_has_many_collection(association, value)
|
48
|
+
# create a new collection to hold value, shove it in, and return the new collection
|
49
|
+
# the replace method will take care of updating the inverse belongs_to links as
|
50
|
+
# the collection is overwritten
|
51
|
+
Collection.new(association.klass, @ar_instance, association).tap do |collection|
|
52
|
+
collection.replace(value || [])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_belongs_to_association(association, value)
|
57
|
+
# either update update the inverse has_many collection or individual belongs_to
|
58
|
+
# inverse values
|
59
|
+
if association.inverse.collection?
|
60
|
+
update_has_many_through_associations(association, value)
|
61
|
+
update_inverse_collections(association, value)
|
62
|
+
else
|
63
|
+
update_inverse_attribute(association, value)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_inverse_attribute(association, value)
|
68
|
+
# when updating the inverse attribute of a belongs_to that is itself a belongs_to
|
69
|
+
# (i.e. 1-1 relationship) we clear the existing inverse value and then
|
70
|
+
# write the current record to the new value
|
71
|
+
current_value = attributes[association.attribute]
|
72
|
+
inverse_attr = association.inverse.attribute
|
73
|
+
current_value.attributes[inverse_attr] = nil unless current_value.nil?
|
74
|
+
return if value.nil?
|
75
|
+
value.attributes[inverse_attr] = @ar_instance
|
76
|
+
return if data_loading?
|
77
|
+
React::State.set_state(value.backing_record, inverse_attr, @ar_instance)
|
78
|
+
end
|
79
|
+
|
80
|
+
def update_inverse_collections(association, value)
|
81
|
+
# when updating an inverse attribute of a belongs_to that is a has_many (i.e. a collection)
|
82
|
+
# we need to first remove the current associated value (if non-nil), then add the new
|
83
|
+
# value to the collection. If the inverse collection is not yet initialized we do it here.
|
84
|
+
current_value = attributes[association.attribute]
|
85
|
+
inverse_attr = association.inverse.attribute
|
86
|
+
if value.nil?
|
87
|
+
current_value.attributes[inverse_attr].delete(@ar_instance) unless current_value.nil?
|
88
|
+
else
|
89
|
+
value.backing_record.push_onto_collection(association.inverse, @ar_instance)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def push_onto_collection(association, ar_instance)
|
94
|
+
attributes[association.attribute] ||= Collection.new(@model, @ar_instance, association)
|
95
|
+
attributes[association.attribute] << ar_instance
|
96
|
+
end
|
97
|
+
|
98
|
+
def update_has_many_through_associations(association, value)
|
99
|
+
association.through_associations.each { |ta| update_through_association(ta, value) }
|
100
|
+
association.source_associations.each { |sa| update_source_association(sa, value) }
|
101
|
+
end
|
102
|
+
|
103
|
+
def update_through_association(ta, new_belongs_to_value)
|
104
|
+
# appointment.doctor = doctor_new_value (i.e. through association is changing)
|
105
|
+
# means appointment.doctor_new_value.patients << appointment.patient
|
106
|
+
# and we have to appointment.doctor_current_value.patients.delete(appointment.patient)
|
107
|
+
source_value = attributes[ta.source]
|
108
|
+
current_belongs_to_value = attributes[ta.inverse.attribute]
|
109
|
+
return unless source_value
|
110
|
+
unless current_belongs_to_value.nil? || current_belongs_to_value.attributes[ta.attribute].nil?
|
111
|
+
current_belongs_to_value.attributes[ta.attribute].delete(source_value)
|
112
|
+
end
|
113
|
+
return unless new_belongs_to_value
|
114
|
+
new_belongs_to_value.attributes[ta.attribute] ||= Collection.new(ta.klass, new_belongs_to_value, ta)
|
115
|
+
new_belongs_to_value.attributes[ta.attribute] << source_value
|
116
|
+
end
|
117
|
+
|
118
|
+
def update_source_association(sa, new_source_value)
|
119
|
+
# appointment.patient = patient_value (i.e. source is changing)
|
120
|
+
# means appointment.doctor.patients.delete(appointment.patient)
|
121
|
+
# means appointment.doctor.patients << patient_value
|
122
|
+
belongs_to_value = attributes[sa.inverse.attribute]
|
123
|
+
current_source_value = attributes[sa.source]
|
124
|
+
return unless belongs_to_value
|
125
|
+
unless belongs_to_value.attributes[sa.attribute].nil? || current_source_value.nil?
|
126
|
+
belongs_to_value.attributes[sa.attribute].delete(current_source_value)
|
127
|
+
end
|
128
|
+
return unless new_source_value
|
129
|
+
belongs_to_value.attributes[sa.attribute] ||= Collection.new(sa.klass, belongs_to_value, sa)
|
130
|
+
belongs_to_value.attributes[sa.attribute] << new_source_value
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# def reactive_set!(attribute, value)
|
136
|
+
# @virgin = false unless data_loading?
|
137
|
+
# unless @destroyed or (!(attributes[attribute].is_a? DummyValue) and attributes.has_key?(attribute) and attributes[attribute] == value)
|
138
|
+
# if association = @model.reflect_on_association(attribute)
|
139
|
+
# if association.collection?
|
140
|
+
# collection = Collection.new(association.klass, @ar_instance, association)
|
141
|
+
# collection.replace(value || [])
|
142
|
+
# value = collection
|
143
|
+
# else
|
144
|
+
# inverse_of = association.inverse_of
|
145
|
+
# inverse_association = association.klass.reflect_on_association(inverse_of)
|
146
|
+
# if inverse_association.collection?
|
147
|
+
# if value.nil?
|
148
|
+
# attributes[attribute].attributes[inverse_of].delete(@ar_instance) unless attributes[attribute].nil?
|
149
|
+
# elsif value.attributes[inverse_of]
|
150
|
+
# value.attributes[inverse_of] << @ar_instance
|
151
|
+
# else
|
152
|
+
# value.attributes[inverse_of] = Collection.new(@model, value, inverse_association)
|
153
|
+
# # value.attributes[inverse_of].replace [@ar_instance]
|
154
|
+
# # why was the above not just the below???? fixed 10/28/2016
|
155
|
+
# value.attributes[inverse_of] << @ar_instance
|
156
|
+
# end
|
157
|
+
# elsif !value.nil?
|
158
|
+
# attributes[attribute].attributes[inverse_of] = nil unless attributes[attribute].nil?
|
159
|
+
# value.attributes[inverse_of] = @ar_instance
|
160
|
+
# React::State.set_state(value.backing_record, inverse_of, @ar_instance) unless data_loading?
|
161
|
+
# elsif attributes[attribute]
|
162
|
+
# attributes[attribute].attributes[inverse_of] = nil
|
163
|
+
# end
|
164
|
+
# end
|
165
|
+
# elsif aggregation = @model.reflect_on_aggregation(attribute) and (aggregation.klass < ActiveRecord::Base)
|
166
|
+
#
|
167
|
+
# if new?
|
168
|
+
# attributes[attribute] ||= aggregation.klass.new
|
169
|
+
# elsif !attributes[attribute]
|
170
|
+
# raise "uninitialized aggregate attribute - should never happen"
|
171
|
+
# end
|
172
|
+
#
|
173
|
+
# aggregate_record = attributes[attribute].backing_record
|
174
|
+
# aggregate_record.virgin = false
|
175
|
+
#
|
176
|
+
# if value
|
177
|
+
# value_attributes = value.backing_record.attributes
|
178
|
+
# aggregation.mapped_attributes.each { |mapped_attribute| aggregate_record.update_attribute(mapped_attribute, value_attributes[mapped_attribute])}
|
179
|
+
# else
|
180
|
+
# aggregation.mapped_attributes.each { |mapped_attribute| aggregate_record.update_attribute(mapped_attribute, nil) }
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# return attributes[attribute]
|
184
|
+
#
|
185
|
+
# end
|
186
|
+
# update_attribute(attribute, value)
|
187
|
+
# end
|
188
|
+
# value
|
189
|
+
# end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module ReactiveRecord
|
2
|
+
# The base collection class works with relationships
|
3
|
+
# method overrides for scoped collections
|
4
|
+
module ScopedCollection
|
5
|
+
[:filter?, :collector?, :joins_with?, :related_records_for].each do |method|
|
6
|
+
define_method(method) { |*args| @scope_description.send method, *args }
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_pre_sync_related_records(related_records, _record = nil)
|
10
|
+
@pre_sync_related_records = nil
|
11
|
+
ReactiveRecord::Base.catch_db_requests do
|
12
|
+
@pre_sync_related_records = filter_records(related_records)
|
13
|
+
live_scopes.each do |scope|
|
14
|
+
scope.set_pre_sync_related_records(@pre_sync_related_records)
|
15
|
+
end
|
16
|
+
end if filter?
|
17
|
+
end
|
18
|
+
|
19
|
+
def sync_scopes(related_records, record, filtering = true)
|
20
|
+
filtering =
|
21
|
+
@pre_sync_related_records && filtering &&
|
22
|
+
ReactiveRecord::Base.catch_db_requests do
|
23
|
+
related_records = update_collection(related_records)
|
24
|
+
end
|
25
|
+
reload_from_db if !filtering && joins_with?(record)
|
26
|
+
live_scopes.each { |scope| scope.sync_scopes(related_records, record, filtering) }
|
27
|
+
ensure
|
28
|
+
@pre_sync_related_records = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_collection(related_records)
|
32
|
+
if collector?
|
33
|
+
update_collector_scope(related_records)
|
34
|
+
else
|
35
|
+
related_records = filter_records(related_records)
|
36
|
+
update_filter_scope(@pre_sync_related_records, related_records)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_collector_scope(related_records)
|
41
|
+
current = Set.new([*@collection])
|
42
|
+
(related_records - @pre_sync_related_records).each { |r| current << r }
|
43
|
+
(@pre_sync_related_records - related_records).each { |r| current.delete(r) }
|
44
|
+
replace(filter_records(current))
|
45
|
+
Set.new([*@collection])
|
46
|
+
end
|
47
|
+
|
48
|
+
def update_filter_scope(before, after)
|
49
|
+
if (collection || !@count.nil?) && before != after
|
50
|
+
if collection
|
51
|
+
(after - before).each { |r| push r }
|
52
|
+
(before - after).each { |r| delete r }
|
53
|
+
else
|
54
|
+
@count += (after - before).count
|
55
|
+
@count -= (before - after).count
|
56
|
+
notify_of_change self # TODO remove self .... and retest
|
57
|
+
end
|
58
|
+
end
|
59
|
+
after
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ReactiveRecord
|
2
|
+
# The base collection class works with relationships
|
3
|
+
# method overrides for the unscoped collection
|
4
|
+
module UnscopedCollection
|
5
|
+
def set_pre_sync_related_records(related_records, _record = nil)
|
6
|
+
@pre_sync_related_records = related_records
|
7
|
+
live_scopes.each { |scope| scope.set_pre_sync_related_records(@pre_sync_related_records) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def sync_scopes(related_records, record, filtering = true)
|
11
|
+
live_scopes.each { |scope| scope.sync_scopes(related_records, record, filtering) }
|
12
|
+
ensure
|
13
|
+
@pre_sync_related_records = nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,299 @@
|
|
1
|
+
module ReactiveRecord
|
2
|
+
|
3
|
+
# will repeatedly execute the block until it is loaded
|
4
|
+
# immediately returns a promise that will resolve once the block is loaded
|
5
|
+
|
6
|
+
def self.load(&block)
|
7
|
+
promise = Promise.new
|
8
|
+
@load_stack ||= []
|
9
|
+
@load_stack << @loads_pending
|
10
|
+
@loads_pending = nil
|
11
|
+
result = block.call
|
12
|
+
if @loads_pending
|
13
|
+
@blocks_to_load ||= []
|
14
|
+
@blocks_to_load << [Base.last_fetch_at, promise, block]
|
15
|
+
else
|
16
|
+
promise.resolve result
|
17
|
+
end
|
18
|
+
@loads_pending = @load_stack.pop
|
19
|
+
promise
|
20
|
+
rescue Exception => e
|
21
|
+
debugger
|
22
|
+
React::IsomorphicHelpers.log "ReactiveRecord.load exception raised during initial load: #{e}", :error
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.loads_pending!
|
26
|
+
@loads_pending = true
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.check_loads_pending
|
30
|
+
if @loads_pending
|
31
|
+
if Base.pending_fetches.count > 0
|
32
|
+
true
|
33
|
+
else # this happens when for example loading foo.x results in somebody looking at foo.y while foo.y is still being loaded
|
34
|
+
ReactiveRecord::WhileLoading.loaded_at Base.last_fetch_at
|
35
|
+
ReactiveRecord::WhileLoading.quiet!
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.run_blocks_to_load(fetch_id, failure = nil)
|
42
|
+
if @blocks_to_load
|
43
|
+
blocks_to_load_now = @blocks_to_load.select { |data| data.first == fetch_id }
|
44
|
+
@blocks_to_load = @blocks_to_load.reject { |data| data.first == fetch_id }
|
45
|
+
@load_stack ||= []
|
46
|
+
blocks_to_load_now.each do |data|
|
47
|
+
id, promise, block = data
|
48
|
+
@load_stack << @loads_pending
|
49
|
+
@loads_pending = nil
|
50
|
+
result = block.call(failure)
|
51
|
+
if check_loads_pending and !failure
|
52
|
+
@blocks_to_load << [Base.last_fetch_at, promise, block]
|
53
|
+
else
|
54
|
+
promise.resolve result
|
55
|
+
end
|
56
|
+
@loads_pending = @load_stack.pop
|
57
|
+
end
|
58
|
+
end
|
59
|
+
rescue Exception => e
|
60
|
+
React::IsomorphicHelpers.log "ReactiveRecord.load exception raised during retry: #{e}", :error
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# Adds while_loading feature to React
|
65
|
+
# to use attach a .while_loading handler to any element for example
|
66
|
+
# div { "displayed if everything is loaded" }.while_loading { "displayed while I'm loading" }
|
67
|
+
# the contents of the div will be switched (using jQuery.show/hide) depending on the state of contents of the first block
|
68
|
+
|
69
|
+
# To notify React that something is loading use React::WhileLoading.loading!
|
70
|
+
# once everything is loaded then do React::WhileLoading.loaded_at message (typically a time stamp just for debug purposes)
|
71
|
+
|
72
|
+
class WhileLoading
|
73
|
+
|
74
|
+
include React::IsomorphicHelpers
|
75
|
+
|
76
|
+
before_first_mount do
|
77
|
+
@css_to_preload = ""
|
78
|
+
@while_loading_counter = 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_next_while_loading_counter
|
82
|
+
@while_loading_counter += 1
|
83
|
+
end
|
84
|
+
|
85
|
+
def preload_css(css)
|
86
|
+
@css_to_preload << css << "\n"
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.has_observers?
|
90
|
+
React::State.has_observers?(self, :loaded_at)
|
91
|
+
end
|
92
|
+
|
93
|
+
prerender_footer do
|
94
|
+
"<style>\n#{@css_to_preload}\n</style>".tap { @css_to_preload = ""}
|
95
|
+
end
|
96
|
+
|
97
|
+
if RUBY_ENGINE == 'opal'
|
98
|
+
|
99
|
+
# I DONT THINK WE USE opal-jquery in this module anymore - require 'opal-jquery' if opal_client?
|
100
|
+
|
101
|
+
include React::Component
|
102
|
+
|
103
|
+
param :loading
|
104
|
+
param :loaded_children
|
105
|
+
param :loading_children
|
106
|
+
param :element_type
|
107
|
+
param :element_props
|
108
|
+
param :display, default: ""
|
109
|
+
|
110
|
+
class << self
|
111
|
+
|
112
|
+
def loading?
|
113
|
+
@is_loading
|
114
|
+
end
|
115
|
+
|
116
|
+
def loading!
|
117
|
+
React::RenderingContext.waiting_on_resources = true
|
118
|
+
React::State.get_state(self, :loaded_at)
|
119
|
+
React::State.set_state(self, :quiet, false)
|
120
|
+
@is_loading = true
|
121
|
+
end
|
122
|
+
|
123
|
+
def loaded_at(loaded_at)
|
124
|
+
React::State.set_state(self, :loaded_at, loaded_at)
|
125
|
+
@is_loading = false
|
126
|
+
end
|
127
|
+
|
128
|
+
def quiet?
|
129
|
+
React::State.get_state(self, :quiet)
|
130
|
+
end
|
131
|
+
|
132
|
+
def page_loaded?
|
133
|
+
React::State.get_state(self, :page_loaded)
|
134
|
+
end
|
135
|
+
|
136
|
+
def quiet!
|
137
|
+
React::State.set_state(self, :quiet, true)
|
138
|
+
after(1) { React::State.set_state(self, :page_loaded, true) } unless on_opal_server? or @page_loaded
|
139
|
+
@page_loaded = true
|
140
|
+
end
|
141
|
+
|
142
|
+
def add_style_sheet
|
143
|
+
@style_sheet ||= %x{
|
144
|
+
$('<style type="text/css">'+
|
145
|
+
' .reactive_record_is_loading > .reactive_record_show_when_loaded { display: none; }'+
|
146
|
+
' .reactive_record_is_loaded > .reactive_record_show_while_loading { display: none; }'+
|
147
|
+
'</style>').appendTo("head")
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
before_mount do
|
154
|
+
@uniq_id = WhileLoading.get_next_while_loading_counter
|
155
|
+
WhileLoading.preload_css(
|
156
|
+
".reactive_record_while_loading_container_#{@uniq_id} > :nth-child(1n+#{loaded_children.count+1}) {\n"+
|
157
|
+
" display: none;\n"+
|
158
|
+
"}\n"
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
after_mount do
|
163
|
+
@waiting_on_resources = loading
|
164
|
+
WhileLoading.add_style_sheet
|
165
|
+
%x{
|
166
|
+
var node = #{dom_node};
|
167
|
+
$(node).children(':nth-child(-1n+'+#{loaded_children.count}+')').addClass('reactive_record_show_when_loaded');
|
168
|
+
$(node).children(':nth-child(1n+'+#{loaded_children.count+1}+')').addClass('reactive_record_show_while_loading');
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
after_update do
|
173
|
+
@waiting_on_resources = loading
|
174
|
+
end
|
175
|
+
|
176
|
+
def render
|
177
|
+
props = element_props.dup
|
178
|
+
classes = [props[:class], props[:className], "reactive_record_while_loading_container_#{@uniq_id}"].compact.join(" ")
|
179
|
+
props.merge!({
|
180
|
+
"data-reactive_record_while_loading_container_id" => @uniq_id,
|
181
|
+
"data-reactive_record_enclosing_while_loading_container_id" => @uniq_id,
|
182
|
+
class: classes
|
183
|
+
})
|
184
|
+
React.create_element(element_type, props) { loaded_children + loading_children }
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
module React
|
194
|
+
|
195
|
+
class Element
|
196
|
+
|
197
|
+
def while_loading(display = "", &loading_display_block)
|
198
|
+
|
199
|
+
loaded_children = []
|
200
|
+
loaded_children = block.call.dup if block
|
201
|
+
|
202
|
+
loading_children = [display]
|
203
|
+
loading_children = RenderingContext.build do |buffer|
|
204
|
+
result = loading_display_block.call
|
205
|
+
buffer << result.to_s if result.is_a? String
|
206
|
+
buffer.dup
|
207
|
+
end if loading_display_block
|
208
|
+
RenderingContext.replace(
|
209
|
+
self,
|
210
|
+
React.create_element(
|
211
|
+
ReactiveRecord::WhileLoading,
|
212
|
+
loading: waiting_on_resources,
|
213
|
+
loading_children: loading_children,
|
214
|
+
loaded_children: loaded_children,
|
215
|
+
element_type: type,
|
216
|
+
element_props: properties)
|
217
|
+
)
|
218
|
+
end
|
219
|
+
|
220
|
+
def hide_while_loading
|
221
|
+
while_loading
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
module Component
|
227
|
+
|
228
|
+
alias_method :original_component_did_mount, :component_did_mount
|
229
|
+
|
230
|
+
def component_did_mount(*args)
|
231
|
+
original_component_did_mount(*args)
|
232
|
+
reactive_record_link_to_enclosing_while_loading_container
|
233
|
+
reactive_record_link_set_while_loading_container_class
|
234
|
+
end
|
235
|
+
|
236
|
+
alias_method :original_component_did_update, :component_did_update
|
237
|
+
|
238
|
+
def component_did_update(*args)
|
239
|
+
original_component_did_update(*args)
|
240
|
+
reactive_record_link_set_while_loading_container_class
|
241
|
+
end
|
242
|
+
|
243
|
+
def reactive_record_link_to_enclosing_while_loading_container
|
244
|
+
# Call after any component mounts - attaches the containers loading id to this component
|
245
|
+
# Fyi, the while_loading container is responsible for setting its own link to itself
|
246
|
+
|
247
|
+
%x{
|
248
|
+
var node = #{dom_node};
|
249
|
+
if (!$(node).is('[data-reactive_record_enclosing_while_loading_container_id]')) {
|
250
|
+
var while_loading_container = $(node).closest('[data-reactive_record_while_loading_container_id]')
|
251
|
+
if (while_loading_container.length > 0) {
|
252
|
+
var container_id = $(while_loading_container).attr('data-reactive_record_while_loading_container_id')
|
253
|
+
$(node).attr('data-reactive_record_enclosing_while_loading_container_id', container_id)
|
254
|
+
}
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
def reactive_record_link_set_while_loading_container_class
|
261
|
+
|
262
|
+
%x{
|
263
|
+
|
264
|
+
var node = #{dom_node};
|
265
|
+
var while_loading_container_id = $(node).attr('data-reactive_record_enclosing_while_loading_container_id');
|
266
|
+
if (while_loading_container_id) {
|
267
|
+
var while_loading_container = $('[data-reactive_record_while_loading_container_id='+while_loading_container_id+']');
|
268
|
+
var loading = (#{waiting_on_resources} == true);
|
269
|
+
if (loading) {
|
270
|
+
$(node).addClass('reactive_record_is_loading');
|
271
|
+
$(node).removeClass('reactive_record_is_loaded');
|
272
|
+
$(while_loading_container).addClass('reactive_record_is_loading');
|
273
|
+
$(while_loading_container).removeClass('reactive_record_is_loaded');
|
274
|
+
|
275
|
+
} else if (!$(node).hasClass('reactive_record_is_loaded')) {
|
276
|
+
|
277
|
+
if (!$(node).attr('data-reactive_record_while_loading_container_id')) {
|
278
|
+
$(node).removeClass('reactive_record_is_loading');
|
279
|
+
$(node).addClass('reactive_record_is_loaded');
|
280
|
+
}
|
281
|
+
if (!$(while_loading_container).hasClass('reactive_record_is_loaded')) {
|
282
|
+
var loading_children = $(while_loading_container).
|
283
|
+
find('[data-reactive_record_enclosing_while_loading_container_id='+while_loading_container_id+'].reactive_record_is_loading')
|
284
|
+
if (loading_children.length == 0) {
|
285
|
+
$(while_loading_container).removeClass('reactive_record_is_loading')
|
286
|
+
$(while_loading_container).addClass('reactive_record_is_loaded')
|
287
|
+
}
|
288
|
+
}
|
289
|
+
|
290
|
+
}
|
291
|
+
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
end if RUBY_ENGINE == 'opal'
|
298
|
+
|
299
|
+
end
|