ar_sync 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +5 -2
  3. data/README.md +6 -6
  4. data/ar_sync.gemspec +2 -2
  5. data/bin/console +1 -2
  6. data/core/ActioncableAdapter.d.ts +26 -2
  7. data/core/ActioncableAdapter.js +3 -3
  8. data/core/ArSyncApi.d.ts +7 -4
  9. data/core/ArSyncApi.js +9 -4
  10. data/core/{ArSyncModelBase.d.ts → ArSyncModel.d.ts} +13 -18
  11. data/core/{ArSyncModelBase.js → ArSyncModel.js} +33 -10
  12. data/{graph → core}/ArSyncStore.d.ts +3 -3
  13. data/{graph → core}/ArSyncStore.js +188 -57
  14. data/core/DataType.d.ts +17 -13
  15. data/core/hooks.d.ts +28 -0
  16. data/core/hooks.js +105 -0
  17. data/index.d.ts +2 -0
  18. data/index.js +6 -0
  19. data/lib/ar_sync.rb +1 -18
  20. data/lib/ar_sync/class_methods.rb +31 -89
  21. data/lib/ar_sync/collection.rb +4 -29
  22. data/lib/ar_sync/core.rb +35 -67
  23. data/lib/ar_sync/instance_methods.rb +40 -86
  24. data/lib/ar_sync/rails.rb +18 -27
  25. data/lib/ar_sync/type_script.rb +39 -18
  26. data/lib/ar_sync/version.rb +1 -1
  27. data/lib/generators/ar_sync/install/install_generator.rb +33 -32
  28. data/lib/generators/ar_sync/types/types_generator.rb +6 -3
  29. data/package-lock.json +21 -10
  30. data/package.json +1 -1
  31. data/src/core/ActioncableAdapter.ts +28 -3
  32. data/src/core/ArSyncApi.ts +8 -4
  33. data/src/core/{ArSyncModelBase.ts → ArSyncModel.ts} +51 -20
  34. data/src/{graph → core}/ArSyncStore.ts +199 -84
  35. data/src/core/DataType.ts +33 -20
  36. data/src/core/hooks.ts +108 -0
  37. data/src/index.ts +2 -0
  38. data/vendor/assets/javascripts/{ar_sync_tree.js.erb → ar_sync.js.erb} +6 -7
  39. metadata +33 -38
  40. data/core/hooksBase.d.ts +0 -29
  41. data/core/hooksBase.js +0 -80
  42. data/graph/ArSyncModel.d.ts +0 -10
  43. data/graph/ArSyncModel.js +0 -22
  44. data/graph/hooks.d.ts +0 -3
  45. data/graph/hooks.js +0 -10
  46. data/graph/index.d.ts +0 -2
  47. data/graph/index.js +0 -4
  48. data/src/core/hooksBase.ts +0 -86
  49. data/src/graph/ArSyncModel.ts +0 -21
  50. data/src/graph/hooks.ts +0 -7
  51. data/src/graph/index.ts +0 -2
  52. data/src/tree/ArSyncModel.ts +0 -145
  53. data/src/tree/ArSyncStore.ts +0 -323
  54. data/src/tree/hooks.ts +0 -7
  55. data/src/tree/index.ts +0 -2
  56. data/tree/ArSyncModel.d.ts +0 -39
  57. data/tree/ArSyncModel.js +0 -143
  58. data/tree/ArSyncStore.d.ts +0 -21
  59. data/tree/ArSyncStore.js +0 -365
  60. data/tree/hooks.d.ts +0 -3
  61. data/tree/hooks.js +0 -10
  62. data/tree/index.d.ts +0 -2
  63. data/tree/index.js +0 -4
  64. data/vendor/assets/javascripts/ar_sync_graph.js.erb +0 -17
@@ -4,14 +4,9 @@ require_relative 'class_methods'
4
4
  require_relative 'instance_methods'
5
5
 
6
6
  module ArSync
7
- ArSync::TreeSync.module_eval do
7
+ ArSync::ModelBase.module_eval do
8
8
  extend ActiveSupport::Concern
9
- include ArSync::TreeSync::InstanceMethods
10
- end
11
-
12
- ArSync::GraphSync.module_eval do
13
- extend ActiveSupport::Concern
14
- include ArSync::GraphSync::InstanceMethods
9
+ include ArSync::ModelBase::InstanceMethods
15
10
  end
16
11
 
17
12
  def self.on_notification(&block)
@@ -41,20 +36,15 @@ module ArSync
41
36
  Thread.current[key] = flag_was
42
37
  end
43
38
 
44
- def self.sync_tree_send(to:, action:, path:, data:, to_user: nil, ordering: nil)
45
- key = sync_key to, path.grep(Symbol), to_user, signature: false
46
- event = [key, action: action, path: path, data: data, ordering: ordering]
47
- buffer = Thread.current[:ar_sync_compact_notifications]
48
- if buffer
49
- buffer << event
50
- else
51
- @sync_send_block&.call [event]
39
+ def self.sync_send(to:, action:, model:, path: nil, field: nil, to_user: nil)
40
+ key = sync_key to, to_user, signature: false
41
+ e = { action: action }
42
+ e[:field] = field if field
43
+ if model
44
+ e[:class_name] = model.class.base_class.name
45
+ e[:id] = model.id
52
46
  end
53
- end
54
-
55
- def self.sync_graph_send(to:, action:, model:, path: nil, to_user: nil)
56
- key = sync_graph_key to, to_user, signature: false
57
- event = ["#{key}#{path}", action: action, class_name: model.class.base_class.name, id: model.id]
47
+ event = ["#{key}#{path}", e]
58
48
  buffer = Thread.current[:ar_sync_compact_notifications]
59
49
  if buffer
60
50
  buffer << event
@@ -63,23 +53,20 @@ module ArSync
63
53
  end
64
54
  end
65
55
 
66
- def self.sync_graph_key(model, to_user = nil, signature: true)
67
- sync_key(model, :graph_sync, to_user, signature: signature) + ';/'
68
- end
69
-
70
- def self.sync_graph_keys(model, user)
71
- [sync_graph_key(model), sync_graph_key(model, user)]
56
+ def self.sync_keys(model, user)
57
+ [sync_key(model), sync_key(model, user)]
72
58
  end
73
59
 
74
- def self.sync_key(model, path, to_user = nil, signature: true)
60
+ def self.sync_key(model, to_user = nil, signature: true)
75
61
  if model.is_a? ArSync::Collection
76
- key = [to_user&.id, model.klass.name, model.name, path].join '/'
62
+ key = [to_user&.id, model.klass.name, model.name].join '/'
77
63
  else
78
- key = [to_user&.id, model.class.name, model.id, path].join '/'
64
+ key = [to_user&.id, model.class.name, model.id].join '/'
79
65
  end
80
66
  key = Digest::SHA256.hexdigest("#{config.key_secret}#{key}")[0, 32] if config.key_secret
81
67
  key = "#{config.key_prefix}#{key}" if config.key_prefix
82
- signature && config.key_expires_in ? signed_key(key, Time.now.to_i.to_s) : key
68
+ key = signature && config.key_expires_in ? signed_key(key, Time.now.to_i.to_s) : key
69
+ key + ';/'
83
70
  end
84
71
 
85
72
  def self.validate_expiration(signed_key)
@@ -94,45 +81,26 @@ module ArSync
94
81
  "#{key};#{time};#{Digest::SHA256.hexdigest("#{config.key_secret}#{key};#{time}")[0, 16]}"
95
82
  end
96
83
 
97
- def self.sync_collection_api(collection, current_user, args)
98
- paths = _extract_paths args
99
- keys = paths.flat_map do |path|
100
- [sync_key(collection, path), sync_key(collection, path, current_user)]
101
- end
102
- {
103
- keys: keys,
104
- data: serialize(collection.to_a, args, user: current_user)
105
- }
106
- end
107
-
108
- def self.sync_api(model, current_user, args)
109
- paths = _extract_paths args
110
- keys = paths.flat_map do |path|
111
- [sync_key(model, path), sync_key(model, path, current_user)]
112
- end
113
- {
114
- keys: keys,
115
- data: serialize(model, args, user: current_user)
116
- }
84
+ def self.serialize(record_or_records, query, user: nil)
85
+ ArSerializer.serialize record_or_records, query, context: user, include_id: true, use: :sync
117
86
  end
118
87
 
119
- def self._extract_paths(args)
120
- parsed = ArSerializer::Serializer.parse_args args
121
- paths = []
122
- extract = lambda do |path, attributes|
123
- paths << path
124
- attributes.each do |key, value|
125
- sub_attributes = value[:attributes]
126
- next unless sub_attributes
127
- sub_path = [*path, key]
128
- extract.call sub_path, sub_attributes
129
- end
88
+ def self.sync_serialize(target, user, query)
89
+ case target
90
+ when ArSync::Collection, ArSync::ModelBase
91
+ serialized = ArSerializer.serialize target, query, context: user, include_id: true, use: :sync
92
+ return serialized if target.is_a? ArSync::ModelBase
93
+ {
94
+ sync_keys: ArSync.sync_keys(target, user),
95
+ order: { mode: target.order, limit: target.limit },
96
+ collection: serialized
97
+ }
98
+ when ActiveRecord::Relation, Array
99
+ ArSync.serialize target.to_a, query, user: user
100
+ when ArSerializer::Serializable
101
+ ArSync.serialize target, query, user: user
102
+ else
103
+ target
130
104
  end
131
- extract.call [], parsed[:attributes]
132
- paths
133
- end
134
-
135
- def self.serialize(record_or_records, query, user: nil)
136
- ArSerializer.serialize record_or_records, query, context: user, include_id: true, use: :sync
137
105
  end
138
106
  end
@@ -1,83 +1,31 @@
1
- module ArSync::TreeSync::InstanceMethods
1
+ module ArSync::ModelBase::InstanceMethods
2
2
  def _sync_notify(action)
3
- if self.class._sync_self?
4
- data = action == :destroy ? nil : _sync_data
5
- ArSync.sync_tree_send to: self, action: action, path: [], data: data
6
- end
7
3
  _sync_notify_parent action
4
+ _sync_notify_self if self.class._sync_self? && action == :update
8
5
  end
9
6
 
10
- def _sync_data(new_record: false)
11
- fallbacks = {}
12
- names = []
13
- self.class._each_sync_child do |name, info|
14
- names << name if info.type == :data
15
- if new_record
16
- fallbacks[name] = [] if info.type == :many
17
- fallbacks[name] = nil if info.type == :one
7
+ def _sync_current_watch_values
8
+ values = {}
9
+ self.class._each_sync_parent do |_, info|
10
+ [*info[:watch]].each do |watch|
11
+ values[watch] = watch.is_a?(Proc) ? instance_exec(&watch) : send(watch)
18
12
  end
19
13
  end
20
- data = ArSync.serialize self, names
21
- fallbacks.update data
22
- end
23
-
24
- def sync_send_event(type:, relation: nil, to_user: nil, data:)
25
- path = [*relation]
26
- event_data = { type: type, data: data }
27
- if self.class._sync_self?
28
- ArSync.sync_tree_send to: self, action: :event, path: path, data: event_data, to_user: to_user
29
- end
30
- _sync_notify_parent(:event, path: path, data: event_data, only_to_user: to_user)
31
- end
32
-
33
- def _sync_notify_parent(action, path: nil, data: nil, order_param: nil, only_to_user: nil)
34
- self.class._each_sync_parent do |parent, inverse_name:, only_to:|
35
- parent = send(parent) if parent.is_a? Symbol
36
- parent = instance_exec(&parent) if parent.is_a? Proc
37
- next unless parent
38
- next if parent.respond_to?(:destroyed?) && parent.destroyed?
39
- inverse_name = instance_exec(&inverse_name) if inverse_name.is_a? Proc
40
- next unless inverse_name
41
- association_field = parent.class._sync_child_info inverse_name
42
- next if association_field.skip_propagation? parent, self, path
43
- action2 = association_field.action_convert action
44
- only_to_user2 = only_to_user
45
- if only_to
46
- to_user = only_to.is_a?(Symbol) ? instance_eval(&only_to) : instance_exec(&only_to)
47
- next unless to_user
48
- next if only_to_user && only_to_user != to_user
49
- only_to_user2 = to_user
50
- end
51
- data2 = path || action2 == :destroy ? data : association_field.data(parent, self, to_user: to_user, action: action)
52
- order_param2 = path ? order_param : association_field.order_param
53
- path2 = [*association_field.path(self), *path]
54
- ArSync.sync_tree_send(
55
- to: parent, action: action2, path: path2, data: data2,
56
- to_user: only_to_user2,
57
- ordering: order_param2
58
- )
59
- parent._sync_notify_parent action2, path: path2, data: data2, order_param: order_param2, only_to_user: to_user || only_to_user
60
- end
61
- end
62
- end
63
-
64
- module ArSync::GraphSync::InstanceMethods
65
- def _sync_notify(action)
66
- _sync_notify_parent action
67
- _sync_notify_self if self.class._sync_self? && action == :update
14
+ values
68
15
  end
69
16
 
70
17
  def _sync_current_parents_info
71
18
  parents = []
72
- self.class._each_sync_parent do |parent, inverse_name:, only_to:|
19
+ self.class._each_sync_parent do |parent, inverse_name:, only_to:, watch:|
73
20
  parent = send parent if parent.is_a? Symbol
74
21
  parent = instance_exec(&parent) if parent.is_a? Proc
75
22
  if only_to
76
23
  to_user = only_to.is_a?(Symbol) ? instance_eval(&only_to) : instance_exec(&only_to)
77
24
  parent = nil unless to_user
78
25
  end
26
+ inverse_name = instance_exec(&inverse_name) if inverse_name.is_a? Proc
79
27
  owned = parent.class._sync_child_info(inverse_name).present? if parent
80
- parents << [parent, [inverse_name, to_user, owned]]
28
+ parents << [parent, [inverse_name, to_user, owned, watch]]
81
29
  end
82
30
  parents
83
31
  end
@@ -121,36 +69,42 @@ module ArSync::GraphSync::InstanceMethods
121
69
  else
122
70
  parents_was = _sync_parents_info_before_mutation
123
71
  parents = _sync_current_parents_info
72
+ column_values_was = _sync_watch_values_before_mutation
73
+ column_values = _sync_current_watch_values
124
74
  end
125
75
  parents_was.zip(parents).each do |(parent_was, info_was), (parent, info)|
126
- if parent_was == parent && info_was == info
127
- parent&._sync_notify_child_changed self, *info
128
- else
129
- parent_was&._sync_notify_child_removed self, *info_was
130
- parent&._sync_notify_child_added self, *info
76
+ name, to_user, owned, watch = info
77
+ name_was, to_user_was, owned_was = info_was
78
+ if parent_was != parent || info_was != info
79
+ if owned_was
80
+ parent_was&._sync_notify_child_removed self, name_was, to_user_was
81
+ else
82
+ parent_was&._sync_notify_child_changed name_was, to_user_was
83
+ end
84
+ if owned
85
+ parent&._sync_notify_child_added self, name, to_user
86
+ else
87
+ parent&._sync_notify_child_changed name, to_user
88
+ end
89
+ elsif parent
90
+ changed = [*watch].any? do |w|
91
+ column_values_was[w] != column_values[w]
92
+ end
93
+ parent._sync_notify_child_changed name, to_user if changed
131
94
  end
132
95
  end
133
96
  end
134
97
 
135
- def _sync_notify_child_removed(child, name, to_user, owned)
136
- if owned
137
- ArSync.sync_graph_send to: self, action: :remove, model: child, path: name, to_user: to_user
138
- else
139
- ArSync.sync_graph_send to: self, action: :update, model: self, to_user: to_user
140
- end
98
+ def _sync_notify_child_removed(child, name, to_user)
99
+ ArSync.sync_send to: self, action: :remove, model: child, path: name, to_user: to_user
141
100
  end
142
101
 
143
- def _sync_notify_child_added(child, name, to_user, owned)
144
- if owned
145
- ArSync.sync_graph_send to: self, action: :add, model: child, path: name, to_user: to_user
146
- else
147
- ArSync.sync_graph_send to: self, action: :update, model: self, to_user: to_user
148
- end
102
+ def _sync_notify_child_added(child, name, to_user)
103
+ ArSync.sync_send to: self, action: :add, model: child, path: name, to_user: to_user
149
104
  end
150
105
 
151
- def _sync_notify_child_changed(_child, _name, to_user, owned)
152
- return if owned
153
- ArSync.sync_graph_send(to: self, action: :update, model: self, to_user: to_user)
106
+ def _sync_notify_child_changed(name, to_user)
107
+ ArSync.sync_send to: self, action: :update, model: self, field: name, to_user: to_user
154
108
  end
155
109
 
156
110
  def _sync_notify_self
@@ -159,9 +113,9 @@ module ArSync::GraphSync::InstanceMethods
159
113
  belongs.each do |name, info|
160
114
  next if belongs_was[name] == info
161
115
  value = info.key?(:value) ? info[:value] : _serializer_field_value(name)
162
- _sync_notify_child_added value, name, nil, true if value.is_a? ArSerializer::Serializable
163
- _sync_notify_child_removed value, name, nil, true if value.nil?
116
+ _sync_notify_child_added value, name, nil if value.is_a? ArSerializer::Serializable
117
+ _sync_notify_child_removed value, name, nil if value.nil?
164
118
  end
165
- ArSync.sync_graph_send(to: self, action: :update, model: self)
119
+ ArSync.sync_send to: self, action: :update, model: self
166
120
  end
167
121
  end
@@ -28,47 +28,37 @@ module ArSync
28
28
  around_action :action_with_compact_ar_sync_notification
29
29
  end
30
30
 
31
+ class SyncSchemaBase
32
+ include ArSerializer::Serializable
33
+ serializer_field :__schema do
34
+ ArSerializer::GraphQL::SchemaClass.new self.class
35
+ end
36
+ end
37
+
31
38
  module ApiControllerConcern
32
39
  extend ActiveSupport::Concern
33
- include ArSerializer::Serializable
34
40
 
35
41
  included do
36
42
  protect_from_forgery except: %i[sync_call static_call graphql_call]
37
- serializer_field :__schema do
38
- ArSerializer::GraphQL::SchemaClass.new self.class
39
- end
43
+ end
44
+
45
+ def schema
46
+ raise 'you must implement method `schema`'
40
47
  end
41
48
 
42
49
  def sync_call
43
50
  _api_call :sync do |model, current_user, query|
44
- case model
45
- when ArSync::Collection::Graph, ArSync::GraphSync
46
- serialized = ArSerializer.serialize model, query, context: current_user, include_id: true, use: :sync
47
- next serialized if model.is_a? ArSync::GraphSync
48
- {
49
- sync_keys: ArSync.sync_graph_keys(model, current_user),
50
- order: { mode: model.order, limit: model.limit },
51
- collection: serialized
52
- }
53
- when ArSync::Collection::Tree
54
- ArSync.sync_collection_api model, current_user, query
55
- when ActiveRecord::Relation, Array
56
- ArSync.serialize model.to_a, query, user: current_user
57
- when ActiveRecord::Base
58
- ArSync.sync_api model, current_user, query
59
- else
60
- model
61
- end
51
+ ArSync.sync_serialize model, current_user, query
62
52
  end
63
53
  end
64
54
 
65
55
  def graphql_schema
66
- render plain: ArSerializer::GraphQL.definition(self.class)
56
+ render plain: ArSerializer::GraphQL.definition(schema.class)
67
57
  end
68
58
 
69
59
  def graphql_call
70
60
  render json: ArSerializer::GraphQL.serialize(
71
- self,
61
+ schema,
72
62
  params[:query],
73
63
  operation_name: params[:operationName],
74
64
  variables: (params[:variables] || {}).as_json,
@@ -83,7 +73,7 @@ module ArSync
83
73
  case model
84
74
  when ArSync::Collection, ActiveRecord::Relation, Array
85
75
  ArSerializer.serialize model.to_a, query, context: current_user
86
- when ActiveRecord::Base
76
+ when ArSerializer::Serializable
87
77
  ArSerializer.serialize model, query, context: current_user
88
78
  else
89
79
  model
@@ -100,10 +90,11 @@ module ArSync
100
90
  responses = params[:requests].map do |request|
101
91
  begin
102
92
  api_name = request[:api]
103
- info = self.class._serializer_field_info api_name
93
+ sch = schema
94
+ info = sch.class._serializer_field_info api_name
104
95
  raise ArSync::ApiNotFound, "#{type.to_s.capitalize} API named `#{api_name}` not configured" unless info
105
96
  api_params = (request[:params].as_json || {}).transform_keys(&:to_sym)
106
- model = instance_exec(current_user, api_params, &info.data_block)
97
+ model = sch.instance_exec(current_user, api_params, &info.data_block)
107
98
  { data: yield(model, current_user, request[:query].as_json) }
108
99
  rescue StandardError => e
109
100
  { error: handle_exception(e) }
@@ -1,12 +1,11 @@
1
1
  module ArSync::TypeScript
2
- def self.generate_typed_files(api_class, dir:, mode: nil, comment: nil)
3
- mode ||= :graph if ActiveRecord::Base.include? ArSync::GraphSync
4
- mode ||= :tree if ActiveRecord::Base.include? ArSync::TreeSync
5
- raise 'ar_sync mode: graph or tree, is not specified.' unless mode
2
+ def self.generate_typed_files(api_class, dir:, comment: nil)
6
3
  {
7
4
  'types.ts' => generate_type_definition(api_class),
8
- 'ArSyncModel.ts' => generate_model_script(mode),
9
- 'hooks.ts' => generate_hooks_script(mode)
5
+ 'ArSyncModel.ts' => generate_model_script,
6
+ 'ArSyncApi.ts' => generate_api_script,
7
+ 'hooks.ts' => generate_hooks_script,
8
+ 'DataTypeFromRequest.ts' => generate_type_util_script
10
9
  }.each { |file, code| File.write File.join(dir, file), "#{comment}#{code}" }
11
10
  end
12
11
 
@@ -52,28 +51,50 @@ module ArSync::TypeScript
52
51
  ].join("\n")
53
52
  end
54
53
 
55
- def self.generate_model_script(mode)
54
+ def self.generate_model_script
56
55
  <<~CODE
57
- import { TypeRequest, ApiNameRequests } from './types'
58
- import { DataTypeFromRequest } from 'ar_sync/core/DataType'
59
- import ArSyncModelBase from 'ar_sync/#{mode}/ArSyncModel'
60
- export default class ArSyncModel<R extends TypeRequest> extends ArSyncModelBase<{}> {
61
- constructor(r: R) { super(r) }
62
- data: DataTypeFromRequest<ApiNameRequests[R['api']], R> | null
56
+ import { TypeRequest } from './types'
57
+ import DataTypeFromRequest from './DataTypeFromRequest'
58
+ import { default as ArSyncModelBase } from 'ar_sync/core/ArSyncModel'
59
+ declare class ArSyncModel<R extends TypeRequest> extends ArSyncModelBase<DataTypeFromRequest<R>> {
60
+ constructor(r: R, option?: { immutable: boolean })
61
+ }
62
+ export default ArSyncModelBase as typeof ArSyncModel
63
+ CODE
64
+ end
65
+
66
+ def self.generate_api_script
67
+ <<~CODE
68
+ import { TypeRequest } from './types'
69
+ import DataTypeFromRequest from './DataTypeFromRequest'
70
+ import ArSyncApi from 'ar_sync/core/ArSyncApi'
71
+ export function fetch<R extends TypeRequest>(request: R) {
72
+ return ArSyncApi.fetch(request) as Promise<DataTypeFromRequest<R>>
63
73
  }
64
74
  CODE
65
75
  end
66
76
 
67
- def self.generate_hooks_script(mode)
77
+ def self.generate_type_util_script
68
78
  <<~CODE
69
79
  import { TypeRequest, ApiNameRequests } from './types'
70
- import { DataTypeFromRequest } from 'ar_sync/core/DataType'
71
- import { useArSyncModel as useArSyncModelBase, useArSyncFetch as useArSyncFetchBase } from 'ar_sync/#{mode}/hooks'
80
+ import { DataTypeFromRequest as DataTypeFromRequestPair } from 'ar_sync/core/DataType'
81
+ type DataTypeFromRequest<R extends TypeRequest> = DataTypeFromRequestPair<ApiNameRequests[R['api']], R>
82
+ export default DataTypeFromRequest
83
+ CODE
84
+ end
85
+
86
+ def self.generate_hooks_script
87
+ <<~CODE
88
+ import { useState, useEffect, useMemo } from 'react'
89
+ import { TypeRequest } from './types'
90
+ import DataTypeFromRequest from './DataTypeFromRequest'
91
+ import { initializeHooks, useArSyncModel as useArSyncModelBase, useArSyncFetch as useArSyncFetchBase } from 'ar_sync/core/hooks'
92
+ initializeHooks({ useState, useEffect, useMemo })
72
93
  export function useArSyncModel<R extends TypeRequest>(request: R | null) {
73
- return useArSyncModelBase<DataTypeFromRequest<ApiNameRequests[R['api']], R>>(request)
94
+ return useArSyncModelBase<DataTypeFromRequest<R>>(request)
74
95
  }
75
96
  export function useArSyncFetch<R extends TypeRequest>(request: R | null) {
76
- return useArSyncFetchBase<DataTypeFromRequest<ApiNameRequests[R['api']], R>>(request)
97
+ return useArSyncFetchBase<DataTypeFromRequest<R>>(request)
77
98
  }
78
99
  CODE
79
100
  end