ar_sync 1.0.1 → 1.0.2

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.
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;