-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.js
More file actions
118 lines (106 loc) · 2.32 KB
/
index.js
File metadata and controls
118 lines (106 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { invalidate } from '$app/navigation'
const endpoint = '/api'
/** @type {Function} */
let onUnauth
/**
* @template T
* @param {string} fn
* @param {Object} args
* @param {fetch} fetch
* @returns {Promise<Api.Response<T>>}
*/
async function invoke (fn, args, fetch) {
const resp = await fetch(`${endpoint}/${fn}`, {
method: 'POST',
body: JSON.stringify(args || {}),
headers: {
'content-type': 'application/json'
}
})
const body = await resp.json()
if (!body.ok) {
const msg = body.error?.message || ''
switch (msg) {
case 'api: unauthorized':
body.error.unauth = true
onUnauth?.()
break
case 'api: forbidden':
body.error.forbidden = true
break
case 'iam: forbidden':
body.error.forbidden = true
break
case 'api: validate error':
body.error.validate = body.error.items
break
default:
if (msg.includes('api: ') && msg.includes('not found')) {
body.error.notFound = true
}
break
}
}
return body
}
/**
* @template T
* @param {string} indexId
* @param {string} fn
* @param {Object} args
* @param {fetch} fetch
* @returns {Promise<Api.ResponseLog<T>>}
*/
async function invokeLog (indexId, fn, args, fetch) {
const url = `${indexId}${fn ? ('/' + fn) : ''}${args ? ('?' + args) : ''}`
const resp = await fetch(`${endpoint}/log/${encodeURIComponent(url)}`, {
method: 'POST',
headers: {
'content-type': 'application/json'
}
})
const body = await resp.json()
return body
}
/**
* @param {Function} callback
*/
function setOnUnauth (callback) {
onUnauth = callback
}
/**
* @param {string} fn
* @returns {Promise<void>}
*/
function wrapInvalidate (fn) {
return invalidate(`${endpoint}/${fn}`)
}
/**
* intervalInvalidate calls callback every interval milliseconds
* must be called in onMount
* callback can return a number to override the interval for only the next call
* @param {() => Promise<number | void>} callback
* @param {number} interval
* @returns {() => void}
*/
function intervalInvalidate (callback, interval) {
let p
const f = async () => {
let newInterval = await callback()
if (!newInterval) {
newInterval = interval
}
p = setTimeout(f, newInterval)
}
p = setTimeout(f, interval)
return () => {
clearTimeout(p)
}
}
export default {
invoke,
invokeLog,
setOnUnauth,
invalidate: wrapInvalidate,
intervalInvalidate
}