ar_sync 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +27 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +29 -31
- data/ar_sync.gemspec +1 -1
- data/core/{ActioncableAdapter.d.ts → ActionCableAdapter.d.ts} +0 -0
- data/core/ActionCableAdapter.js +31 -0
- data/core/ArSyncApi.d.ts +8 -2
- data/core/ArSyncApi.js +123 -49
- data/core/ArSyncModel.js +69 -60
- data/core/ArSyncStore.js +522 -381
- data/core/ConnectionManager.d.ts +1 -1
- data/core/ConnectionManager.js +45 -38
- data/core/DataType.d.ts +14 -9
- data/core/hooks.d.ts +5 -0
- data/core/hooks.js +64 -36
- data/gemfiles/Gemfile-rails-6 +9 -0
- data/gemfiles/Gemfile-rails-7 +9 -0
- data/index.js +2 -2
- data/lib/ar_sync/class_methods.rb +71 -36
- data/lib/ar_sync/collection.rb +23 -19
- data/lib/ar_sync/core.rb +3 -3
- data/lib/ar_sync/instance_methods.rb +7 -4
- data/lib/ar_sync/rails.rb +1 -1
- data/lib/ar_sync/type_script.rb +50 -14
- data/lib/ar_sync/version.rb +1 -1
- data/lib/generators/ar_sync/install/install_generator.rb +1 -1
- data/package-lock.json +1706 -227
- data/package.json +1 -1
- data/src/core/{ActioncableAdapter.ts → ActionCableAdapter.ts} +0 -0
- data/src/core/ArSyncApi.ts +20 -7
- data/src/core/ArSyncStore.ts +177 -125
- data/src/core/ConnectionManager.ts +1 -0
- data/src/core/DataType.ts +15 -16
- data/src/core/hooks.ts +31 -7
- data/tsconfig.json +2 -2
- data/vendor/assets/javascripts/{ar_sync_actioncable_adapter.js.erb → ar_sync_action_cable_adapter.js.erb} +1 -1
- metadata +17 -16
- data/core/ActioncableAdapter.js +0 -29
- data/lib/ar_sync/field.rb +0 -96
@@ -8,7 +8,7 @@ module ArSync::ModelBase::InstanceMethods
|
|
8
8
|
values = {}
|
9
9
|
self.class._each_sync_parent do |_, info|
|
10
10
|
[*info[:watch]].each do |watch|
|
11
|
-
values[watch] = watch.is_a?(Proc) ? instance_exec(&watch) :
|
11
|
+
values[watch] = watch.is_a?(Proc) ? instance_exec(&watch) : __send__(watch)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
values
|
@@ -33,10 +33,10 @@ module ArSync::ModelBase::InstanceMethods
|
|
33
33
|
def _serializer_field_value(name)
|
34
34
|
field = self.class._serializer_field_info name
|
35
35
|
preloadeds = field.preloaders.map do |preloader|
|
36
|
-
args = [[self], nil
|
36
|
+
args = [[self], nil]
|
37
37
|
preloader.call(*(preloader.arity < 0 ? args : args.take(preloader.arity)))
|
38
38
|
end
|
39
|
-
instance_exec(*preloadeds, nil,
|
39
|
+
instance_exec(*preloadeds, nil, &field.data_block)
|
40
40
|
end
|
41
41
|
|
42
42
|
def _sync_current_belongs_to_info
|
@@ -65,11 +65,13 @@ module ArSync::ModelBase::InstanceMethods
|
|
65
65
|
parents_was = parents.map { nil }
|
66
66
|
elsif action == :destroy
|
67
67
|
parents_was = _sync_parents_info_before_mutation
|
68
|
+
return unless parents_was
|
68
69
|
parents = parents_was.map { nil }
|
69
70
|
else
|
70
71
|
parents_was = _sync_parents_info_before_mutation
|
72
|
+
return unless parents_was
|
71
73
|
parents = _sync_current_parents_info
|
72
|
-
column_values_was = _sync_watch_values_before_mutation
|
74
|
+
column_values_was = _sync_watch_values_before_mutation || {}
|
73
75
|
column_values = _sync_current_watch_values
|
74
76
|
end
|
75
77
|
parents_was.zip(parents).each do |(parent_was, info_was), (parent, info)|
|
@@ -109,6 +111,7 @@ module ArSync::ModelBase::InstanceMethods
|
|
109
111
|
|
110
112
|
def _sync_notify_self
|
111
113
|
belongs_was = _sync_belongs_to_info_before_mutation
|
114
|
+
return unless belongs_was
|
112
115
|
belongs = _sync_current_belongs_to_info
|
113
116
|
belongs.each do |name, info|
|
114
117
|
next if belongs_was[name] == info
|
data/lib/ar_sync/rails.rb
CHANGED
@@ -94,7 +94,7 @@ module ArSync
|
|
94
94
|
info = sch.class._serializer_field_info api_name
|
95
95
|
raise ArSync::ApiNotFound, "#{type.to_s.capitalize} API named `#{api_name}` not configured" unless info
|
96
96
|
api_params = (request[:params].as_json || {}).transform_keys(&:to_sym)
|
97
|
-
model = sch.instance_exec(current_user, api_params, &info.data_block)
|
97
|
+
model = sch.instance_exec(current_user, **api_params, &info.data_block)
|
98
98
|
{ data: yield(model, current_user, request[:query].as_json) }
|
99
99
|
rescue StandardError => e
|
100
100
|
{ error: handle_exception(e) }
|
data/lib/ar_sync/type_script.rb
CHANGED
@@ -10,17 +10,14 @@ module ArSync::TypeScript
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.generate_type_definition(api_class)
|
13
|
+
types = ArSerializer::TypeScript.related_serializer_types([api_class]).reject { |t| t.type == api_class }
|
13
14
|
[
|
14
|
-
|
15
|
+
types.map { |t| data_type_definition t },
|
16
|
+
types.map { |t| query_type_definition t },
|
15
17
|
request_type_definition(api_class)
|
16
18
|
].join "\n"
|
17
19
|
end
|
18
20
|
|
19
|
-
def self.api_related_classes(api_class)
|
20
|
-
classes = ArSerializer::TypeScript.related_serializer_types([api_class]).map(&:type)
|
21
|
-
classes - [api_class]
|
22
|
-
end
|
23
|
-
|
24
21
|
def self.request_type_definition(api_class)
|
25
22
|
type = ArSerializer::GraphQL::TypeClass.from api_class
|
26
23
|
definitions = []
|
@@ -78,24 +75,63 @@ module ArSync::TypeScript
|
|
78
75
|
<<~CODE
|
79
76
|
import { TypeRequest, ApiNameRequests } from './types'
|
80
77
|
import { DataTypeFromRequest as DataTypeFromRequestPair } from 'ar_sync/core/DataType'
|
81
|
-
type
|
78
|
+
export type NeverMatchArgument = { __nevermatch: never }
|
79
|
+
type DataTypeFromRequest<R extends TypeRequest | NeverMatchArgument> = NeverMatchArgument extends R ? never : R extends TypeRequest ? DataTypeFromRequestPair<ApiNameRequests[R['api']], R> : never
|
82
80
|
export default DataTypeFromRequest
|
83
81
|
CODE
|
84
82
|
end
|
85
83
|
|
86
84
|
def self.generate_hooks_script
|
87
85
|
<<~CODE
|
88
|
-
import { useState, useEffect, useMemo } from 'react'
|
86
|
+
import { useState, useEffect, useMemo, useRef } from 'react'
|
89
87
|
import { TypeRequest } from './types'
|
90
|
-
import DataTypeFromRequest from './DataTypeFromRequest'
|
88
|
+
import DataTypeFromRequest, { NeverMatchArgument } from './DataTypeFromRequest'
|
91
89
|
import { initializeHooks, useArSyncModel as useArSyncModelBase, useArSyncFetch as useArSyncFetchBase } from 'ar_sync/core/hooks'
|
92
|
-
initializeHooks({ useState, useEffect, useMemo })
|
93
|
-
export function useArSyncModel<R extends TypeRequest>(request: R | null) {
|
94
|
-
return useArSyncModelBase<DataTypeFromRequest<R>>(request)
|
90
|
+
initializeHooks({ useState, useEffect, useMemo, useRef })
|
91
|
+
export function useArSyncModel<R extends TypeRequest | NeverMatchArgument>(request: R | null) {
|
92
|
+
return useArSyncModelBase<DataTypeFromRequest<R>>(request as TypeRequest)
|
95
93
|
}
|
96
|
-
export function useArSyncFetch<R extends TypeRequest>(request: R | null) {
|
97
|
-
return useArSyncFetchBase<DataTypeFromRequest<R>>(request)
|
94
|
+
export function useArSyncFetch<R extends TypeRequest | NeverMatchArgument>(request: R | null) {
|
95
|
+
return useArSyncFetchBase<DataTypeFromRequest<R>>(request as TypeRequest)
|
98
96
|
}
|
99
97
|
CODE
|
100
98
|
end
|
99
|
+
|
100
|
+
def self.query_type_definition(type)
|
101
|
+
field_definitions = type.fields.map do |field|
|
102
|
+
association_type = field.type.association_type
|
103
|
+
if association_type
|
104
|
+
qname = "Type#{association_type.name}Query"
|
105
|
+
if field.args.empty?
|
106
|
+
"#{field.name}?: true | #{qname} | { attributes?: #{qname} }"
|
107
|
+
else
|
108
|
+
"#{field.name}?: true | #{qname} | { params: #{field.args_ts_type}; attributes?: #{qname} }"
|
109
|
+
end
|
110
|
+
else
|
111
|
+
"#{field.name}?: true"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
field_definitions << "'*'?: true"
|
115
|
+
query_type_name = "Type#{type.name}Query"
|
116
|
+
base_query_type_name = "Type#{type.name}QueryBase"
|
117
|
+
<<~TYPE
|
118
|
+
export type #{query_type_name} = keyof (#{base_query_type_name}) | Readonly<(keyof (#{base_query_type_name}))[]> | #{base_query_type_name}
|
119
|
+
export interface #{base_query_type_name} {
|
120
|
+
#{field_definitions.map { |line| " #{line}" }.join("\n")}
|
121
|
+
}
|
122
|
+
TYPE
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.data_type_definition(type)
|
126
|
+
field_definitions = []
|
127
|
+
type.fields.each do |field|
|
128
|
+
field_definitions << "#{field.name}: #{field.type.ts_type}"
|
129
|
+
end
|
130
|
+
field_definitions << "_meta?: { name: '#{type.name}'; query: Type#{type.name}QueryBase }"
|
131
|
+
<<~TYPE
|
132
|
+
export interface Type#{type.name} {
|
133
|
+
#{field_definitions.map { |line| " #{line}" }.join("\n")}
|
134
|
+
}
|
135
|
+
TYPE
|
136
|
+
end
|
101
137
|
end
|
data/lib/ar_sync/version.rb
CHANGED
@@ -78,7 +78,7 @@ module ArSync
|
|
78
78
|
[
|
79
79
|
'//= require ar_sync',
|
80
80
|
'//= require action_cable',
|
81
|
-
'//= require
|
81
|
+
'//= require ar_sync_action_cable_adapter',
|
82
82
|
'ArSyncModel.setConnectionAdapter(new ArSyncActionCableAdapter(ActionCable))'
|
83
83
|
].join("\n") + "\n",
|
84
84
|
before: '//= require_tree .'
|