class LucidFile < LucidDataGeneric include LucidI18nMixin VALID_METHODS = %i[key data data_uri name content_type] class << self def api_path(key:) "#{Isomorfeus.api_files_path}#{self.name}/#{key}" end def format_data_uri(c, d) "data:#{c};base64,#{Base64.strict_encode64(d)}" end def search(query = :all, params = nil) proxy_instance = LucidObject::SearchResultProxy.new(self.name, query, params) unless proxy_instance.loaded? Isomorfeus.something_loading! Isomorfeus.store.deferred_dispatch(type: 'FILE_SEARCH', class_name: self.name, query: query, params: params) end proxy_instance end def destroy(key:) Isomorfeus.store.deferred_dispatch(type: 'FILE_DESTROY', class_name: self.name, key: key) true end def load!(key:, instance: nil) instance = self.new(key: key, _loading: true) unless instance Isomorfeus.something_loading! Isomorfeus.store.deferred_dispatch(type: 'FILE_LOAD', class_name: self.name, key: key) instance end end def initialize(key: nil, content_type: nil, data: nil, data_uri: nil, name: nil, _loading: false) super(key: key) _update_paths loaded = loaded? @changed_uri_string = nil @changed_name = name if name if data_uri @changed_uri_string = data_uri elsif data || content_type data = data.to_s unless data.is_a?(String) if RUBY_ENGINE != 'opal' content_type = Marcel::MimeType.for(data) unless content_type end @changed_uri_string = self.class.format_data_uri(content_type, data) end end def create raise 'Already created!' if revision > 0 @last_revision = 0 d = data_uri unchange! Isomorfeus.something_loading! Isomorfeus.store.deferred_dispatch(type: "FILE_CREATE", class_name: @class_name, key: @key, data_uri: d, name: name, instance_uuid: instance_uuid, revision: 0) self end def save @last_revision = revision return create if @last_revision == 0 d = data_uri unchange! Isomorfeus.something_loading! Isomorfeus.store.deferred_dispatch(type: "FILE_SAVE", class_name: @class_name, key: @key, data_uri: d, name: name, instance_uuid: instance_uuid, revision: @last_revision) self end def [](n) self.send(n) if VALID_METHODS.include?(n) end def []=(n, value) self.send("#{n}=".to_sym, value) if VALID_METHODS.include?(n) end def unchange! super @changed_uri_string = nil end def _update_paths @store_path = [:data_state, @class_name, @key] end def content_type data_uri_object&.content_type end def content_type=(c) changed! uri_string = @changed_uri_string ? @changed_uri_string : Isomorfeus.store.dig(*@store_path)&.fetch(:data_uri, nil) @changed_uri_string = self.class.format_data_uri(c, URI::Data.new(uri_string).data) c end def data_uri @changed_uri_string ? @changed_uri_string : Isomorfeus.store.dig(*@store_path)&.fetch(:data_uri, nil) end def data_uri=(d) changed! @changed_uri_string = d end def data_uri_object du = data_uri URI::Data.new(du) if du end def data data_uri_object&.data end def data=(d) changed! d = d.to_s unless d.is_a?(String) if RUBY_ENGINE == 'opal' ct = content_type else ct = Marcel::MimeType.for(d) end @changed_uri_string = self.class.format_data_uri(ct, d) end def name @changed_name ? @changed_name : Isomorfeus.store.dig(*@store_path)&.fetch(:name, nil) end def name=(n) changed! @changed_name = name end if RUBY_ENGINE != 'opal' class << self def inherited(base) Isomorfeus.add_valid_data_class(base) unless 'LucidFile' == base.name end def file_accelerator @file_accelerator ||= Isomorfeus::Data::FileAccelerator.new(self) end def each(&block) if block_given? file_accelerator.each do |key| block.call self.load(key: key) end else Enumerator.new do |yielder| file_accelerator.each do |key| yielder << self.load(key: key) end end end end alias to_enum each def exist?(key:) raise "Not authorized!" unless current_user.authorized?(self, :load, key: key) file_accelerator.exist?(sid: SID.new(self.name, key)) end end end # RUBY_ENGINE end