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
@@ -6,7 +6,8 @@ declare type RecordType = {
6
6
  declare type Values<T> = T extends {
7
7
  [K in keyof T]: infer U;
8
8
  } ? U : never;
9
- declare type DataTypeExtractField<BaseType, Key extends keyof BaseType> = BaseType[Key] extends RecordType ? (null extends BaseType[Key] ? {} | null : {}) : BaseType[Key] extends RecordType[] ? {}[] : BaseType[Key];
9
+ declare type AddNullable<Test, Type> = null extends Test ? Type | null : Type;
10
+ declare type DataTypeExtractField<BaseType, Key extends keyof BaseType> = Exclude<BaseType[Key], null> extends RecordType ? AddNullable<BaseType[Key], {}> : BaseType[Key] extends RecordType[] ? {}[] : BaseType[Key];
10
11
  declare type DataTypeExtractFieldsFromQuery<BaseType, Fields> = '*' extends Fields ? {
11
12
  [key in Exclude<keyof BaseType, '_meta'>]: DataTypeExtractField<BaseType, key>;
12
13
  } : {
@@ -16,45 +17,48 @@ interface ExtraFieldErrorType {
16
17
  error: 'extraFieldError';
17
18
  }
18
19
  declare type DataTypeExtractFromQueryHash<BaseType, QueryType> = '*' extends keyof QueryType ? {
19
- [key in Exclude<(keyof BaseType) | (keyof QueryType), '_meta' | '_params' | '*'>]: (key extends keyof BaseType ? (key extends keyof QueryType ? (QueryType[key] extends true ? DataTypeExtractField<BaseType, key> : DataTypeFromQuery<BaseType[key] & {}, QueryType[key]>) : DataTypeExtractField<BaseType, key>) : ExtraFieldErrorType);
20
+ [key in Exclude<(keyof BaseType) | (keyof QueryType), '_meta' | '_params' | '*'>]: (key extends keyof BaseType ? (key extends keyof QueryType ? (QueryType[key] extends true ? DataTypeExtractField<BaseType, key> : AddNullable<BaseType[key], DataTypeFromQuery<BaseType[key] & {}, QueryType[key]>>) : DataTypeExtractField<BaseType, key>) : ExtraFieldErrorType);
20
21
  } : {
21
- [key in keyof QueryType]: (key extends keyof BaseType ? (QueryType[key] extends true ? DataTypeExtractField<BaseType, key> : DataTypeFromQuery<BaseType[key] & {}, QueryType[key]>) : ExtraFieldErrorType);
22
+ [key in keyof QueryType]: (key extends keyof BaseType ? (QueryType[key] extends true ? DataTypeExtractField<BaseType, key> : AddNullable<BaseType[key], DataTypeFromQuery<BaseType[key] & {}, QueryType[key]>>) : ExtraFieldErrorType);
22
23
  };
23
24
  declare type _DataTypeFromQuery<BaseType, QueryType> = QueryType extends keyof BaseType | '*' ? DataTypeExtractFieldsFromQuery<BaseType, QueryType> : QueryType extends Readonly<(keyof BaseType | '*')[]> ? DataTypeExtractFieldsFromQuery<BaseType, Values<QueryType>> : QueryType extends {
24
25
  as: string;
25
26
  } ? {
26
27
  error: 'type for alias field is not supported';
27
28
  } | undefined : DataTypeExtractFromQueryHash<BaseType, QueryType>;
28
- export declare type DataTypeFromQuery<BaseType, QueryType> = BaseType extends any[] ? CheckAttributesField<BaseType[0], QueryType>[] : null extends BaseType ? CheckAttributesField<BaseType & {}, QueryType> | null : CheckAttributesField<BaseType & {}, QueryType>;
29
+ export declare type DataTypeFromQuery<BaseType, QueryType> = BaseType extends any[] ? CheckAttributesField<BaseType[0], QueryType>[] : AddNullable<BaseType, CheckAttributesField<BaseType & {}, QueryType>>;
29
30
  declare type CheckAttributesField<P, Q> = Q extends {
30
31
  attributes: infer R;
31
32
  } ? _DataTypeFromQuery<P, R> : _DataTypeFromQuery<P, Q>;
32
33
  declare type IsAnyCompareLeftType = {
33
34
  __any: never;
34
35
  };
35
- declare type CollectExtraFields<Type, Path> = IsAnyCompareLeftType extends Type ? null : Type extends ExtraFieldErrorType ? Path : Type extends (infer R)[] ? _CollectExtraFields<R> : Type extends object ? _CollectExtraFields<Type> : null;
36
- declare type _CollectExtraFields<Type> = keyof (Type) extends never ? null : Values<{
37
- [key in keyof Type]: CollectExtraFields<Type[key], [key]>;
38
- }>;
36
+ declare type CollectExtraFields<Type, Path> = IsAnyCompareLeftType extends Type ? null : Type extends ExtraFieldErrorType ? Path : Type extends (infer R)[] ? _CollectExtraFields<R> : _CollectExtraFields<Type>;
37
+ declare type _CollectExtraFields<Type> = Type extends object ? (keyof (Type) extends never ? null : Values<{
38
+ [key in keyof Type]: CollectExtraFields<Type[key], key>;
39
+ }>) : null;
39
40
  declare type SelectString<T> = T extends string ? T : never;
40
- declare type _ValidateDataTypeExtraFileds<Extra, Type> = SelectString<Values<Extra>> extends never ? Type : {
41
+ declare type _ValidateDataTypeExtraFileds<Extra, Type> = SelectString<Extra> extends never ? Type : {
41
42
  error: {
42
- extraFields: SelectString<Values<Extra>>;
43
+ extraFields: SelectString<Extra>;
43
44
  };
44
45
  };
45
46
  declare type ValidateDataTypeExtraFileds<Type> = _ValidateDataTypeExtraFileds<CollectExtraFields<Type, []>, Type>;
46
47
  declare type RequestBase = {
47
48
  api: string;
48
49
  query: any;
50
+ id?: number;
49
51
  params?: any;
50
52
  _meta?: {
51
53
  data: any;
52
54
  };
53
55
  };
54
- declare type DataTypeBaseFromRequestType<R> = R extends {
56
+ declare type DataTypeBaseFromRequestType<R extends RequestBase, ID> = R extends {
55
57
  _meta?: {
56
58
  data: infer DataType;
57
59
  };
58
- } ? DataType : never;
59
- export declare type DataTypeFromRequest<Req extends RequestBase, R extends RequestBase> = ValidateDataTypeExtraFileds<DataTypeFromQuery<DataTypeBaseFromRequestType<Req>, R['query']>>;
60
+ } ? (ID extends number ? ([DataType, R['params']] extends [(infer DT)[], {
61
+ ids: number[];
62
+ } | undefined] ? DT : never) : DataType) : never;
63
+ export declare type DataTypeFromRequest<Req extends RequestBase, R extends RequestBase> = ValidateDataTypeExtraFileds<DataTypeFromQuery<DataTypeBaseFromRequestType<Req, R['id']>, R['query']>>;
60
64
  export {};
@@ -0,0 +1,28 @@
1
+ declare let useState: <T>(t: T | (() => T)) => [T, (t: T | ((t: T) => T)) => void];
2
+ declare let useEffect: (f: (() => void) | (() => (() => void)), deps: any[]) => void;
3
+ declare let useMemo: <T>(f: () => T, deps: any[]) => T;
4
+ declare type InitializeHooksParams = {
5
+ useState: typeof useState;
6
+ useEffect: typeof useEffect;
7
+ useMemo: typeof useMemo;
8
+ };
9
+ export declare function initializeHooks(hooks: InitializeHooksParams): void;
10
+ interface ModelStatus {
11
+ complete: boolean;
12
+ notfound?: boolean;
13
+ connected: boolean;
14
+ }
15
+ export declare type DataAndStatus<T> = [T | null, ModelStatus];
16
+ export interface Request {
17
+ api: string;
18
+ params?: any;
19
+ query: any;
20
+ }
21
+ export declare function useArSyncModel<T>(request: Request | null): DataAndStatus<T>;
22
+ interface FetchStatus {
23
+ complete: boolean;
24
+ notfound?: boolean;
25
+ }
26
+ declare type DataStatusUpdate<T> = [T | null, FetchStatus, () => void];
27
+ export declare function useArSyncFetch<T>(request: Request | null): DataStatusUpdate<T>;
28
+ export {};
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ArSyncApi_1 = require("./ArSyncApi");
4
+ const ArSyncModel_1 = require("./ArSyncModel");
5
+ let useState;
6
+ let useEffect;
7
+ let useMemo;
8
+ function initializeHooks(hooks) {
9
+ useState = hooks.useState;
10
+ useEffect = hooks.useEffect;
11
+ useMemo = hooks.useMemo;
12
+ }
13
+ exports.initializeHooks = initializeHooks;
14
+ function checkHooks() {
15
+ if (!useState)
16
+ throw 'uninitialized. needs `initializeHooks({ useState, useEffect, useMemo })`';
17
+ }
18
+ const initialResult = [null, { complete: false, notfound: undefined, connected: true }];
19
+ function useArSyncModel(request) {
20
+ checkHooks();
21
+ const [result, setResult] = useState(initialResult);
22
+ const requestString = JSON.stringify(request && request.params);
23
+ useEffect(() => {
24
+ if (!request) {
25
+ setResult(initialResult);
26
+ return () => { };
27
+ }
28
+ const model = new ArSyncModel_1.default(request, { immutable: true });
29
+ function update() {
30
+ const { complete, notfound, connected, data } = model;
31
+ setResult(resultWas => {
32
+ const [, statusWas] = resultWas;
33
+ const statusPersisted = statusWas.complete === complete && statusWas.notfound === notfound && statusWas.connected === connected;
34
+ const status = statusPersisted ? statusWas : { complete, notfound, connected };
35
+ return [data, status];
36
+ });
37
+ }
38
+ if (model.complete) {
39
+ update();
40
+ }
41
+ else {
42
+ setResult(initialResult);
43
+ }
44
+ model.subscribe('change', update);
45
+ model.subscribe('connection', update);
46
+ return () => model.release();
47
+ }, [requestString]);
48
+ return result;
49
+ }
50
+ exports.useArSyncModel = useArSyncModel;
51
+ const initialFetchState = { data: null, status: { complete: false, notfound: undefined } };
52
+ function useArSyncFetch(request) {
53
+ checkHooks();
54
+ const [state, setState] = useState(initialFetchState);
55
+ const requestString = JSON.stringify(request && request.params);
56
+ const loader = useMemo(() => {
57
+ let lastLoadId = 0;
58
+ let timer = null;
59
+ function cancel() {
60
+ if (timer)
61
+ clearTimeout(timer);
62
+ timer = null;
63
+ lastLoadId++;
64
+ }
65
+ function fetch(request, retryCount) {
66
+ cancel();
67
+ const currentLoadingId = lastLoadId;
68
+ ArSyncApi_1.default.fetch(request).then((response) => {
69
+ if (currentLoadingId !== lastLoadId)
70
+ return;
71
+ setState({ data: response, status: { complete: true, notfound: false } });
72
+ }).catch(e => {
73
+ if (currentLoadingId !== lastLoadId)
74
+ return;
75
+ if (!e.retry) {
76
+ setState({ data: null, status: { complete: true, notfound: true } });
77
+ return;
78
+ }
79
+ timer = setTimeout(() => fetch(request, retryCount + 1), 1000 * Math.min(4 ** retryCount, 30));
80
+ });
81
+ }
82
+ function update() {
83
+ if (request) {
84
+ setState(state => {
85
+ const { data, status } = state;
86
+ if (!status.complete && status.notfound === undefined)
87
+ return state;
88
+ return { data, status: { complete: false, notfound: undefined } };
89
+ });
90
+ fetch(request, 0);
91
+ }
92
+ else {
93
+ setState(initialFetchState);
94
+ }
95
+ }
96
+ return { update, cancel };
97
+ }, [requestString]);
98
+ useEffect(() => {
99
+ setState(initialFetchState);
100
+ loader.update();
101
+ return () => loader.cancel();
102
+ }, [requestString]);
103
+ return [state.data, state.status, loader.update];
104
+ }
105
+ exports.useArSyncFetch = useArSyncFetch;
@@ -0,0 +1,2 @@
1
+ export { default as ArSyncModel } from './core/ArSyncModel';
2
+ export { default as ArSyncApi } from './core/ArSyncApi';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var ArSyncModel_1 = require("./core/ArSyncModel");
4
+ exports.ArSyncModel = ArSyncModel_1.default;
5
+ var ArSyncApi_1 = require("./core/ArSyncApi");
6
+ exports.ArSyncApi = ArSyncApi_1.default;
@@ -1,22 +1,5 @@
1
1
  module ArSync
2
- module GraphSync; end
3
- module TreeSync; end
4
- def self.use(mode, klass: ActiveRecord::Base)
5
- case mode
6
- when :tree
7
- if klass.ancestors.include? ArSync::GraphSync
8
- raise ArgumentError, 'already activated ArSync::GraphSync'
9
- end
10
- klass.include ArSync::TreeSync
11
- when :graph
12
- if klass.ancestors.include? ArSync::TreeSync
13
- raise ArgumentError, 'already activated ArSync::TreeSync'
14
- end
15
- klass.include ArSync::GraphSync
16
- else
17
- raise ArgumentError, 'argument should be :tree or :graph'
18
- end
19
- end
2
+ module ModelBase; end
20
3
  end
21
4
  require 'ar_sync/version'
22
5
  require 'ar_sync/core'
@@ -1,7 +1,7 @@
1
1
  require_relative 'field'
2
2
  require_relative 'collection'
3
3
 
4
- module ArSync::ClassMethodsBase
4
+ module ArSync::ModelBase::ClassMethods
5
5
  def _sync_self?
6
6
  instance_variable_defined? '@_sync_self'
7
7
  end
@@ -30,89 +30,16 @@ module ArSync::ClassMethodsBase
30
30
  superclass._each_sync_child(&block) if superclass < ActiveRecord::Base
31
31
  end
32
32
 
33
- def sync_parent(parent, inverse_of:, only_to: nil)
33
+ def sync_parent(parent, inverse_of:, only_to: nil, watch: nil)
34
34
  _initialize_sync_callbacks
35
35
  _sync_parents_info << [
36
36
  parent,
37
- { inverse_name: inverse_of, only_to: only_to }
37
+ { inverse_name: inverse_of, only_to: only_to, watch: watch }
38
38
  ]
39
39
  end
40
- end
41
-
42
- module ArSync::TreeSync::ClassMethods
43
- include ArSync::ClassMethodsBase
44
- def sync_collection(name)
45
- ArSync::Collection::Tree.find self, name
46
- end
47
-
48
- def sync_has_data(*names, **option, &original_data_block)
49
- @_sync_self = true
50
- option = option.dup
51
- if original_data_block
52
- data_block = ->(*args) { instance_exec(*args, &original_data_block).as_json }
53
- end
54
- option[:params_type] = {}
55
- names.each do |name|
56
- type_override = data_block.nil? && reflect_on_association(name.to_s.underscore) ? { type: :any } : {}
57
- _sync_define ArSync::DataField.new(name), option.merge(type_override), &data_block
58
- end
59
- end
60
-
61
- def sync_has_one(name, **option, &data_block)
62
- _sync_define ArSync::HasOneField.new(name), option, &data_block
63
- end
64
-
65
- def sync_has_many(name, order: :asc, propagate_when: nil, params_type: nil, limit: nil, preload: nil, association: nil, **option, &data_block)
66
- if data_block.nil? && preload.nil?
67
- underscore_name = name.to_s.underscore.to_sym
68
- preload = lambda do |records, _context, params|
69
- ArSerializer::Field.preload_association(
70
- self, records, association || underscore_name,
71
- order: (!limit && params && params[:order]) || order,
72
- limit: [params && params[:limit]&.to_i, limit].compact.min
73
- )
74
- end
75
- data_block = lambda do |preloaded, _context, _params|
76
- preloaded ? preloaded[id] || [] : send(name)
77
- end
78
- params_type = { limit?: :int, order?: [{ :* => %w[asc desc] }, 'asc', 'desc'] }
79
- else
80
- params_type = {}
81
- end
82
- field = ArSync::HasManyField.new name, association: association, order: order, limit: limit, propagate_when: propagate_when
83
- _sync_define field, preload: preload, association: association, params_type: params_type, **option, &data_block
84
- end
85
-
86
- def _sync_define(info, **option, &data_block)
87
- _initialize_sync_callbacks
88
- _sync_children_info[info.name] = info
89
- serializer_field info.name, **option, &data_block unless _serializer_field_info info.name
90
- serializer_field info.name, **option, namespace: :sync, &data_block
91
- end
92
-
93
- def sync_define_collection(name, limit: nil, order: :asc)
94
- _initialize_sync_callbacks
95
- collection = ArSync::Collection::Tree.new self, name, limit: limit, order: order
96
- sync_parent collection, inverse_of: [self, name]
97
- end
98
-
99
- def _initialize_sync_callbacks
100
- return if instance_variable_defined? '@_sync_callbacks_initialized'
101
- @_sync_callbacks_initialized = true
102
- _sync_define ArSync::DataField.new(:id)
103
- %i[create update destroy].each do |action|
104
- after_commit on: action do
105
- next if ArSync.skip_notification?
106
- self.class.default_scoped.scoping { _sync_notify action }
107
- end
108
- end
109
- end
110
- end
111
40
 
112
- module ArSync::GraphSync::ClassMethods
113
- include ArSync::ClassMethodsBase
114
41
  def sync_collection(name)
115
- ArSync::Collection::Graph.find self, name
42
+ ArSync::Collection.find self, name
116
43
  end
117
44
 
118
45
  def sync_has_data(*names, **option, &data_block)
@@ -153,22 +80,33 @@ module ArSync::GraphSync::ClassMethods
153
80
  limit: [params && params[:limit]&.to_i, limit].compact.min
154
81
  )
155
82
  end
83
+ serializer_data_block = lambda do |preloaded, _context, _params|
84
+ preloaded ? preloaded[id] || [] : send(name)
85
+ end
156
86
  params_type = { limit?: :int, order?: [{ :* => %w[asc desc] }, 'asc', 'desc'] }
157
87
  else
158
88
  params_type = {}
159
89
  end
160
- _sync_define name, preload: preload, association: association, **option.merge(params_type: params_type), &data_block
161
- end
162
-
163
- def _sync_define(name, **option, &data_block)
90
+ _sync_define(
91
+ name,
92
+ serializer_data_block: serializer_data_block,
93
+ preload: preload,
94
+ association: association,
95
+ params_type: params_type,
96
+ **option,
97
+ &data_block
98
+ )
99
+ end
100
+
101
+ def _sync_define(name, serializer_data_block: nil, **option, &data_block)
164
102
  _initialize_sync_callbacks
165
- serializer_field name, **option, &data_block unless _serializer_field_info name
103
+ serializer_field name, **option, &(serializer_data_block || data_block) unless _serializer_field_info name
166
104
  serializer_field name, **option, namespace: :sync, &data_block
167
105
  end
168
106
 
169
107
  def sync_define_collection(name, limit: nil, order: :asc)
170
108
  _initialize_sync_callbacks
171
- collection = ArSync::Collection::Graph.new self, name, limit: limit, order: order
109
+ collection = ArSync::Collection.new self, name, limit: limit, order: order
172
110
  sync_parent collection, inverse_of: [self, name]
173
111
  end
174
112
 
@@ -176,8 +114,9 @@ module ArSync::GraphSync::ClassMethods
176
114
  return if instance_variable_defined? '@_sync_callbacks_initialized'
177
115
  @_sync_callbacks_initialized = true
178
116
  mod = Module.new do
179
- def write_attribute(attr_name, value)
117
+ def _write_attribute(attr_name, value)
180
118
  self.class.default_scoped.scoping do
119
+ @_sync_watch_values_before_mutation ||= _sync_current_watch_values
181
120
  @_sync_parents_info_before_mutation ||= _sync_current_parents_info
182
121
  @_sync_belongs_to_info_before_mutation ||= _sync_current_belongs_to_info
183
122
  end
@@ -185,32 +124,35 @@ module ArSync::GraphSync::ClassMethods
185
124
  end
186
125
  end
187
126
  prepend mod
188
- attr_reader :_sync_parents_info_before_mutation, :_sync_belongs_to_info_before_mutation
127
+ attr_reader :_sync_parents_info_before_mutation, :_sync_belongs_to_info_before_mutation, :_sync_watch_values_before_mutation
189
128
 
190
129
  _sync_define :id
191
130
 
192
131
  _sync_define :sync_keys, type: [:string] do |current_user|
193
- ArSync.sync_graph_keys self, current_user
132
+ ArSync.sync_keys self, current_user
194
133
  end
195
134
 
196
135
  _sync_define :defaults, namespace: :sync do |current_user|
197
- { sync_keys: ArSync.sync_graph_keys(self, current_user) }
136
+ { sync_keys: ArSync.sync_keys(self, current_user) }
198
137
  end
199
138
 
200
139
  before_destroy do
201
140
  @_sync_parents_info_before_mutation ||= _sync_current_parents_info
141
+ @_sync_watch_values_before_mutation ||= _sync_current_watch_values
202
142
  @_sync_belongs_to_info_before_mutation ||= _sync_current_belongs_to_info
203
143
  end
204
144
 
205
145
  before_save on: :create do
206
- @_sync_parents_info_before_mutation ||= _sync_current_parents_info
207
- @_sync_belongs_to_info_before_mutation ||= _sync_current_belongs_to_info
146
+ @_sync_parents_info_before_mutation ||= {}
147
+ @_sync_watch_values_before_mutation ||= {}
148
+ @_sync_belongs_to_info_before_mutation ||= {}
208
149
  end
209
150
 
210
151
  %i[create update destroy].each do |action|
211
152
  after_commit on: action do
212
153
  next if ArSync.skip_notification?
213
154
  self.class.default_scoped.scoping { _sync_notify action }
155
+ @_sync_watch_values_before_mutation = nil
214
156
  @_sync_parents_info_before_mutation = nil
215
157
  @_sync_belongs_to_info_before_mutation = nil
216
158
  end
@@ -11,11 +11,6 @@ class ArSync::Collection
11
11
  define_singleton_method(name) { to_a }
12
12
  end
13
13
 
14
- def sync_send_event(type:, to_user: nil, data:)
15
- event_data = { type: type, data: data }
16
- ArSync.sync_tree_send to: self, action: :event, path: [], data: event_data, to_user: to_user
17
- end
18
-
19
14
  def to_a
20
15
  all = klass.all
21
16
  all = all.order id: order if order
@@ -30,35 +25,15 @@ class ArSync::Collection
30
25
  def self.find(klass, name)
31
26
  defined_collections[[klass, name]]
32
27
  end
33
- end
34
-
35
- class ArSync::Collection::Tree < ArSync::Collection
36
- def initialize(*)
37
- super
38
- @field = ArSync::CollectionField.new @name, limit: @limit, order: @order
39
- self.class._sync_children_info[[@klass, @name]] = @field
40
- end
41
-
42
- def _sync_notify_parent(*); end
43
-
44
- def self._sync_children_info
45
- @sync_children_info ||= {}
46
- end
47
-
48
- def self._sync_child_info(key)
49
- _sync_children_info[key]
50
- end
51
- end
52
28
 
53
- class ArSync::Collection::Graph < ArSync::Collection
54
- def _sync_notify_child_changed(_child, _name, _to_user, _owned); end
29
+ def _sync_notify_child_changed(_name, _to_user); end
55
30
 
56
- def _sync_notify_child_added(child, _name, to_user, _owned)
57
- ArSync.sync_graph_send to: self, action: :add, model: child, path: :collection, to_user: to_user
31
+ def _sync_notify_child_added(child, _name, to_user)
32
+ ArSync.sync_send to: self, action: :add, model: child, path: :collection, to_user: to_user
58
33
  end
59
34
 
60
35
  def _sync_notify_child_removed(child, _name, to_user, _owned)
61
- ArSync.sync_graph_send to: self, action: :remove, model: child, path: :collection, to_user: to_user
36
+ ArSync.sync_send to: self, action: :remove, model: child, path: :collection, to_user: to_user
62
37
  end
63
38
 
64
39
  def self._sync_children_info