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
@@ -1,7 +1,8 @@
1
1
  type RecordType = { _meta?: { query: any } }
2
2
  type Values<T> = T extends { [K in keyof T]: infer U } ? U : never
3
- type DataTypeExtractField<BaseType, Key extends keyof BaseType> = BaseType[Key] extends RecordType
4
- ? (null extends BaseType[Key] ? {} | null : {})
3
+ type AddNullable<Test, Type> = null extends Test ? Type | null : Type
4
+ type DataTypeExtractField<BaseType, Key extends keyof BaseType> = Exclude<BaseType[Key], null> extends RecordType
5
+ ? AddNullable<BaseType[Key], {}>
5
6
  : BaseType[Key] extends RecordType[]
6
7
  ? {}[]
7
8
  : BaseType[Key]
@@ -11,7 +12,7 @@ type DataTypeExtractFieldsFromQuery<BaseType, Fields> = '*' extends Fields
11
12
  : { [key in Fields & keyof (BaseType)]: DataTypeExtractField<BaseType, key> }
12
13
 
13
14
  interface ExtraFieldErrorType {
14
- extraFieldError: any
15
+ error: 'extraFieldError';
15
16
  }
16
17
 
17
18
  type DataTypeExtractFromQueryHash<BaseType, QueryType> = '*' extends keyof QueryType
@@ -20,7 +21,7 @@ type DataTypeExtractFromQueryHash<BaseType, QueryType> = '*' extends keyof Query
20
21
  ? (key extends keyof QueryType
21
22
  ? (QueryType[key] extends true
22
23
  ? DataTypeExtractField<BaseType, key>
23
- : DataTypeFromQuery<BaseType[key] & {}, QueryType[key]>)
24
+ : AddNullable<BaseType[key], DataTypeFromQuery<BaseType[key] & {}, QueryType[key]>>)
24
25
  : DataTypeExtractField<BaseType, key>)
25
26
  : ExtraFieldErrorType)
26
27
  }
@@ -28,7 +29,7 @@ type DataTypeExtractFromQueryHash<BaseType, QueryType> = '*' extends keyof Query
28
29
  [key in keyof QueryType]: (key extends keyof BaseType
29
30
  ? (QueryType[key] extends true
30
31
  ? DataTypeExtractField<BaseType, key>
31
- : DataTypeFromQuery<BaseType[key] & {}, QueryType[key]>)
32
+ : AddNullable<BaseType[key], DataTypeFromQuery<BaseType[key] & {}, QueryType[key]>>)
32
33
  : ExtraFieldErrorType)
33
34
  }
34
35
 
@@ -42,9 +43,7 @@ type _DataTypeFromQuery<BaseType, QueryType> = QueryType extends keyof BaseType
42
43
 
43
44
  export type DataTypeFromQuery<BaseType, QueryType> = BaseType extends any[]
44
45
  ? CheckAttributesField<BaseType[0], QueryType>[]
45
- : null extends BaseType
46
- ? CheckAttributesField<BaseType & {}, QueryType> | null
47
- : CheckAttributesField<BaseType & {}, QueryType>
46
+ : AddNullable<BaseType, CheckAttributesField<BaseType & {}, QueryType>>
48
47
 
49
48
  type CheckAttributesField<P, Q> = Q extends { attributes: infer R }
50
49
  ? _DataTypeFromQuery<P, R>
@@ -52,22 +51,36 @@ type CheckAttributesField<P, Q> = Q extends { attributes: infer R }
52
51
 
53
52
  type IsAnyCompareLeftType = { __any: never }
54
53
 
55
- type CollectExtraFields<Type, Path> = ExtraFieldErrorType extends Type
56
- ? (IsAnyCompareLeftType extends Type ? null : Path)
57
- : _CollectExtraFields<Type extends (infer R)[] ? R : (Type extends object ? Type : null)>
58
-
59
- type _CollectExtraFields<Type> = keyof (Type) extends never
54
+ type CollectExtraFields<Type, Path> =
55
+ IsAnyCompareLeftType extends Type
60
56
  ? null
61
- : Values<{ [key in keyof Type]: CollectExtraFields<Type[key], [key]> }>
57
+ : Type extends ExtraFieldErrorType
58
+ ? Path
59
+ : Type extends (infer R)[]
60
+ ? _CollectExtraFields<R>
61
+ : _CollectExtraFields<Type>
62
+
63
+ type _CollectExtraFields<Type> = Type extends object
64
+ ? (keyof (Type) extends never
65
+ ? null
66
+ : Values<{ [key in keyof Type]: CollectExtraFields<Type[key], key> }>
67
+ )
68
+ : null
62
69
 
63
70
  type SelectString<T> = T extends string ? T : never
64
- type _ValidateDataTypeExtraFileds<Extra, Type> = SelectString<Values<Extra>> extends never
71
+ type _ValidateDataTypeExtraFileds<Extra, Type> = SelectString<Extra> extends never
65
72
  ? Type
66
- : { error: { extraFields: SelectString<Values<Extra>> } }
73
+ : { error: { extraFields: SelectString<Extra> } }
67
74
  type ValidateDataTypeExtraFileds<Type> = _ValidateDataTypeExtraFileds<CollectExtraFields<Type, []>, Type>
68
75
 
69
- type RequestBase = { api: string; query: any; params?: any; _meta?: { data: any } }
70
- type DataTypeBaseFromRequestType<R> = R extends { _meta?: { data: infer DataType } } ? DataType : never
76
+ type RequestBase = { api: string; query: any; id?: number; params?: any; _meta?: { data: any } }
77
+ type DataTypeBaseFromRequestType<R extends RequestBase, ID> = R extends { _meta?: { data: infer DataType } }
78
+ ? (
79
+ ID extends number
80
+ ? ([DataType, R['params']] extends [(infer DT)[], { ids: number[] } | undefined] ? DT : never)
81
+ : DataType
82
+ )
83
+ : never
71
84
  export type DataTypeFromRequest<Req extends RequestBase, R extends RequestBase> = ValidateDataTypeExtraFileds<
72
- DataTypeFromQuery<DataTypeBaseFromRequestType<Req>, R['query']>
73
- >
85
+ DataTypeFromQuery<DataTypeBaseFromRequestType<Req, R['id']>, R['query']>
86
+ >
@@ -0,0 +1,108 @@
1
+ import ArSyncAPI from './ArSyncApi'
2
+ import ArSyncModel from './ArSyncModel'
3
+
4
+ let useState: <T>(t: T | (() => T)) => [T, (t: T | ((t: T) => T)) => void]
5
+ let useEffect: (f: (() => void) | (() => (() => void)), deps: any[]) => void
6
+ let useMemo: <T>(f: () => T, deps: any[]) => T
7
+ type InitializeHooksParams = {
8
+ useState: typeof useState
9
+ useEffect: typeof useEffect
10
+ useMemo: typeof useMemo
11
+ }
12
+ export function initializeHooks(hooks: InitializeHooksParams) {
13
+ useState = hooks.useState
14
+ useEffect = hooks.useEffect
15
+ useMemo = hooks.useMemo
16
+ }
17
+ function checkHooks() {
18
+ if (!useState) throw 'uninitialized. needs `initializeHooks({ useState, useEffect, useMemo })`'
19
+ }
20
+
21
+ interface ModelStatus { complete: boolean; notfound?: boolean; connected: boolean }
22
+ export type DataAndStatus<T> = [T | null, ModelStatus]
23
+ export interface Request { api: string; params?: any; query: any }
24
+
25
+ const initialResult: DataAndStatus<any> = [null, { complete: false, notfound: undefined, connected: true }]
26
+ export function useArSyncModel<T>(request: Request | null): DataAndStatus<T> {
27
+ checkHooks()
28
+ const [result, setResult] = useState<DataAndStatus<T>>(initialResult)
29
+ const requestString = JSON.stringify(request && request.params)
30
+ useEffect(() => {
31
+ if (!request) {
32
+ setResult(initialResult)
33
+ return () => {}
34
+ }
35
+ const model = new ArSyncModel<T>(request, { immutable: true })
36
+ function update() {
37
+ const { complete, notfound, connected, data } = model
38
+ setResult(resultWas => {
39
+ const [, statusWas] = resultWas
40
+ const statusPersisted = statusWas.complete === complete && statusWas.notfound === notfound && statusWas.connected === connected
41
+ const status = statusPersisted ? statusWas : { complete, notfound, connected }
42
+ return [data, status]
43
+ })
44
+ }
45
+ if (model.complete) {
46
+ update()
47
+ } else {
48
+ setResult(initialResult)
49
+ }
50
+ model.subscribe('change', update)
51
+ model.subscribe('connection', update)
52
+ return () => model.release()
53
+ }, [requestString])
54
+ return result
55
+ }
56
+
57
+ interface FetchStatus { complete: boolean; notfound?: boolean }
58
+ type DataStatusUpdate<T> = [T | null, FetchStatus, () => void]
59
+ type FetchState<T> = { data: T | null; status: FetchStatus }
60
+ const initialFetchState: FetchState<any> = { data: null, status: { complete: false, notfound: undefined } }
61
+ export function useArSyncFetch<T>(request: Request | null): DataStatusUpdate<T> {
62
+ checkHooks()
63
+ const [state, setState] = useState<FetchState<T>>(initialFetchState)
64
+ const requestString = JSON.stringify(request && request.params)
65
+ const loader = useMemo(() => {
66
+ let lastLoadId = 0
67
+ let timer: null | number = null
68
+ function cancel() {
69
+ if (timer) clearTimeout(timer)
70
+ timer = null
71
+ lastLoadId++
72
+ }
73
+ function fetch(request: Request, retryCount: number) {
74
+ cancel()
75
+ const currentLoadingId = lastLoadId
76
+ ArSyncAPI.fetch(request).then((response: T) => {
77
+ if (currentLoadingId !== lastLoadId) return
78
+ setState({ data: response, status: { complete: true, notfound: false } })
79
+ }).catch(e => {
80
+ if (currentLoadingId !== lastLoadId) return
81
+ if (!e.retry) {
82
+ setState({ data: null, status: { complete: true, notfound: true } })
83
+ return
84
+ }
85
+ timer = setTimeout(() => fetch(request, retryCount + 1), 1000 * Math.min(4 ** retryCount, 30))
86
+ })
87
+ }
88
+ function update() {
89
+ if (request) {
90
+ setState(state => {
91
+ const { data, status } = state
92
+ if (!status.complete && status.notfound === undefined) return state
93
+ return { data, status: { complete: false, notfound: undefined } }
94
+ })
95
+ fetch(request, 0)
96
+ } else {
97
+ setState(initialFetchState)
98
+ }
99
+ }
100
+ return { update, cancel }
101
+ }, [requestString])
102
+ useEffect(() => {
103
+ setState(initialFetchState)
104
+ loader.update()
105
+ return () => loader.cancel()
106
+ }, [requestString])
107
+ return [state.data, state.status, loader.update]
108
+ }
@@ -0,0 +1,2 @@
1
+ export { default as ArSyncModel } from './core/ArSyncModel'
2
+ export { default as ArSyncApi } from './core/ArSyncApi'
@@ -5,13 +5,12 @@
5
5
  <% require = -> (path) { path = File.dirname(__FILE__) + "/../../../#{path}"; depend_on path; File.read path } %>
6
6
  <%= require.call 'core/ArSyncApi.js' %>
7
7
  window.ArSyncAPI = exports.default
8
- modules['../core/ArSyncApi'] = { default: exports.default }
8
+ modules['./ArSyncApi'] = { default: exports.default }
9
9
  <%= require.call 'core/ConnectionManager.js' %>
10
- modules['../core/ConnectionManager'] = { default: exports.default }
11
- <%= require.call 'core/ArSyncModelBase.js' %>
12
- modules['../core/ArSyncModelBase'] = { default: exports.default }
13
- <%= require.call 'tree/ArSyncStore.js' %>
10
+ modules['./ConnectionManager'] = { default: exports.default }
11
+ <%= require.call 'core/ArSyncStore.js' %>
14
12
  modules['./ArSyncStore'] = { default: exports.default }
15
- <%= require.call 'tree/ArSyncModel.js' %>
16
- window.ArSyncModel = ArSyncModel
13
+ <%= require.call 'core/ArSyncModel.js' %>
14
+ modules['./ArSyncModel'] = { default: exports.default }
15
+ window.ArSyncModel = exports.default
17
16
  }())
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - tompng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-13 00:00:00.000000000 Z
11
+ date: 2019-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: ar_serializer
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 1.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 1.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activerecord-import
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: ActiveRecord data synchronized with frontend DataStore
84
98
  email:
85
99
  - tomoyapenguin@gmail.com
@@ -101,24 +115,20 @@ files:
101
115
  - core/ActioncableAdapter.js
102
116
  - core/ArSyncApi.d.ts
103
117
  - core/ArSyncApi.js
104
- - core/ArSyncModelBase.d.ts
105
- - core/ArSyncModelBase.js
118
+ - core/ArSyncModel.d.ts
119
+ - core/ArSyncModel.js
120
+ - core/ArSyncStore.d.ts
121
+ - core/ArSyncStore.js
106
122
  - core/ConnectionAdapter.d.ts
107
123
  - core/ConnectionAdapter.js
108
124
  - core/ConnectionManager.d.ts
109
125
  - core/ConnectionManager.js
110
126
  - core/DataType.d.ts
111
127
  - core/DataType.js
112
- - core/hooksBase.d.ts
113
- - core/hooksBase.js
114
- - graph/ArSyncModel.d.ts
115
- - graph/ArSyncModel.js
116
- - graph/ArSyncStore.d.ts
117
- - graph/ArSyncStore.js
118
- - graph/hooks.d.ts
119
- - graph/hooks.js
120
- - graph/index.d.ts
121
- - graph/index.js
128
+ - core/hooks.d.ts
129
+ - core/hooks.js
130
+ - index.d.ts
131
+ - index.js
122
132
  - lib/ar_sync.rb
123
133
  - lib/ar_sync/class_methods.rb
124
134
  - lib/ar_sync/collection.rb
@@ -135,31 +145,16 @@ files:
135
145
  - package.json
136
146
  - src/core/ActioncableAdapter.ts
137
147
  - src/core/ArSyncApi.ts
138
- - src/core/ArSyncModelBase.ts
148
+ - src/core/ArSyncModel.ts
149
+ - src/core/ArSyncStore.ts
139
150
  - src/core/ConnectionAdapter.ts
140
151
  - src/core/ConnectionManager.ts
141
152
  - src/core/DataType.ts
142
- - src/core/hooksBase.ts
143
- - src/graph/ArSyncModel.ts
144
- - src/graph/ArSyncStore.ts
145
- - src/graph/hooks.ts
146
- - src/graph/index.ts
147
- - src/tree/ArSyncModel.ts
148
- - src/tree/ArSyncStore.ts
149
- - src/tree/hooks.ts
150
- - src/tree/index.ts
151
- - tree/ArSyncModel.d.ts
152
- - tree/ArSyncModel.js
153
- - tree/ArSyncStore.d.ts
154
- - tree/ArSyncStore.js
155
- - tree/hooks.d.ts
156
- - tree/hooks.js
157
- - tree/index.d.ts
158
- - tree/index.js
153
+ - src/core/hooks.ts
154
+ - src/index.ts
159
155
  - tsconfig.json
156
+ - vendor/assets/javascripts/ar_sync.js.erb
160
157
  - vendor/assets/javascripts/ar_sync_actioncable_adapter.js.erb
161
- - vendor/assets/javascripts/ar_sync_graph.js.erb
162
- - vendor/assets/javascripts/ar_sync_tree.js.erb
163
158
  homepage: https://github.com/tompng/ar_sync
164
159
  licenses:
165
160
  - MIT
@@ -1,29 +0,0 @@
1
- interface ModelStatus {
2
- complete: boolean;
3
- notfound?: boolean;
4
- connected: boolean;
5
- }
6
- export declare type DataAndStatus<T> = [T | null, ModelStatus];
7
- export interface Request {
8
- api: string;
9
- params?: any;
10
- query: any;
11
- }
12
- interface ArSyncModel<T> {
13
- data: T | null;
14
- complete: boolean;
15
- connected: boolean;
16
- notfound?: boolean;
17
- release(): void;
18
- subscribe(type: any, callback: any): any;
19
- }
20
- export declare function useArSyncModelWithClass<T>(modelClass: {
21
- new <T>(req: Request, option?: any): ArSyncModel<T>;
22
- }, request: Request | null): DataAndStatus<T>;
23
- interface FetchStatus {
24
- complete: boolean;
25
- notfound?: boolean;
26
- }
27
- declare type DataAndStatusAndUpdater<T> = [T | null, FetchStatus, () => void];
28
- export declare function useArSyncFetch<T>(request: Request | null): DataAndStatusAndUpdater<T>;
29
- export {};
@@ -1,80 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const react_1 = require("react");
4
- const ArSyncApi_1 = require("./ArSyncApi");
5
- function useArSyncModelWithClass(modelClass, request) {
6
- const [data, setData] = react_1.useState(null);
7
- const [status, setStatus] = react_1.useState({ complete: false, connected: true });
8
- const updateStatus = (complete, notfound, connected) => {
9
- if (complete === status.complete || notfound === status.notfound || connected === status.notfound)
10
- return;
11
- setStatus({ complete, notfound, connected });
12
- };
13
- react_1.useEffect(() => {
14
- if (!request)
15
- return () => { };
16
- const model = new modelClass(request, { immutable: true });
17
- if (model.complete)
18
- setData(model.data);
19
- updateStatus(model.complete, model.notfound, model.connected);
20
- model.subscribe('change', () => {
21
- updateStatus(model.complete, model.notfound, model.connected);
22
- setData(model.data);
23
- });
24
- model.subscribe('connection', () => {
25
- updateStatus(model.complete, model.notfound, model.connected);
26
- });
27
- return () => model.release();
28
- }, [JSON.stringify(request && request.params)]);
29
- return [data, status];
30
- }
31
- exports.useArSyncModelWithClass = useArSyncModelWithClass;
32
- function useArSyncFetch(request) {
33
- const [response, setResponse] = react_1.useState(null);
34
- const [status, setStatus] = react_1.useState({ complete: false });
35
- const requestString = JSON.stringify(request && request.params);
36
- let canceled = false;
37
- let timer = null;
38
- const update = react_1.useCallback(() => {
39
- if (!request) {
40
- setStatus({ complete: false, notfound: undefined });
41
- return () => { };
42
- }
43
- canceled = false;
44
- timer = null;
45
- const fetch = (count) => {
46
- if (timer)
47
- clearTimeout(timer);
48
- timer = null;
49
- ArSyncApi_1.default.fetch(request)
50
- .then((response) => {
51
- if (canceled)
52
- return;
53
- setResponse(response);
54
- setStatus({ complete: true, notfound: false });
55
- })
56
- .catch(e => {
57
- if (canceled)
58
- return;
59
- if (!e.retry) {
60
- setResponse(null);
61
- setStatus({ complete: true, notfound: true });
62
- return;
63
- }
64
- timer = setTimeout(() => fetch(count + 1), 1000 * Math.min(4 ** count, 30));
65
- });
66
- };
67
- fetch(0);
68
- }, [requestString]);
69
- react_1.useEffect(() => {
70
- update();
71
- return () => {
72
- canceled = true;
73
- if (timer)
74
- clearTimeout(timer);
75
- timer = null;
76
- };
77
- }, [requestString]);
78
- return [response, status, update];
79
- }
80
- exports.useArSyncFetch = useArSyncFetch;