@aiao/rxdb-adapter-http 0.0.26
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.
- package/LICENSE +21 -0
- package/README.md +269 -0
- package/dist/RxDBAdapterHttp.d.ts +251 -0
- package/dist/RxDBAdapterHttp.d.ts.map +1 -0
- package/dist/change-feed.d.ts +66 -0
- package/dist/change-feed.d.ts.map +1 -0
- package/dist/chunking.d.ts +29 -0
- package/dist/chunking.d.ts.map +1 -0
- package/dist/conditional-cache.d.ts +175 -0
- package/dist/conditional-cache.d.ts.map +1 -0
- package/dist/config.d.ts +30 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/errors.d.ts +215 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/handler-contract.d.ts +41 -0
- package/dist/handler-contract.d.ts.map +1 -0
- package/dist/http.interface.d.ts +519 -0
- package/dist/http.interface.d.ts.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +864 -0
- package/dist/metadata.d.ts +15 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/pagination.d.ts +30 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/rest.d.ts +94 -0
- package/dist/rest.d.ts.map +1 -0
- package/dist/transport.d.ts +174 -0
- package/dist/transport.d.ts.map +1 -0
- package/package.json +64 -0
- package/src/RxDBAdapterHttp.ts +786 -0
- package/src/change-feed.ts +470 -0
- package/src/chunking.ts +68 -0
- package/src/conditional-cache.ts +271 -0
- package/src/config.ts +83 -0
- package/src/errors.ts +295 -0
- package/src/handler-contract.ts +77 -0
- package/src/http.interface.ts +554 -0
- package/src/index.ts +25 -0
- package/src/metadata.ts +94 -0
- package/src/pagination.ts +184 -0
- package/src/rest.ts +476 -0
- package/src/transport.ts +699 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,864 @@
|
|
|
1
|
+
import { NetworkOfflineError as e, PropertyType as t, RxDBAdapterRemoteBase as n, getEntityMetadata as r, getSyncConfig as i, getSyncType as a, isSystemEntity as o } from "@aiao/rxdb";
|
|
2
|
+
import { defer as s, from as c, map as l, of as u } from "rxjs";
|
|
3
|
+
//#region src/errors.ts
|
|
4
|
+
var d = class e extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(t, n) {
|
|
7
|
+
super(t), this.code = n, this.name = "HttpAdapterError", Object.setPrototypeOf(this, e.prototype);
|
|
8
|
+
}
|
|
9
|
+
}, f = class e extends d {
|
|
10
|
+
field;
|
|
11
|
+
value;
|
|
12
|
+
constructor(t, n, r) {
|
|
13
|
+
super(t, "CONFIG_ERROR"), this.field = n, this.value = r, this.name = "HttpConfigError", Object.setPrototypeOf(this, e.prototype);
|
|
14
|
+
}
|
|
15
|
+
}, p = class e extends d {
|
|
16
|
+
operation;
|
|
17
|
+
constructor(t) {
|
|
18
|
+
super(`HTTP adapter does not support changelog operation "${t}" (v1 has no Full-sync)`, "CHANGELOG_UNSUPPORTED"), this.operation = t, this.name = "HttpChangelogUnsupportedError", Object.setPrototypeOf(this, e.prototype);
|
|
19
|
+
}
|
|
20
|
+
}, m = class e extends d {
|
|
21
|
+
entity;
|
|
22
|
+
property;
|
|
23
|
+
propertyType;
|
|
24
|
+
constructor(t, n, r) {
|
|
25
|
+
super(`HTTP adapter has no wire codec for property type "${r}" at "${t}.${n}"`, "UNSUPPORTED_WIRE_TYPE"), this.entity = t, this.property = n, this.propertyType = r, this.name = "HttpUnsupportedWireTypeError", Object.setPrototypeOf(this, e.prototype);
|
|
26
|
+
}
|
|
27
|
+
}, h = class e extends d {
|
|
28
|
+
operation;
|
|
29
|
+
reason;
|
|
30
|
+
constructor(t, n = "v1 supports SyncType.QueryCache only") {
|
|
31
|
+
super(`HTTP adapter does not support "${t}": ${n}`, "UNSUPPORTED_OPERATION"), this.operation = t, this.reason = n, this.name = "HttpUnsupportedOperationError", Object.setPrototypeOf(this, e.prototype);
|
|
32
|
+
}
|
|
33
|
+
}, g = class e extends d {
|
|
34
|
+
handler;
|
|
35
|
+
entityName;
|
|
36
|
+
constructor(t, n, r) {
|
|
37
|
+
super(`${t} handler for "${n}" returned an unexpected shape: ${r}`, "HANDLER_CONTRACT"), this.handler = t, this.entityName = n, this.name = "HttpHandlerContractError", Object.setPrototypeOf(this, e.prototype);
|
|
38
|
+
}
|
|
39
|
+
}, _ = class e extends d {
|
|
40
|
+
reason;
|
|
41
|
+
constructor(t, n) {
|
|
42
|
+
super(n, "PAGINATION_ERROR"), this.reason = t, this.name = "HttpPaginationError", Object.setPrototypeOf(this, e.prototype);
|
|
43
|
+
}
|
|
44
|
+
}, v = class e extends d {
|
|
45
|
+
entityName;
|
|
46
|
+
detail;
|
|
47
|
+
constructor(t, n) {
|
|
48
|
+
super(`HTTP adapter received invalid metadata for "${t}": ${n}`, "INVALID_METADATA"), this.entityName = t, this.detail = n, this.name = "HttpInvalidMetadataError", Object.setPrototypeOf(this, e.prototype);
|
|
49
|
+
}
|
|
50
|
+
}, y = class e extends d {
|
|
51
|
+
operation;
|
|
52
|
+
constructor(t) {
|
|
53
|
+
super(`HTTP adapter is disconnected; "${t}" was cancelled or rejected`, "DISCONNECTED"), this.operation = t, this.name = "HttpDisconnectedError", Object.setPrototypeOf(this, e.prototype);
|
|
54
|
+
}
|
|
55
|
+
}, b = class e extends d {
|
|
56
|
+
status;
|
|
57
|
+
url;
|
|
58
|
+
detail;
|
|
59
|
+
constructor(t, n, r) {
|
|
60
|
+
super(`HTTP ${t} from ${n} returned a non-JSON body: ${r}`, "INVALID_RESPONSE"), this.status = t, this.url = n, this.detail = r, this.name = "HttpInvalidResponseError", Object.setPrototypeOf(this, e.prototype);
|
|
61
|
+
}
|
|
62
|
+
}, x = class e extends d {
|
|
63
|
+
reason;
|
|
64
|
+
operation;
|
|
65
|
+
constructor(t, n, r) {
|
|
66
|
+
super(`HTTP request for "${n}" could not be built (${t}): ${r}`, "REQUEST_BUILD_ERROR"), this.reason = t, this.operation = n, this.name = "HttpRequestBuildError", Object.setPrototypeOf(this, e.prototype);
|
|
67
|
+
}
|
|
68
|
+
}, S = class e extends d {
|
|
69
|
+
status;
|
|
70
|
+
url;
|
|
71
|
+
body;
|
|
72
|
+
constructor(t, n, r) {
|
|
73
|
+
super(`HTTP ${t} from ${n}`, "HTTP_RESPONSE_ERROR"), this.status = t, this.url = n, this.body = r, this.name = "HttpResponseError", Object.setPrototypeOf(this, e.prototype);
|
|
74
|
+
}
|
|
75
|
+
}, C = {
|
|
76
|
+
pageSize: 1e3,
|
|
77
|
+
idChunkSize: 100,
|
|
78
|
+
maxEmptyPages: 3,
|
|
79
|
+
maxPages: 1e3,
|
|
80
|
+
requestTimeoutMs: 3e4,
|
|
81
|
+
conditionalCacheSize: 256
|
|
82
|
+
}, w = /* @__PURE__ */ new Set(["maxEmptyPages"]), ee = (e, t) => {
|
|
83
|
+
let n = +!w.has(e);
|
|
84
|
+
if (!Number.isInteger(t) || t < n) throw new f(`HTTP adapter config "${e}" must be a finite integer >= ${n}, received ${String(t)}`, e, t);
|
|
85
|
+
}, te = (e) => {
|
|
86
|
+
let t = {};
|
|
87
|
+
for (let n of Object.keys(C)) {
|
|
88
|
+
let r = e[n] ?? C[n];
|
|
89
|
+
ee(n, r), t[n] = r;
|
|
90
|
+
}
|
|
91
|
+
return t;
|
|
92
|
+
}, T = ["entity"], E = {
|
|
93
|
+
fetchMetadata: {
|
|
94
|
+
method: "POST",
|
|
95
|
+
path: ":entity/metadata",
|
|
96
|
+
placeholders: T,
|
|
97
|
+
closable: !1,
|
|
98
|
+
carriesBody: !0
|
|
99
|
+
},
|
|
100
|
+
findByIds: {
|
|
101
|
+
method: "POST",
|
|
102
|
+
path: ":entity/by-ids",
|
|
103
|
+
placeholders: T,
|
|
104
|
+
closable: !1,
|
|
105
|
+
carriesBody: !0
|
|
106
|
+
},
|
|
107
|
+
create: {
|
|
108
|
+
method: "POST",
|
|
109
|
+
path: ":entity",
|
|
110
|
+
placeholders: T,
|
|
111
|
+
closable: !0,
|
|
112
|
+
carriesBody: !0
|
|
113
|
+
},
|
|
114
|
+
update: {
|
|
115
|
+
method: "PATCH",
|
|
116
|
+
path: ":entity/:id",
|
|
117
|
+
placeholders: ["entity", "id"],
|
|
118
|
+
closable: !0,
|
|
119
|
+
carriesBody: !0
|
|
120
|
+
},
|
|
121
|
+
delete: {
|
|
122
|
+
method: "POST",
|
|
123
|
+
path: ":entity/delete",
|
|
124
|
+
placeholders: T,
|
|
125
|
+
closable: !0,
|
|
126
|
+
carriesBody: !0
|
|
127
|
+
},
|
|
128
|
+
version: {
|
|
129
|
+
method: "GET",
|
|
130
|
+
placeholders: [],
|
|
131
|
+
closable: !0,
|
|
132
|
+
carriesBody: !1
|
|
133
|
+
},
|
|
134
|
+
isTableExisted: {
|
|
135
|
+
method: "HEAD",
|
|
136
|
+
placeholders: T,
|
|
137
|
+
closable: !0,
|
|
138
|
+
carriesBody: !1
|
|
139
|
+
}
|
|
140
|
+
}, D = /* @__PURE__ */ new Set([
|
|
141
|
+
"GET",
|
|
142
|
+
"HEAD",
|
|
143
|
+
"POST",
|
|
144
|
+
"PUT",
|
|
145
|
+
"PATCH",
|
|
146
|
+
"DELETE"
|
|
147
|
+
]), ne = /* @__PURE__ */ new Set(["GET", "HEAD"]), O = /:([a-zA-Z][a-zA-Z0-9_]*)/g, k = /[\s?#]/, re = "(server version)", ie = (e) => typeof e == "object" && !!e && !Array.isArray(e), ae = (e) => [...e.matchAll(O)].map((e) => e[1]), oe = (e, t, n) => {
|
|
148
|
+
let r = `templates.${e}`;
|
|
149
|
+
if (typeof t.path != "string" || t.path.trim().length === 0) throw new f(`REST template "${r}.path" must be a non-empty string, received ${JSON.stringify(t.path)}`, `${r}.path`, t.path);
|
|
150
|
+
if (k.test(t.path)) throw new f(`REST template "${r}.path" must not contain whitespace, "?" or "#", received "${t.path}"`, `${r}.path`, t.path);
|
|
151
|
+
if (t.method !== void 0 && !D.has(t.method)) throw new f(`REST template "${r}.method" must be one of ${[...D].join(" / ")}, received ${JSON.stringify(t.method)}`, `${r}.method`, t.method);
|
|
152
|
+
if (n.carriesBody && t.method !== void 0 && ne.has(t.method)) throw new f(`REST template "${r}.method" cannot be "${t.method}": the "${e}" handler always sends a request body, and ${t.method} requests cannot carry a body`, `${r}.method`, t.method);
|
|
153
|
+
let i = new Set(ae(t.path)), a = new Set(n.placeholders), o = [...a].filter((e) => !i.has(e)), s = [...i].filter((e) => !a.has(e));
|
|
154
|
+
if (o.length === 0 && s.length === 0) return;
|
|
155
|
+
let c = [o.length > 0 ? `missing ${o.map((e) => `":${e}"`).join(", ")}` : void 0, s.length > 0 ? `unexpected ${s.map((e) => `":${e}"`).join(", ")}` : void 0].filter(Boolean).join("; ");
|
|
156
|
+
throw new f(`REST template "${r}.path" must use exactly ${a.size === 0 ? "no placeholder" : [...a].map((e) => `":${e}"`).join(" and ")} — ${c} in "${t.path}"`, `${r}.path`, t.path);
|
|
157
|
+
}, se = (e) => {
|
|
158
|
+
let t = {};
|
|
159
|
+
for (let n of Object.keys(E)) {
|
|
160
|
+
let r = E[n], i = e?.[n];
|
|
161
|
+
if (i === null) {
|
|
162
|
+
if (!r.closable) throw new f(`REST template "templates.${n}" cannot be disabled: it backs a required RxDBAdapterRemoteBase member`, `templates.${n}`, i);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
let a = i?.path ?? r.path;
|
|
166
|
+
if (a === void 0) continue;
|
|
167
|
+
let o = {
|
|
168
|
+
path: a,
|
|
169
|
+
method: i?.method ?? r.method
|
|
170
|
+
};
|
|
171
|
+
oe(n, o, r), t[n] = o;
|
|
172
|
+
}
|
|
173
|
+
return t;
|
|
174
|
+
}, ce = (e) => {
|
|
175
|
+
for (let [t, n] of Object.entries(e ?? {})) if (typeof n != "string" || n.trim().length === 0 || k.test(n)) throw new f(`REST resource mapping "resources.${t}" must be a non-empty path fragment without whitespace, "?" or "#", received ${JSON.stringify(n)}`, `resources.${t}`, n);
|
|
176
|
+
return e;
|
|
177
|
+
}, A = (e, t) => {
|
|
178
|
+
let n = e?.[t];
|
|
179
|
+
if (n !== void 0) return n;
|
|
180
|
+
if (k.test(t) || t.includes("/")) throw new f(`REST templates cannot use entity name "${t}" as a path fragment; add an explicit "resources.${t}" mapping`, `resources.${t}`, void 0);
|
|
181
|
+
return t;
|
|
182
|
+
}, le = (e, t, n) => {
|
|
183
|
+
if (typeof n != "string" || n.length === 0) throw new x("id", e, `REST templates require a non-empty string id for "${t}", received ${JSON.stringify(n) ?? typeof n}`);
|
|
184
|
+
return encodeURIComponent(n);
|
|
185
|
+
}, j = (e, t, n) => ({
|
|
186
|
+
url: t.path.replace(O, (r, i) => {
|
|
187
|
+
let a = n[i];
|
|
188
|
+
if (a === void 0) throw new f(`REST template "templates.${e}.path" has no value for placeholder ":${i}"`, `templates.${e}.path`, t.path);
|
|
189
|
+
return a;
|
|
190
|
+
}),
|
|
191
|
+
method: t.method
|
|
192
|
+
}), ue = (e = {}) => {
|
|
193
|
+
let t = ce(e.resources), n = se(e.templates), r = (e, n, r) => j(e, n, { entity: A(t, r) }), i = n.fetchMetadata, a = n.findByIds, o = {
|
|
194
|
+
onFetchMetadata: {
|
|
195
|
+
request: (e) => ({
|
|
196
|
+
...r("fetchMetadata", i, e.entityName),
|
|
197
|
+
body: {
|
|
198
|
+
where: e.where,
|
|
199
|
+
offset: e.offset,
|
|
200
|
+
limit: e.limit,
|
|
201
|
+
pageToken: e.pageToken
|
|
202
|
+
}
|
|
203
|
+
}),
|
|
204
|
+
parse: (e) => e
|
|
205
|
+
},
|
|
206
|
+
onFindByIds: {
|
|
207
|
+
request: (e) => ({
|
|
208
|
+
...r("findByIds", a, e.entityName),
|
|
209
|
+
body: { ids: e.ids }
|
|
210
|
+
}),
|
|
211
|
+
parse: (e) => e
|
|
212
|
+
}
|
|
213
|
+
}, { create: s, update: c, delete: l, version: u, isTableExisted: d } = n;
|
|
214
|
+
return s && (o.onCreate = {
|
|
215
|
+
request: (e) => ({
|
|
216
|
+
...r("create", s, e.entityName),
|
|
217
|
+
body: e.data
|
|
218
|
+
}),
|
|
219
|
+
parse: (e) => e
|
|
220
|
+
}), c && (o.onUpdate = {
|
|
221
|
+
request: (e) => ({
|
|
222
|
+
...j("update", c, {
|
|
223
|
+
entity: A(t, e.entityName),
|
|
224
|
+
id: le("update", e.entityName, e.id)
|
|
225
|
+
}),
|
|
226
|
+
body: e.data
|
|
227
|
+
}),
|
|
228
|
+
parse: (e) => e
|
|
229
|
+
}), l && (o.onDelete = { request: (e) => ({
|
|
230
|
+
...r("delete", l, e.entityName),
|
|
231
|
+
body: { ids: e.ids }
|
|
232
|
+
}) }), u && (o.onVersion = {
|
|
233
|
+
request: () => j("version", u, {}),
|
|
234
|
+
parse: (e) => {
|
|
235
|
+
if (typeof e == "string") return e;
|
|
236
|
+
if (ie(e) && typeof e.version == "string") return e.version;
|
|
237
|
+
throw new g("version", re, `expected a version string or { version: string }, received ${JSON.stringify(e)}`);
|
|
238
|
+
}
|
|
239
|
+
}), d && (o.onIsTableExisted = { request: (e) => r("isTableExisted", d, e.entityName) }), o;
|
|
240
|
+
}, de = 0, fe = "public", pe = 1e3, M = 3e4, N = 3, P = class {
|
|
241
|
+
#e;
|
|
242
|
+
#t;
|
|
243
|
+
#n;
|
|
244
|
+
#r;
|
|
245
|
+
#i;
|
|
246
|
+
#a = 0;
|
|
247
|
+
#o = !0;
|
|
248
|
+
#s;
|
|
249
|
+
constructor(e) {
|
|
250
|
+
if (this.#e = e, z(e.url), this.#t = L(e.options.reconnectBaseDelayMs, "reconnectBaseDelayMs"), this.#n = L(e.options.reconnectMaxDelayMs, "reconnectMaxDelayMs", M), this.#n < this.#t) throw new f(`HTTP adapter config "changeFeed.reconnectMaxDelayMs" must be >= "changeFeed.reconnectBaseDelayMs" (${this.#t}), received ${this.#n}`, "changeFeed.reconnectMaxDelayMs", this.#n);
|
|
251
|
+
}
|
|
252
|
+
start() {
|
|
253
|
+
this.#o = !1, this.#a = 0, this.#m(), this.#c();
|
|
254
|
+
}
|
|
255
|
+
stop() {
|
|
256
|
+
this.#o = !0, this.#m(), this.#h();
|
|
257
|
+
}
|
|
258
|
+
#c() {
|
|
259
|
+
this.#h();
|
|
260
|
+
let e = globalThis.EventSource;
|
|
261
|
+
if (typeof e != "function") {
|
|
262
|
+
this.#g({
|
|
263
|
+
reason: "unsupported-runtime",
|
|
264
|
+
attempt: 0,
|
|
265
|
+
message: `change feed is enabled but this runtime has no global "EventSource"; no connection will be attempted for ${this.#e.url}`
|
|
266
|
+
});
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
let t = new e(this.#e.url, { withCredentials: this.#e.options.withCredentials === !0 });
|
|
271
|
+
t.onopen = this.#v, t.onmessage = this.#y, t.onerror = this.#b, this.#r = t;
|
|
272
|
+
} catch (e) {
|
|
273
|
+
this.#u(void 0, e instanceof Error ? e.message : String(e));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
#l() {
|
|
277
|
+
for (let e of this.#e.entities()) this.#e.invalidate(e.name, e.namespace);
|
|
278
|
+
}
|
|
279
|
+
#u(e, t) {
|
|
280
|
+
this.#d() && (this.#a = 0), this.#s = void 0, this.#a++;
|
|
281
|
+
let n = e === de && this.#a <= N ? void 0 : this.#f();
|
|
282
|
+
this.#g({
|
|
283
|
+
reason: "connection-error",
|
|
284
|
+
attempt: this.#a,
|
|
285
|
+
readyState: e,
|
|
286
|
+
retryInMs: n,
|
|
287
|
+
message: `change feed connection to ${this.#e.url} failed (${t}); EventSource does not expose the status code, so the cause may be an unimplemented endpoint, an authentication failure, or a network error`
|
|
288
|
+
}), n !== void 0 && (this.#h(), this.#p(n));
|
|
289
|
+
}
|
|
290
|
+
#d() {
|
|
291
|
+
return this.#s !== void 0 && Date.now() - this.#s >= this.#t;
|
|
292
|
+
}
|
|
293
|
+
#f() {
|
|
294
|
+
return Math.min(this.#t * 2 ** (this.#a - 1), this.#n);
|
|
295
|
+
}
|
|
296
|
+
#p(e) {
|
|
297
|
+
this.#m(), this.#i = setTimeout(() => {
|
|
298
|
+
this.#i = void 0, this.#c();
|
|
299
|
+
}, e);
|
|
300
|
+
}
|
|
301
|
+
#m() {
|
|
302
|
+
this.#i !== void 0 && (clearTimeout(this.#i), this.#i = void 0);
|
|
303
|
+
}
|
|
304
|
+
#h() {
|
|
305
|
+
let e = this.#r;
|
|
306
|
+
e !== void 0 && (this.#r = void 0, e.onopen = null, e.onmessage = null, e.onerror = null, e.close());
|
|
307
|
+
}
|
|
308
|
+
#g(e) {
|
|
309
|
+
let t = this.#e.options.onUnavailable;
|
|
310
|
+
if (t) try {
|
|
311
|
+
t({
|
|
312
|
+
...e,
|
|
313
|
+
url: this.#e.url
|
|
314
|
+
});
|
|
315
|
+
} catch {}
|
|
316
|
+
}
|
|
317
|
+
#_(e, t) {
|
|
318
|
+
let n = this.#e.options.onNotification;
|
|
319
|
+
if (n) try {
|
|
320
|
+
n({
|
|
321
|
+
url: this.#e.url,
|
|
322
|
+
entity: e.entity,
|
|
323
|
+
namespace: e.namespace,
|
|
324
|
+
clientId: e.clientId,
|
|
325
|
+
suppressed: t
|
|
326
|
+
});
|
|
327
|
+
} catch {}
|
|
328
|
+
}
|
|
329
|
+
#v = () => {
|
|
330
|
+
this.#s = Date.now(), this.#l();
|
|
331
|
+
};
|
|
332
|
+
#y = (e) => {
|
|
333
|
+
if (this.#o) return;
|
|
334
|
+
let t = F(e.data);
|
|
335
|
+
if (t === void 0) {
|
|
336
|
+
this.#g({
|
|
337
|
+
reason: "malformed-message",
|
|
338
|
+
attempt: this.#a,
|
|
339
|
+
data: typeof e.data == "string" ? e.data : void 0,
|
|
340
|
+
message: `change feed message from ${this.#e.url} carries no usable entity name; expected JSON like {"entity":"Recipe"}`
|
|
341
|
+
});
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
let n = t.clientId !== void 0 && t.clientId === this.#e.clientId();
|
|
345
|
+
this.#_(t, n), !n && this.#e.invalidate(t.entity, t.namespace);
|
|
346
|
+
};
|
|
347
|
+
#b = () => {
|
|
348
|
+
if (this.#o) return;
|
|
349
|
+
let e = this.#r?.readyState;
|
|
350
|
+
this.#u(e, `readyState=${String(e)}`);
|
|
351
|
+
};
|
|
352
|
+
}, F = (e) => {
|
|
353
|
+
if (typeof e != "string") return;
|
|
354
|
+
let t = I(e);
|
|
355
|
+
if (typeof t != "object" || !t) return;
|
|
356
|
+
let n = t, r = n.entity;
|
|
357
|
+
if (typeof r != "string" || r.length === 0) return;
|
|
358
|
+
let i = n.namespace, a = n.clientId;
|
|
359
|
+
return {
|
|
360
|
+
entity: r,
|
|
361
|
+
namespace: typeof i == "string" && i.length > 0 ? i : fe,
|
|
362
|
+
clientId: typeof a == "string" ? a : void 0
|
|
363
|
+
};
|
|
364
|
+
}, I = (e) => {
|
|
365
|
+
try {
|
|
366
|
+
return JSON.parse(e);
|
|
367
|
+
} catch {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
}, L = (e, t, n = pe) => {
|
|
371
|
+
let r = e ?? n;
|
|
372
|
+
if (!Number.isInteger(r) || r < 1) throw new f(`HTTP adapter config "changeFeed.${t}" must be a finite integer >= 1, received ${String(r)}`, `changeFeed.${t}`, r);
|
|
373
|
+
return r;
|
|
374
|
+
}, R = (e) => {
|
|
375
|
+
if (typeof e != "string" || e.trim().length === 0) throw new f("HTTP adapter config \"changeFeed.url\" must be a non-empty string", "changeFeed.url", e);
|
|
376
|
+
}, z = (e) => {
|
|
377
|
+
if (!URL.canParse(e)) throw new f(`HTTP adapter config "changeFeed.url" resolves to "${e}", which is not a parsable URL`, "changeFeed.url", e);
|
|
378
|
+
}, B = (e, t) => {
|
|
379
|
+
let n = [];
|
|
380
|
+
for (let r = 0; r < e.length; r += t) n.push(e.slice(r, r + t));
|
|
381
|
+
return n;
|
|
382
|
+
}, me = async (e, t) => {
|
|
383
|
+
let { transport: n, handler: r, config: i } = e, a = [];
|
|
384
|
+
for (let e of B(t.ids, i.idChunkSize)) {
|
|
385
|
+
let i = {
|
|
386
|
+
entityName: t.entityName,
|
|
387
|
+
ids: e
|
|
388
|
+
}, o = await n.sendJson(r.request(i), "findByIds", t.entityName), s = r.parse(o, i);
|
|
389
|
+
if (!Array.isArray(s)) throw new g("findByIds", t.entityName, `expected an array of rows, received ${typeof s}`);
|
|
390
|
+
a.push(...s);
|
|
391
|
+
}
|
|
392
|
+
return a;
|
|
393
|
+
}, he = (e) => typeof e == "object" && !!e && !Array.isArray(e), V = (e, t, n) => {
|
|
394
|
+
if (!he(n)) throw new g(e, t, `expected the persisted row object, received ${JSON.stringify(n) ?? typeof n}`);
|
|
395
|
+
return n;
|
|
396
|
+
}, ge = "(server version)", _e = (e) => {
|
|
397
|
+
if (typeof e != "string" || e.trim() === "") throw new g("version", ge, `expected a non-empty version string, received ${JSON.stringify(e) ?? typeof e}`);
|
|
398
|
+
return e;
|
|
399
|
+
}, ve = /^\d{4}-\d{2}-\d{2}[Tt]\d{2}:\d{2}(:\d{2}(\.\d+)?)?([Zz]|[+-]\d{2}:\d{2})$/, ye = (e) => typeof e == "object" && !!e, be = (e, t, n) => {
|
|
400
|
+
if (typeof n != "string") throw new v(e, `row "${t}" has updatedAt of type ${typeof n}, expected an ISO 8601 string`);
|
|
401
|
+
if (!ve.test(n)) throw new v(e, `row "${t}" has updatedAt "${n}", expected ISO 8601 with an explicit time zone`);
|
|
402
|
+
let r = new Date(n);
|
|
403
|
+
if (Number.isNaN(r.getTime())) throw new v(e, `row "${t}" has updatedAt "${n}", which is not a real instant`);
|
|
404
|
+
return r.toISOString();
|
|
405
|
+
}, xe = (e, t) => {
|
|
406
|
+
let { id: n } = t;
|
|
407
|
+
if (typeof n != "string" || n.length === 0) throw new v(e, `row has id ${JSON.stringify(n)}, expected a non-empty string`);
|
|
408
|
+
return n;
|
|
409
|
+
}, Se = (e, t) => {
|
|
410
|
+
if (!Array.isArray(t)) throw new v(e, `expected an array of metadata rows, received ${typeof t}`);
|
|
411
|
+
return t.map((t) => {
|
|
412
|
+
if (!ye(t)) throw new v(e, `expected a metadata object, received ${JSON.stringify(t)}`);
|
|
413
|
+
let n = xe(e, t);
|
|
414
|
+
return {
|
|
415
|
+
id: n,
|
|
416
|
+
updatedAt: be(e, n, t.updatedAt)
|
|
417
|
+
};
|
|
418
|
+
});
|
|
419
|
+
}, Ce = (e, t) => {
|
|
420
|
+
if (Array.isArray(t)) return {
|
|
421
|
+
shape: "offset",
|
|
422
|
+
rows: t
|
|
423
|
+
};
|
|
424
|
+
let n = t;
|
|
425
|
+
if (!n || !Array.isArray(n.rows)) throw new g("fetchMetadata", e, `expected an array of rows or { rows, nextPageToken }, received ${JSON.stringify(t)}`);
|
|
426
|
+
if (n.nextPageToken === void 0 && n.nextCursor !== void 0) throw new g("fetchMetadata", e, "returned the removed key \"nextCursor\"; rename it to \"nextPageToken\" (reading it as undefined would end pagination at the first page)");
|
|
427
|
+
if (n.nextPageToken !== void 0 && typeof n.nextPageToken != "string") throw new g("fetchMetadata", e, `expected "nextPageToken" to be a string or undefined, received ${JSON.stringify(n.nextPageToken)}`);
|
|
428
|
+
return {
|
|
429
|
+
shape: "token",
|
|
430
|
+
rows: n.rows,
|
|
431
|
+
nextPageToken: n.nextPageToken
|
|
432
|
+
};
|
|
433
|
+
}, we = async (e, t) => {
|
|
434
|
+
let { transport: n, handler: r, config: i } = e, a = [], o, s = 0, c, l = 0;
|
|
435
|
+
for (let e = 1;; e++) {
|
|
436
|
+
if (e > i.maxPages) throw new _("max_pages", `fetchMetadata for "${t.entityName}" exceeded maxPages=${i.maxPages}; refusing to return a truncated result`);
|
|
437
|
+
let u = {
|
|
438
|
+
...t,
|
|
439
|
+
offset: s,
|
|
440
|
+
limit: i.pageSize,
|
|
441
|
+
pageToken: c
|
|
442
|
+
}, d = await n.sendJson(r.request(u), "fetchMetadata", t.entityName), f = Ce(t.entityName, r.parse(d, u));
|
|
443
|
+
if (o && f.shape !== o) throw new _("shape_switch", `fetchMetadata for "${t.entityName}" started in ${o} mode but page ${e} returned ${f.shape} mode`);
|
|
444
|
+
if (o = f.shape, a.push(...Se(t.entityName, f.rows)), o === "offset") {
|
|
445
|
+
if (f.rows.length < i.pageSize) return a;
|
|
446
|
+
s += f.rows.length;
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
if (f.nextPageToken === void 0) return a;
|
|
450
|
+
if (f.nextPageToken === c) throw new _("page_token_not_advancing", `fetchMetadata for "${t.entityName}" received the same nextPageToken "${c}" twice; refusing to loop forever`);
|
|
451
|
+
l = Te(t.entityName, f.rows.length, l, i.maxEmptyPages), c = f.nextPageToken;
|
|
452
|
+
}
|
|
453
|
+
}, Te = (e, t, n, r) => {
|
|
454
|
+
if (t > 0) return 0;
|
|
455
|
+
let i = n + 1;
|
|
456
|
+
if (i > r) throw new _("empty_page_limit", `fetchMetadata for "${e}" received ${i} consecutive empty pages (maxEmptyPages=${r}); the remote is spinning`);
|
|
457
|
+
return i;
|
|
458
|
+
}, H = (e) => structuredClone(e), Ee = (e) => {
|
|
459
|
+
let t = Object.entries(e ?? {});
|
|
460
|
+
return t.sort(([e], [t]) => e < t ? -1 : 1), t;
|
|
461
|
+
}, De = (e, t, n, r) => JSON.stringify([
|
|
462
|
+
e,
|
|
463
|
+
t,
|
|
464
|
+
n ?? null,
|
|
465
|
+
Ee(r)
|
|
466
|
+
]), Oe = class {
|
|
467
|
+
maxEntries;
|
|
468
|
+
#e = /* @__PURE__ */ new Map();
|
|
469
|
+
#t = /* @__PURE__ */ new Map();
|
|
470
|
+
#n = /* @__PURE__ */ new Set();
|
|
471
|
+
get size() {
|
|
472
|
+
return this.#e.size;
|
|
473
|
+
}
|
|
474
|
+
constructor(e) {
|
|
475
|
+
this.maxEntries = e;
|
|
476
|
+
}
|
|
477
|
+
get(e) {
|
|
478
|
+
let t = this.#e.get(e);
|
|
479
|
+
if (t) return this.#e.delete(e), this.#e.set(e, t), {
|
|
480
|
+
etag: t.etag,
|
|
481
|
+
takeValue: () => H(t.value)
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
set(e, t) {
|
|
485
|
+
this.#e.delete(e), this.#e.set(e, {
|
|
486
|
+
etag: t.etag,
|
|
487
|
+
value: H(t.value)
|
|
488
|
+
});
|
|
489
|
+
for (let e of this.#e.keys()) {
|
|
490
|
+
if (this.#e.size <= this.maxEntries) break;
|
|
491
|
+
this.#e.delete(e);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
delete(e) {
|
|
495
|
+
this.#e.delete(e);
|
|
496
|
+
}
|
|
497
|
+
markEtagUnreadable(e) {
|
|
498
|
+
if (this.#n.has(e)) return !1;
|
|
499
|
+
this.#n.add(e);
|
|
500
|
+
for (let e of this.#n) {
|
|
501
|
+
if (this.#n.size <= this.maxEntries) break;
|
|
502
|
+
this.#n.delete(e);
|
|
503
|
+
}
|
|
504
|
+
return !0;
|
|
505
|
+
}
|
|
506
|
+
clear() {
|
|
507
|
+
this.#e.clear(), this.#n.clear();
|
|
508
|
+
}
|
|
509
|
+
async singleFlight(e, t) {
|
|
510
|
+
let n = this.#t.get(e);
|
|
511
|
+
if (n) return H(await n);
|
|
512
|
+
let r = t().finally(() => this.#t.delete(e));
|
|
513
|
+
return this.#t.set(e, r), r;
|
|
514
|
+
}
|
|
515
|
+
}, ke = /* @__PURE__ */ new Set(["fetchMetadata", "findByIds"]), Ae = (e) => `${e.entityName === void 0 ? e.operation : `${e.entityName} ${e.operation}`}: conditionalRequests is enabled, but no ETag is readable on this 200 response (${e.url}, Response.type=${e.responseType}); neither this request nor later ones with the same fingerprint will send If-None-Match. Two possibilities, indistinguishable from the client: (1) the server did not send an ETag; (2) the server sent one, but a cross-origin response did not list it in Access-Control-Expose-Headers. A cross-origin response reports Response.type 'cors' in the browser, which is a clue; if your server logs show an ETag that is unreadable here, check (2) first.`, U = (e, t) => /^https?:\/\//i.test(t) ? t : `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}`, W = (e) => e instanceof Error ? e.message : String(e), G = async (e) => {
|
|
516
|
+
await e.body?.cancel().catch(() => void 0);
|
|
517
|
+
}, K = async (e, t) => {
|
|
518
|
+
try {
|
|
519
|
+
return await e.text();
|
|
520
|
+
} catch (e) {
|
|
521
|
+
if (t.aborted) throw e;
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
}, q = async (e, t, n) => {
|
|
525
|
+
if (!e.ok) throw new S(e.status, t, await K(e, n));
|
|
526
|
+
}, je = (e, t) => {
|
|
527
|
+
if (e === void 0) return;
|
|
528
|
+
let n;
|
|
529
|
+
try {
|
|
530
|
+
n = JSON.stringify(e);
|
|
531
|
+
} catch (e) {
|
|
532
|
+
throw new x("body", t, W(e));
|
|
533
|
+
}
|
|
534
|
+
if (n === void 0) throw new x("body", t, `JSON.stringify() returned undefined for ${typeof e}`);
|
|
535
|
+
return n;
|
|
536
|
+
}, Me = /* @__PURE__ */ new Set(["GET", "HEAD"]), Ne = (e, t, n) => {
|
|
537
|
+
if (t !== void 0 && Me.has(e.toUpperCase())) throw new x("method", n, `${e.toUpperCase()} requests cannot carry a body`);
|
|
538
|
+
}, Pe = (e, t) => {
|
|
539
|
+
if (!(URL.canParse(e) || globalThis.location !== void 0 && URL.canParse(e, globalThis.location.href))) throw new x("url", t, `"${e}" is not a parsable URL`);
|
|
540
|
+
}, J = (e, t) => {
|
|
541
|
+
for (let [n, r] of Object.entries(t ?? {})) e[n.toLowerCase()] = r;
|
|
542
|
+
return e;
|
|
543
|
+
}, Y = (e, t) => {
|
|
544
|
+
try {
|
|
545
|
+
return Object.fromEntries(new Headers(e));
|
|
546
|
+
} catch (e) {
|
|
547
|
+
throw new x("headers", t, W(e));
|
|
548
|
+
}
|
|
549
|
+
}, X = async (e, t) => {
|
|
550
|
+
let n = await e.text();
|
|
551
|
+
try {
|
|
552
|
+
return JSON.parse(n);
|
|
553
|
+
} catch (n) {
|
|
554
|
+
throw new b(e.status, t, W(n));
|
|
555
|
+
}
|
|
556
|
+
}, Fe = class {
|
|
557
|
+
options;
|
|
558
|
+
#e;
|
|
559
|
+
constructor(e) {
|
|
560
|
+
this.options = e, this.#e = e.conditional && new Oe(e.conditional.maxEntries);
|
|
561
|
+
}
|
|
562
|
+
async sendJson(e, t, n) {
|
|
563
|
+
let r = await this.#t(e, t), i = this.#e;
|
|
564
|
+
if (!i || !ke.has(t)) return this.#r(r, t);
|
|
565
|
+
let a = De(r.method, r.url, r.body, r.variant);
|
|
566
|
+
return i.singleFlight(a, () => this.#i(i, a, r, {
|
|
567
|
+
operation: t,
|
|
568
|
+
entityName: n
|
|
569
|
+
}));
|
|
570
|
+
}
|
|
571
|
+
clearConditionalCache() {
|
|
572
|
+
this.#e?.clear();
|
|
573
|
+
}
|
|
574
|
+
async sendVoid(e, t) {
|
|
575
|
+
await this.execute(e, t, async (t) => {
|
|
576
|
+
await q(t, this.resolveUrl(e), this.options.disconnectSignal), await G(t);
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
resolveUrl(e) {
|
|
580
|
+
return U(this.options.baseUrl, e.url);
|
|
581
|
+
}
|
|
582
|
+
async execute(e, t, n) {
|
|
583
|
+
return this.#n(await this.#t(e, t), t, n);
|
|
584
|
+
}
|
|
585
|
+
async buildHeaders(e) {
|
|
586
|
+
let t = J({}, this.options.headers);
|
|
587
|
+
return e.body !== void 0 && (t["content-type"] = "application/json"), J(t, e.headers), this.options.auth && J(t, await this.options.auth()), t;
|
|
588
|
+
}
|
|
589
|
+
classify(t, n) {
|
|
590
|
+
return t instanceof d ? t : n.timedOut ? new e(/* @__PURE__ */ Error(`HTTP request to ${n.url} exceeded requestTimeoutMs=${this.options.requestTimeoutMs}`)) : this.options.disconnectSignal.aborted ? new y(n.operation) : new e(t instanceof Error ? t : Error(W(t)));
|
|
591
|
+
}
|
|
592
|
+
async #t(e, t) {
|
|
593
|
+
if (this.options.disconnectSignal.aborted) throw new y(t);
|
|
594
|
+
let n = await this.buildHeaders(e), r = U(this.options.baseUrl, e.url), i = je(e.body, t);
|
|
595
|
+
return Pe(r, t), Ne(e.method, i, t), {
|
|
596
|
+
url: r,
|
|
597
|
+
method: e.method,
|
|
598
|
+
headers: Y(n, t),
|
|
599
|
+
variant: J({}, e.headers),
|
|
600
|
+
body: i
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
async #n(e, t, n) {
|
|
604
|
+
let { disconnectSignal: r, requestTimeoutMs: i, reportResult: a } = this.options, o = new AbortController(), s = !1, c = setTimeout(() => {
|
|
605
|
+
s = !0, o.abort();
|
|
606
|
+
}, i), l = AbortSignal.any([r, o.signal]);
|
|
607
|
+
try {
|
|
608
|
+
let t = await n(await fetch(e.url, {
|
|
609
|
+
method: e.method,
|
|
610
|
+
headers: e.headers,
|
|
611
|
+
body: e.body,
|
|
612
|
+
signal: l
|
|
613
|
+
}));
|
|
614
|
+
return a?.(null), t;
|
|
615
|
+
} catch (n) {
|
|
616
|
+
let r = this.classify(n, {
|
|
617
|
+
operation: t,
|
|
618
|
+
url: e.url,
|
|
619
|
+
timedOut: s
|
|
620
|
+
});
|
|
621
|
+
throw a?.(r), r;
|
|
622
|
+
} finally {
|
|
623
|
+
clearTimeout(c);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
async #r(e, t) {
|
|
627
|
+
return this.#n(e, t, async (t) => (await q(t, e.url, this.options.disconnectSignal), X(t, e.url)));
|
|
628
|
+
}
|
|
629
|
+
async #i(e, t, n, r) {
|
|
630
|
+
let i = e.get(t), a = i ? {
|
|
631
|
+
...n,
|
|
632
|
+
headers: {
|
|
633
|
+
...n.headers,
|
|
634
|
+
"if-none-match": i.etag
|
|
635
|
+
}
|
|
636
|
+
} : n;
|
|
637
|
+
return this.#n(a, r.operation, async (a) => i && a.status === 304 ? (await G(a), i.takeValue()) : (await q(a, n.url, this.options.disconnectSignal), this.#a(e, t, n.url, a, r)));
|
|
638
|
+
}
|
|
639
|
+
async #a(e, t, n, r, i) {
|
|
640
|
+
let a = await X(r, n), o = r.headers.get("etag");
|
|
641
|
+
return o === null ? (e.delete(t), this.#o(e, t, n, r, i), a) : (e.set(t, {
|
|
642
|
+
etag: o,
|
|
643
|
+
value: a
|
|
644
|
+
}), a);
|
|
645
|
+
}
|
|
646
|
+
#o(e, t, n, r, i) {
|
|
647
|
+
let a = this.options.conditional?.onEtagUnreadable;
|
|
648
|
+
if (!a || !e.markEtagUnreadable(t)) return;
|
|
649
|
+
let o = {
|
|
650
|
+
operation: i.operation,
|
|
651
|
+
entityName: i.entityName,
|
|
652
|
+
url: n,
|
|
653
|
+
responseType: r.type
|
|
654
|
+
};
|
|
655
|
+
try {
|
|
656
|
+
a({
|
|
657
|
+
...o,
|
|
658
|
+
message: Ae(o)
|
|
659
|
+
});
|
|
660
|
+
} catch {}
|
|
661
|
+
}
|
|
662
|
+
}, Z = "http", Ie = {
|
|
663
|
+
combinator: "and",
|
|
664
|
+
rules: []
|
|
665
|
+
}, Q = /* @__PURE__ */ new Set([t.bigint, t.binary]), Le = class extends n {
|
|
666
|
+
options;
|
|
667
|
+
#e;
|
|
668
|
+
#t;
|
|
669
|
+
#n;
|
|
670
|
+
#r;
|
|
671
|
+
#i;
|
|
672
|
+
#a = !1;
|
|
673
|
+
name = Z;
|
|
674
|
+
config;
|
|
675
|
+
get changeFeedEnabled() {
|
|
676
|
+
return this.#i;
|
|
677
|
+
}
|
|
678
|
+
constructor(e, t) {
|
|
679
|
+
super(e), this.options = t, ze(t.baseUrl), Be(t.handlers), this.config = te(t), this.#e = t.handlers, this.#t = new AbortController(), this.#n = this.#o(), this.#r = this.#s(), this.#i = this.#r !== void 0, this.#f();
|
|
680
|
+
}
|
|
681
|
+
async connect() {
|
|
682
|
+
return this.#p(), this.#t.abort(), this.#t = new AbortController(), this.#n = this.#o(), this.#a = !0, this.#i && this.#r?.start(), this;
|
|
683
|
+
}
|
|
684
|
+
async disconnect() {
|
|
685
|
+
return this.#a = !1, this.#t.abort(), this.#n.clearConditionalCache(), this.#r?.stop(), Promise.resolve();
|
|
686
|
+
}
|
|
687
|
+
startChangeFeed() {
|
|
688
|
+
if (!this.#a) throw new y("startChangeFeed");
|
|
689
|
+
let e = this.#d("startChangeFeed");
|
|
690
|
+
this.#i = !0, e.start();
|
|
691
|
+
}
|
|
692
|
+
stopChangeFeed() {
|
|
693
|
+
let e = this.#d("stopChangeFeed");
|
|
694
|
+
this.#i = !1, e.stop();
|
|
695
|
+
}
|
|
696
|
+
async version() {
|
|
697
|
+
this.#u("version");
|
|
698
|
+
let e = this.#e.onVersion;
|
|
699
|
+
if (!e) throw new h("version", "no \"onVersion\" handler is configured; the adapter must not report its own package version as the backend version");
|
|
700
|
+
let t = await this.#n.sendJson(e.request(), "version");
|
|
701
|
+
return _e(e.parse(t));
|
|
702
|
+
}
|
|
703
|
+
async isTableExisted(e) {
|
|
704
|
+
this.#u("isTableExisted");
|
|
705
|
+
let t = r(e).name, n = this.#e.onIsTableExisted ? this.#e.onIsTableExisted.request({ entityName: t }) : this.#e.onFetchMetadata.request({
|
|
706
|
+
entityName: t,
|
|
707
|
+
where: Ie,
|
|
708
|
+
offset: 0,
|
|
709
|
+
limit: 1
|
|
710
|
+
});
|
|
711
|
+
return this.#n.execute(n, "isTableExisted", async (e) => {
|
|
712
|
+
if (e.ok || e.status === 404) return await e.body?.cancel().catch(() => void 0), e.ok;
|
|
713
|
+
let t = await K(e, this.#t.signal);
|
|
714
|
+
throw new S(e.status, this.#n.resolveUrl(n), t);
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
fetchMetadata(e, t) {
|
|
718
|
+
return s(() => (this.#u("fetchMetadata"), c(we({
|
|
719
|
+
transport: this.#n,
|
|
720
|
+
handler: this.#e.onFetchMetadata,
|
|
721
|
+
config: this.config
|
|
722
|
+
}, {
|
|
723
|
+
entityName: e,
|
|
724
|
+
where: t
|
|
725
|
+
}))));
|
|
726
|
+
}
|
|
727
|
+
findByIds(e, t) {
|
|
728
|
+
return s(() => (this.#u("findByIds"), c(me({
|
|
729
|
+
transport: this.#n,
|
|
730
|
+
handler: this.#e.onFindByIds,
|
|
731
|
+
config: this.config
|
|
732
|
+
}, {
|
|
733
|
+
entityName: e,
|
|
734
|
+
ids: t
|
|
735
|
+
})).pipe(l((e) => e))));
|
|
736
|
+
}
|
|
737
|
+
getRepository() {
|
|
738
|
+
throw new h("getRepository");
|
|
739
|
+
}
|
|
740
|
+
async saveMany() {
|
|
741
|
+
throw new h("saveMany");
|
|
742
|
+
}
|
|
743
|
+
async removeMany() {
|
|
744
|
+
throw new h("removeMany");
|
|
745
|
+
}
|
|
746
|
+
async mutations() {
|
|
747
|
+
throw new h("mutations");
|
|
748
|
+
}
|
|
749
|
+
async pullChanges() {
|
|
750
|
+
throw new p("pullChanges");
|
|
751
|
+
}
|
|
752
|
+
async getChangeCount() {
|
|
753
|
+
throw new p("getChangeCount");
|
|
754
|
+
}
|
|
755
|
+
async mergeChanges() {
|
|
756
|
+
throw new p("mergeChanges");
|
|
757
|
+
}
|
|
758
|
+
#o() {
|
|
759
|
+
return new Fe({
|
|
760
|
+
baseUrl: this.options.baseUrl,
|
|
761
|
+
requestTimeoutMs: this.config.requestTimeoutMs,
|
|
762
|
+
disconnectSignal: this.#t.signal,
|
|
763
|
+
auth: this.options.auth,
|
|
764
|
+
headers: this.options.headers,
|
|
765
|
+
reportResult: (e) => this.rxdb.reachability.report(e),
|
|
766
|
+
conditional: this.options.conditionalRequests === !0 ? {
|
|
767
|
+
maxEntries: this.config.conditionalCacheSize,
|
|
768
|
+
onEtagUnreadable: this.options.onEtagUnreadable
|
|
769
|
+
} : void 0
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
#s() {
|
|
773
|
+
let e = this.options.changeFeed;
|
|
774
|
+
if (e !== void 0) return R(e.url), new P({
|
|
775
|
+
url: this.#n.resolveUrl({
|
|
776
|
+
url: e.url,
|
|
777
|
+
method: "GET"
|
|
778
|
+
}),
|
|
779
|
+
options: e,
|
|
780
|
+
clientId: () => this.rxdb.context.clientId,
|
|
781
|
+
entities: () => this.#c(),
|
|
782
|
+
invalidate: (e, t) => this.rxdb.invalidateRemoteEntity(e, t)
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
#c() {
|
|
786
|
+
let e = [], t = /* @__PURE__ */ new Set();
|
|
787
|
+
for (let n of this.rxdb.config.entities) {
|
|
788
|
+
let i = r(n), a = $(i.name, i.namespace);
|
|
789
|
+
!t.has(a) && this.#l(n, i) && (t.add(a), e.push({
|
|
790
|
+
name: i.name,
|
|
791
|
+
namespace: i.namespace
|
|
792
|
+
}));
|
|
793
|
+
}
|
|
794
|
+
return e;
|
|
795
|
+
}
|
|
796
|
+
#l(e, t) {
|
|
797
|
+
if (o(e)) return !1;
|
|
798
|
+
let n = this.rxdb.config.sync;
|
|
799
|
+
return a(t, n) === "querycache" && i(t, n)?.remote?.adapter === "http";
|
|
800
|
+
}
|
|
801
|
+
#u(e) {
|
|
802
|
+
if (!this.#a) throw new y(e);
|
|
803
|
+
}
|
|
804
|
+
#d(e) {
|
|
805
|
+
let t = this.#r;
|
|
806
|
+
if (!t) throw new h(e, "no \"changeFeed\" is configured; there is no channel to switch on or off");
|
|
807
|
+
return t;
|
|
808
|
+
}
|
|
809
|
+
#f() {
|
|
810
|
+
let { onCreate: e, onUpdate: t, onDelete: n } = this.#e;
|
|
811
|
+
e && (this.create = (t, n) => {
|
|
812
|
+
let r = {
|
|
813
|
+
entityName: t,
|
|
814
|
+
data: n
|
|
815
|
+
};
|
|
816
|
+
return s(() => (this.#u("create"), c(this.#n.sendJson(e.request(r), "create")))).pipe(l((n) => V("create", t, e.parse(n, r))));
|
|
817
|
+
}), t && (this.update = (e, n, r) => {
|
|
818
|
+
let i = {
|
|
819
|
+
entityName: e,
|
|
820
|
+
id: n,
|
|
821
|
+
data: r
|
|
822
|
+
};
|
|
823
|
+
return s(() => (this.#u("update"), c(this.#n.sendJson(t.request(i), "update")))).pipe(l((n) => V("update", e, t.parse(n, i))));
|
|
824
|
+
}), n && (this.delete = (e, t) => s(() => {
|
|
825
|
+
this.#u("delete");
|
|
826
|
+
let r = Array.isArray(t) ? t : [t];
|
|
827
|
+
return r.length === 0 ? u(void 0) : c(this.#n.sendVoid(n.request({
|
|
828
|
+
entityName: e,
|
|
829
|
+
ids: r
|
|
830
|
+
}), "delete"));
|
|
831
|
+
}));
|
|
832
|
+
}
|
|
833
|
+
#p() {
|
|
834
|
+
let e = /* @__PURE__ */ new Map();
|
|
835
|
+
for (let t of this.rxdb.config.entities) {
|
|
836
|
+
let n = r(t);
|
|
837
|
+
e.set($(n.name, n.namespace), n);
|
|
838
|
+
}
|
|
839
|
+
for (let t of e.values()) this.#m(t, e);
|
|
840
|
+
}
|
|
841
|
+
#m(e, t) {
|
|
842
|
+
if (i(e, this.rxdb.config.sync)?.remote?.adapter !== "http") return;
|
|
843
|
+
let n = Re(e, t);
|
|
844
|
+
if (n) throw new m(e.name, n.name, n.type);
|
|
845
|
+
}
|
|
846
|
+
}, $ = (e, t) => `${t}\u0000${e}`, Re = (e, t) => {
|
|
847
|
+
for (let t of e.propertyMap.values()) if (Q.has(t.type)) return {
|
|
848
|
+
name: t.name,
|
|
849
|
+
type: t.type
|
|
850
|
+
};
|
|
851
|
+
for (let [n, r] of e.foreignKeyRelationMap) {
|
|
852
|
+
let i = t.get($(r.mappedEntity, r.mappedNamespace ?? e.namespace))?.propertyMap.get("id")?.type;
|
|
853
|
+
if (i !== void 0 && Q.has(i)) return {
|
|
854
|
+
name: n,
|
|
855
|
+
type: i
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
}, ze = (e) => {
|
|
859
|
+
if (typeof e != "string" || e.trim().length === 0) throw new f("HTTP adapter config \"baseUrl\" must be a non-empty string", "baseUrl", e);
|
|
860
|
+
}, Be = (e) => {
|
|
861
|
+
for (let t of ["onFetchMetadata", "onFindByIds"]) if (!e?.[t]) throw new f(`HTTP adapter config "handlers.${t}" is required`, `handlers.${t}`, e?.[t]);
|
|
862
|
+
};
|
|
863
|
+
//#endregion
|
|
864
|
+
export { Z as ADAPTER_NAME, C as DEFAULT_HTTP_CONFIG, d as HttpAdapterError, p as HttpChangelogUnsupportedError, f as HttpConfigError, y as HttpDisconnectedError, g as HttpHandlerContractError, v as HttpInvalidMetadataError, b as HttpInvalidResponseError, _ as HttpPaginationError, x as HttpRequestBuildError, S as HttpResponseError, h as HttpUnsupportedOperationError, m as HttpUnsupportedWireTypeError, Le as RxDBAdapterHttp, ue as createRestHandlers };
|