@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
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
import { QueryCacheEntityMetadata, RuleGroup } from '@aiao/rxdb';
|
|
2
|
+
/**
|
|
3
|
+
* handler 可以产出的 HTTP 方法。
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* 含 `HEAD` 是为 `isTableExisted` 探测留的:判定只看状态码,拉响应体是白费带宽。
|
|
7
|
+
*/
|
|
8
|
+
export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
9
|
+
/**
|
|
10
|
+
* handler 产出、**适配器执行**的请求描述。
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* auth header 由适配器叠加,不在这里写。
|
|
14
|
+
*/
|
|
15
|
+
export interface HttpRequestSpec {
|
|
16
|
+
/** 绝对 URL,或相对于 `baseUrl` 的路径 */
|
|
17
|
+
url: string;
|
|
18
|
+
method: HttpMethod;
|
|
19
|
+
/** 适配器负责 JSON 序列化 */
|
|
20
|
+
body?: unknown;
|
|
21
|
+
/**
|
|
22
|
+
* 附加 header;与 auth hook 冲突时 **auth hook 优先**。
|
|
23
|
+
*
|
|
24
|
+
* @remarks
|
|
25
|
+
* 开了 {@link HttpAdapterOptions.conditionalRequests} 时,这一组**参与请求指纹**:
|
|
26
|
+
* 在同一条 URL 上按租户 / 语言分投影是安全的,两个投影各占各的缓存条目。
|
|
27
|
+
* 三组 header 里只有它进指纹,另外两组的取舍见 `conditionalRequests`。
|
|
28
|
+
*/
|
|
29
|
+
headers?: Record<string, string>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 单页 `fetchMetadata` 请求的上下文。
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* **这一族类型不带实体类型参数**,`where` / `data` 一律是 `unknown` 侧的形态。
|
|
36
|
+
* 一个适配器实例服务**所有**挂在它 remote 槽位上的实体,单个类型参数只能取成联合类型
|
|
37
|
+
* (`RuleGroup<A | B>` 会把字段收窄到两者的交集,比不写还糟)或 `unknown`;而 core 递进来的
|
|
38
|
+
* 本就是 `RuleGroup<unknown>`,写成 `RuleGroup<T>` 只能靠一次没人验证的 `as` 转换成立——
|
|
39
|
+
* 那是把类型当注释用。需要收窄的接入方在**自己的** handler 里标注参数即可
|
|
40
|
+
* (方法签名双变,`(ctx: FetchMetadataContext) => …` 允许更窄的入参)。
|
|
41
|
+
*/
|
|
42
|
+
export interface FetchMetadataContext {
|
|
43
|
+
entityName: string;
|
|
44
|
+
where: RuleGroup<unknown>;
|
|
45
|
+
/** 本页起始偏移;token 形态可忽略 */
|
|
46
|
+
offset: number;
|
|
47
|
+
/** 来自 `pageSize`,适配器保证为 finite 正整数 */
|
|
48
|
+
limit: number;
|
|
49
|
+
/**
|
|
50
|
+
* 上一页返回的 `nextPageToken`;首页为 `undefined`。
|
|
51
|
+
*
|
|
52
|
+
* @remarks
|
|
53
|
+
* **不透明**:适配器只做「相等 / 不等 / 是否 `undefined`」三种判断,不解析内部结构。
|
|
54
|
+
* 刻意不叫 `cursor`——core 的 `findByCursor` 用「游标」指**实体实例**做的 keyset 锚点,
|
|
55
|
+
* 那种游标会在 Repository 里被编译成 `where` 规则组、可以拆字段比较,适配器根本看不到;
|
|
56
|
+
* 这个只能原样送回远端。同名会让人以为后者也能拆开看。
|
|
57
|
+
*/
|
|
58
|
+
pageToken?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 单页解析结果,两种形态**判别式**返回。
|
|
62
|
+
*
|
|
63
|
+
* @remarks
|
|
64
|
+
* 适配器按**首页的返回形状**锁定本次查询的翻页模式,中途换形态即抛错
|
|
65
|
+
* (`HttpPaginationError`,`reason: 'shape_switch'`)——混用会让两条终止判据互相盖掉,
|
|
66
|
+
* 正是本包要防的静默截断。
|
|
67
|
+
*
|
|
68
|
+
* 对象形态的键叫 `nextPageToken`。返回改名前的 `nextCursor` 会被当场判为契约错误
|
|
69
|
+
* (`HttpHandlerContractError`)而**不是**读成 `undefined`:后者等于首页即末页,
|
|
70
|
+
* 整表只剩第一页而全程不报错。
|
|
71
|
+
*/
|
|
72
|
+
export type FetchMetadataResult =
|
|
73
|
+
/** 形态 1(`offset`):短页终止(`rows.length < limit` 即末页) */
|
|
74
|
+
QueryCacheEntityMetadata[]
|
|
75
|
+
/** 形态 2(`token`):token 终止(`nextPageToken === undefined` 即末页) */
|
|
76
|
+
| {
|
|
77
|
+
rows: QueryCacheEntityMetadata[];
|
|
78
|
+
nextPageToken?: string;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* `fetchMetadata` 的协议 mapping。
|
|
82
|
+
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* offset 形态依赖一条**服务端保证**:返回少于 `limit` 条即最后一页,不得因限流、超时或
|
|
85
|
+
* 服务端 max-rows 提前返回短页;跨页排序稳定;一次查询内快照一致。
|
|
86
|
+
* **任一条不满足的服务端 MUST 用 token 形态**——适配器无法在客户端侧检测短页截断。
|
|
87
|
+
*/
|
|
88
|
+
export interface FetchMetadataHandler {
|
|
89
|
+
/**
|
|
90
|
+
* 产出本页请求描述。纯函数,不碰网络。
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* **必须把翻页位置编码进 URL 或 body**:offset 形态编 `ctx.offset`,token 形态编 `ctx.pageToken`。
|
|
94
|
+
* 适配器只按返回的行数与 token 决定要不要继续翻,无从检查请求里带没带位置——漏掉的表现是
|
|
95
|
+
* 远端每页都回第一页,翻页一直不推进,直到 `maxPages` 触顶抛错,而错误信息指向的是
|
|
96
|
+
* 页数上限,不是漏掉的那个参数。
|
|
97
|
+
*
|
|
98
|
+
* 开了 `conditionalRequests` 会让这个症状更难认:请求指纹取自实际发出的
|
|
99
|
+
* method + URL + body,位置没进去就意味着所有页共用一个指纹,第 2 页起全是 304,
|
|
100
|
+
* 重放的还是第一页。
|
|
101
|
+
*/
|
|
102
|
+
request(ctx: FetchMetadataContext): HttpRequestSpec;
|
|
103
|
+
/** 解析已 JSON 解码的响应体。抛错 = 本次 `fetchMetadata` 失败,不吞不重试 */
|
|
104
|
+
parse(body: unknown, ctx: FetchMetadataContext): FetchMetadataResult;
|
|
105
|
+
}
|
|
106
|
+
/** 单块 `findByIds` 请求的上下文。 */
|
|
107
|
+
export interface FindByIdsContext {
|
|
108
|
+
entityName: string;
|
|
109
|
+
/** 长度 ≤ `idChunkSize` */
|
|
110
|
+
ids: string[];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* `findByIds` 的协议 mapping。
|
|
114
|
+
*
|
|
115
|
+
* @remarks
|
|
116
|
+
* 某块返回的行数**少于**该块 id 数是**合法**结果(远端确实删了),
|
|
117
|
+
* 适配器不会据此重试或补空对象。
|
|
118
|
+
*/
|
|
119
|
+
export interface FindByIdsHandler {
|
|
120
|
+
/** 产出本块请求描述。纯函数,不碰网络 */
|
|
121
|
+
request(ctx: FindByIdsContext): HttpRequestSpec;
|
|
122
|
+
/** 解析已 JSON 解码的响应体 */
|
|
123
|
+
parse(body: unknown, ctx: FindByIdsContext): unknown[];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* `create` 写入口的上下文。
|
|
127
|
+
*
|
|
128
|
+
* @remarks
|
|
129
|
+
* `data` 是 `unknown`:core 的 duck 签名是 `create<R>(entityName, data: R)`,行类型由
|
|
130
|
+
* **每次调用**决定,不由适配器实例决定(理由同 {@link FetchMetadataContext})。
|
|
131
|
+
*/
|
|
132
|
+
export interface CreateContext {
|
|
133
|
+
entityName: string;
|
|
134
|
+
data: unknown;
|
|
135
|
+
}
|
|
136
|
+
/** `update` 写入口的上下文。`data` 是调用方给的部分字段,理由同 {@link CreateContext}。 */
|
|
137
|
+
export interface UpdateContext {
|
|
138
|
+
entityName: string;
|
|
139
|
+
id: string;
|
|
140
|
+
data: unknown;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* `delete` 写入口的上下文。
|
|
144
|
+
*
|
|
145
|
+
* @remarks
|
|
146
|
+
* `ids` 恒为数组:core 的 duck 签名是 `delete(entityName, ids: string | string[])`,
|
|
147
|
+
* 单值那一支由适配器在边界归一,handler 只需处理数组。
|
|
148
|
+
*/
|
|
149
|
+
export interface DeleteContext {
|
|
150
|
+
entityName: string;
|
|
151
|
+
ids: string[];
|
|
152
|
+
}
|
|
153
|
+
/** `create` 的协议 mapping。 */
|
|
154
|
+
export interface CreateHandler {
|
|
155
|
+
request(ctx: CreateContext): HttpRequestSpec;
|
|
156
|
+
/**
|
|
157
|
+
* 解析响应体为**写入后**的完整实体(远端可能补了 id / updatedAt)。
|
|
158
|
+
*
|
|
159
|
+
* @remarks
|
|
160
|
+
* 必须解析远端回执、**不能回显入参**:回执才是落库后的那份,回显会让本地留下一条
|
|
161
|
+
* 远端从不存在的行。时间戳一律由远端定型;id 则可能是客户端给的那个——离线新建的行
|
|
162
|
+
* 带着本地 id 入队,远端采纳它,本地那份才对得上远端。
|
|
163
|
+
*/
|
|
164
|
+
parse(body: unknown, ctx: CreateContext): unknown;
|
|
165
|
+
}
|
|
166
|
+
/** `update` 的协议 mapping。 */
|
|
167
|
+
export interface UpdateHandler {
|
|
168
|
+
request(ctx: UpdateContext): HttpRequestSpec;
|
|
169
|
+
parse(body: unknown, ctx: UpdateContext): unknown;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* `delete` 的协议 mapping。
|
|
173
|
+
*
|
|
174
|
+
* @remarks
|
|
175
|
+
* 没有 `parse`:core 的 duck 返回 `Observable<void>`,响应体无处可去。
|
|
176
|
+
*/
|
|
177
|
+
export interface DeleteHandler {
|
|
178
|
+
request(ctx: DeleteContext): HttpRequestSpec;
|
|
179
|
+
}
|
|
180
|
+
/** `version()` 的协议 mapping。 */
|
|
181
|
+
export interface VersionHandler {
|
|
182
|
+
request(): HttpRequestSpec;
|
|
183
|
+
/** 解析出**远端服务端版本**,与 sqlite / pglite / supabase 三家口径一致 */
|
|
184
|
+
parse(body: unknown): string;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* `isTableExisted()` 的协议 mapping。
|
|
188
|
+
*
|
|
189
|
+
* @remarks
|
|
190
|
+
* 只需给出探测请求:判定完全由适配器按 HTTP 状态码做(2xx → `true`、404 → `false`、
|
|
191
|
+
* 其余与传输失败 → 抛错)。**handler 拿不到 status**,所以这里没有 `parse`——
|
|
192
|
+
* 「不知道」和「不存在」必须区分,而只有 transport 那一层看得见状态码。
|
|
193
|
+
*/
|
|
194
|
+
export interface IsTableExistedHandler {
|
|
195
|
+
request(ctx: {
|
|
196
|
+
entityName: string;
|
|
197
|
+
}): HttpRequestSpec;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* 阶段 A 的 handler 集合。
|
|
201
|
+
*
|
|
202
|
+
* @remarks
|
|
203
|
+
* **命名方向要注意**:handler 字段一律带 `on` 前缀,而**适配器类上的方法名不带**。
|
|
204
|
+
* `fetchMetadata` / `findByIds` 是 `RxDBAdapterRemoteBase` 的 abstract,必须同名;
|
|
205
|
+
* `create` / `update` / `delete` 是 `QueryCacheRemoteAdapter` 的 optional duck,
|
|
206
|
+
* `QueryCacheEngine` 先 `if (!this.remoteAdapter.create)` 特性探测再调用——
|
|
207
|
+
* 把类方法也取成 `onCreate` 会让探测判 `false`,写入口静默退化成「不支持 create」,
|
|
208
|
+
* 而配置里明明配了 handler。
|
|
209
|
+
*/
|
|
210
|
+
export interface HttpHandlers {
|
|
211
|
+
onFetchMetadata: FetchMetadataHandler;
|
|
212
|
+
onFindByIds: FindByIdsHandler;
|
|
213
|
+
onCreate?: CreateHandler;
|
|
214
|
+
onUpdate?: UpdateHandler;
|
|
215
|
+
onDelete?: DeleteHandler;
|
|
216
|
+
/** 未配置则 `version()` 抛 unsupported,**不得**回落到本包 `package.json` 的版本号 */
|
|
217
|
+
onVersion?: VersionHandler;
|
|
218
|
+
/** 未配置则复用 `onFetchMetadata` 的 `limit: 1` 探测 */
|
|
219
|
+
onIsTableExisted?: IsTableExistedHandler;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* auth hook:注入 token / header。
|
|
223
|
+
*
|
|
224
|
+
* @remarks
|
|
225
|
+
* 由适配器**在发请求前**调用,因此「hook 抛错则请求不发出」可由本包担保(AC#16)。
|
|
226
|
+
* 本包不内置 OAuth 流程。
|
|
227
|
+
*/
|
|
228
|
+
export type HttpAuthHook = () => Record<string, string> | Promise<Record<string, string>>;
|
|
229
|
+
/**
|
|
230
|
+
* `Response.type` 的取值集合。
|
|
231
|
+
*
|
|
232
|
+
* @remarks
|
|
233
|
+
* 与 DOM 的 `ResponseType` 逐字同义,但**自己声明一份**:DOM 的那个是全局名,只在
|
|
234
|
+
* `lib` 含 `dom` 时存在。写进公开接口后,纯 Node 消费方(`lib: ["es2025"]`)编我们的
|
|
235
|
+
* `.d.ts` 会以 `TS2304: Cannot find name 'ResponseType'` 失败——而本仓库的 base tsconfig
|
|
236
|
+
* 带着 `dom`,这个红我们自己永远看不见。守卫在 `__tests__/public-types.spec.ts`。
|
|
237
|
+
*
|
|
238
|
+
* 不从 `undici-types` 引:那是 Node 侧的**模块**导出,浏览器消费方没有它。
|
|
239
|
+
*/
|
|
240
|
+
export type HttpResponseType = 'basic' | 'cors' | 'default' | 'error' | 'opaque' | 'opaqueredirect';
|
|
241
|
+
/**
|
|
242
|
+
* 「条件请求开着,却读不到 `ETag`」这一刻的**事实**(US-215)。
|
|
243
|
+
*
|
|
244
|
+
* @remarks
|
|
245
|
+
* 字段全是观测值,没有结论:客户端**分不清**读不到 `ETag` 的两种成因——远端根本没发,
|
|
246
|
+
* 或远端发了而跨源响应没把它列进 `Access-Control-Expose-Headers`——二者在
|
|
247
|
+
* `response.headers.get('etag') === null` 上完全重合。替调用方猜一个,在猜错的那一半
|
|
248
|
+
* 情况下会把人送去改一个本来就对的服务端。
|
|
249
|
+
*/
|
|
250
|
+
export interface HttpEtagUnreadableReport {
|
|
251
|
+
/** 触发的操作名;参与条件缓存的只有 `fetchMetadata` / `findByIds` 两个 */
|
|
252
|
+
operation: string;
|
|
253
|
+
/**
|
|
254
|
+
* 实体名。
|
|
255
|
+
*
|
|
256
|
+
* @remarks
|
|
257
|
+
* 可选只是因为 transport 的 `sendJson` 对所有操作共用一个签名,而 `version` 这类
|
|
258
|
+
* 操作没有实体。**实际触发本回调的两个操作都由实体驱动,所以这里恒有值。**
|
|
259
|
+
*/
|
|
260
|
+
entityName?: string;
|
|
261
|
+
/** 发出该请求的绝对 URL */
|
|
262
|
+
url: string;
|
|
263
|
+
/**
|
|
264
|
+
* `Response.type` 原样透出,**不作判定**。
|
|
265
|
+
*
|
|
266
|
+
* @remarks
|
|
267
|
+
* 浏览器里跨源响应是 `'cors'`、同源是 `'basic'`,可作线索。Node(undici)下手工构造的
|
|
268
|
+
* `Response` 恒为 `'default'`,所以这是**线索而非判据**——判断留给拿得到部署拓扑的调用方。
|
|
269
|
+
*/
|
|
270
|
+
responseType: HttpResponseType;
|
|
271
|
+
/** 现成的说明文案:两种成因都点到,且不选边 */
|
|
272
|
+
message: string;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* 诊断回调:条件请求开着却读不到 `ETag` 时被调用。
|
|
276
|
+
*
|
|
277
|
+
* @remarks
|
|
278
|
+
* **同步调用、返回值忽略、抛错被丢弃**(见 `HttpAdapterOptions.onEtagUnreadable`)。
|
|
279
|
+
* 想做异步上报的实现要自己 `catch`:本回调是包内唯一的输出通道,
|
|
280
|
+
* 它自己失败时没有第二条通道可以报告这次失败。
|
|
281
|
+
*/
|
|
282
|
+
export type HttpEtagUnreadableHook = (report: HttpEtagUnreadableReport) => void;
|
|
283
|
+
/**
|
|
284
|
+
* 变更通知通道不可用的那一刻的**事实**(US-023 AC#17)。
|
|
285
|
+
*
|
|
286
|
+
* @remarks
|
|
287
|
+
* 与 {@link HttpEtagUnreadableReport} 同一条判例:字段全是观测值,没有结论。
|
|
288
|
+
* 尤其是**连接为什么失败读不出来**——`EventSource` 的 `error` 事件不带状态码、不带响应体,
|
|
289
|
+
* 「端点没实现(404)」「认证过期(401)」「网络断了」在它上面完全重合。替调用方猜一个,
|
|
290
|
+
* 会把人送去修一个本来就对的地方。
|
|
291
|
+
*/
|
|
292
|
+
export interface HttpChangeFeedUnavailableReport {
|
|
293
|
+
/** 通知端点的绝对 URL */
|
|
294
|
+
url: string;
|
|
295
|
+
/**
|
|
296
|
+
* 观测到的是哪一类事实。
|
|
297
|
+
*
|
|
298
|
+
* - `unsupported-runtime`:当前运行时没有 `EventSource`(如 Node)。**不会重连**——
|
|
299
|
+
* 重试再多次也变不出一个全局构造器。
|
|
300
|
+
* - `connection-error`:连接建立失败或中途断开。
|
|
301
|
+
* - `malformed-message`:连接是好的,但这一条消息解析不出实体名。
|
|
302
|
+
*/
|
|
303
|
+
reason: 'unsupported-runtime' | 'connection-error' | 'malformed-message';
|
|
304
|
+
/** 自上次连接成功以来的失败次数;`unsupported-runtime` 恒为 `0` */
|
|
305
|
+
attempt: number;
|
|
306
|
+
/**
|
|
307
|
+
* 失败时 `EventSource.readyState` 原样透出,**不作判定**。
|
|
308
|
+
*
|
|
309
|
+
* @remarks
|
|
310
|
+
* `0`(CONNECTING)表示浏览器自己正在重连,本包不插手;`2`(CLOSED)表示浏览器已放弃,
|
|
311
|
+
* 重连由本包的退避接管。构造器直接抛错时没有实例可读,因此为 `undefined`。
|
|
312
|
+
*/
|
|
313
|
+
readyState?: number;
|
|
314
|
+
/** 本包安排的下次重连延迟(毫秒);本包这次不重连时为 `undefined` */
|
|
315
|
+
retryInMs?: number;
|
|
316
|
+
/** `malformed-message` 时的原始 `data` 文本;其余情形为 `undefined` */
|
|
317
|
+
data?: string;
|
|
318
|
+
/** 现成的说明文案 */
|
|
319
|
+
message: string;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* 诊断回调:变更通知通道不可用时被调用。
|
|
323
|
+
*
|
|
324
|
+
* @remarks
|
|
325
|
+
* **同步调用、返回值忽略、抛错被丢弃**,与 {@link HttpEtagUnreadableHook} 同一条口径。
|
|
326
|
+
*/
|
|
327
|
+
export type HttpChangeFeedUnavailableHook = (report: HttpChangeFeedUnavailableReport) => void;
|
|
328
|
+
/**
|
|
329
|
+
* 收到一条**读得懂**的变更通知时的事实(US-023 AC#24)。
|
|
330
|
+
*
|
|
331
|
+
* @remarks
|
|
332
|
+
* 这个出口存在的唯一理由是**自回声抑制发生在包内**(D6):被抑制的那条通知不会走到
|
|
333
|
+
* `RxDB.invalidateRemoteEntity`,包外从 core 的事件流上看它和「压根没收到」一模一样。
|
|
334
|
+
* 想从「后端广播条数 − core 失效条数」倒推抑制数,会把断线期间丢掉的通知一并算进去。
|
|
335
|
+
*
|
|
336
|
+
* **报告结构上带不了行数据**(D8):字段是固定的这几个,载荷里多出来的键一律不透出。
|
|
337
|
+
* 通知的语义是「某个实体变了」,不是「变成了什么」——本地行只有 `#pull → upsertMany` 一条写入路径。
|
|
338
|
+
*/
|
|
339
|
+
export interface HttpChangeFeedNotificationReport {
|
|
340
|
+
/** 通知端点的绝对 URL */
|
|
341
|
+
url: string;
|
|
342
|
+
/** 通知里的实体名,原样透出(本客户端没注册的名字也会出现在这里,见 D9) */
|
|
343
|
+
entity: string;
|
|
344
|
+
/** 通知里的命名空间;载荷没带时为 `'public'` */
|
|
345
|
+
namespace: string;
|
|
346
|
+
/** 通知里的发起方 `clientId`;载荷没带时为 `undefined` */
|
|
347
|
+
clientId?: string;
|
|
348
|
+
/**
|
|
349
|
+
* 这条通知是否因为「发起方就是本机」而没有上报失效(D6)。
|
|
350
|
+
*
|
|
351
|
+
* @remarks
|
|
352
|
+
* `true` 时本包**没有**调用 `RxDB.invalidateRemoteEntity`——这不是错误,是本机刚写完、
|
|
353
|
+
* 本地已是最新,再查一次远端纯属白跑。
|
|
354
|
+
*/
|
|
355
|
+
suppressed: boolean;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* 诊断回调:收到一条读得懂的变更通知时被调用(无论是否被抑制)。
|
|
359
|
+
*
|
|
360
|
+
* @remarks
|
|
361
|
+
* **同步调用、返回值忽略、抛错被丢弃**,与 {@link HttpChangeFeedUnavailableHook} 同一条口径:
|
|
362
|
+
* 诊断口失败绝不能带塌失效上报。
|
|
363
|
+
*/
|
|
364
|
+
export type HttpChangeFeedNotificationHook = (report: HttpChangeFeedNotificationReport) => void;
|
|
365
|
+
/**
|
|
366
|
+
* 变更通知通道(SSE)的配置(US-023 D5)。
|
|
367
|
+
*
|
|
368
|
+
* @remarks
|
|
369
|
+
* **所有字段都收在这个对象里**,不平铺到 {@link HttpAdapterOptions}:它们离开
|
|
370
|
+
* `changeFeed` 都没有意义,平铺会让「配了 `onChangeFeedUnavailable` 却没配
|
|
371
|
+
* `changeFeed`」这种永不触发的死配置在类型上合法。
|
|
372
|
+
*
|
|
373
|
+
* **认证走不了 `auth` hook。** `EventSource` 发不出自定义 header,这是它的规格而不是
|
|
374
|
+
* 本包的取舍。因此通知端点只能靠 cookie(配 {@link HttpChangeFeedOptions.withCredentials})
|
|
375
|
+
* 或把凭据编进 `url`。适配器的 `auth` hook **不作用于**这条连接。
|
|
376
|
+
*/
|
|
377
|
+
export interface HttpChangeFeedOptions {
|
|
378
|
+
/** SSE 端点:绝对 URL,或相对于 `baseUrl` 的路径 */
|
|
379
|
+
url: string;
|
|
380
|
+
/** 跨源连接是否携带 cookie,透传给 `EventSource`。默认 `false` */
|
|
381
|
+
withCredentials?: boolean;
|
|
382
|
+
/** 退避重连的起步延迟(毫秒)。默认 `1000`;必须是 finite 正整数 */
|
|
383
|
+
reconnectBaseDelayMs?: number;
|
|
384
|
+
/** 退避重连的延迟上限(毫秒)。默认 `30000`;必须是 finite 正整数且不小于起步延迟 */
|
|
385
|
+
reconnectMaxDelayMs?: number;
|
|
386
|
+
/**
|
|
387
|
+
* 通道不可用时的诊断回调。
|
|
388
|
+
*
|
|
389
|
+
* @remarks
|
|
390
|
+
* 不配它时通道的行为完全不变(照常退避重连),只是没有嘴——而 D5 明确不给轮询降级,
|
|
391
|
+
* 「连不上」的唯一出口就是这个回调。抛出的错误被丢弃,理由见 {@link HttpChangeFeedUnavailableHook}。
|
|
392
|
+
*/
|
|
393
|
+
onUnavailable?: HttpChangeFeedUnavailableHook;
|
|
394
|
+
/**
|
|
395
|
+
* 收到一条读得懂的通知时的诊断回调(含被抑制的自回声)。
|
|
396
|
+
*
|
|
397
|
+
* @remarks
|
|
398
|
+
* 与 {@link HttpChangeFeedOptions.onUnavailable} 对称:一个报「通道没了」,一个报「通道来货了」。
|
|
399
|
+
* 不配它时通道行为完全不变。理由见 {@link HttpChangeFeedNotificationReport}。
|
|
400
|
+
*/
|
|
401
|
+
onNotification?: HttpChangeFeedNotificationHook;
|
|
402
|
+
}
|
|
403
|
+
/** 六个数值配置,全部可覆盖、全部有默认。 */
|
|
404
|
+
export interface HttpNumericConfig {
|
|
405
|
+
/** 单页条数,透传为 handler 的 `ctx.limit`。默认 `1000`(对标 `SUPABASE_PAGE_SIZE`) */
|
|
406
|
+
pageSize: number;
|
|
407
|
+
/** `findByIds` 单块 id 数。默认 `100`(对标 `SUPABASE_IN_CHUNK_SIZE`) */
|
|
408
|
+
idChunkSize: number;
|
|
409
|
+
/** token 形态下连续空页容忍上限。默认 `3`;`0` = 不容忍空页 */
|
|
410
|
+
maxEmptyPages: number;
|
|
411
|
+
/** 单次 `fetchMetadata` 总页数上限。默认 `1000`;触顶是**抛错不是截断** */
|
|
412
|
+
maxPages: number;
|
|
413
|
+
/** **单个** HTTP 请求的超时上限(毫秒)。默认 `30000` */
|
|
414
|
+
requestTimeoutMs: number;
|
|
415
|
+
/**
|
|
416
|
+
* 条件请求响应缓存的条目上限。默认 `256`;仅在 `conditionalRequests` 为 `true` 时生效。
|
|
417
|
+
*
|
|
418
|
+
* @remarks
|
|
419
|
+
* 一页 / 一块各占一个条目,所以上限要按**并发活跃查询的总页数**估,不是按实体数。
|
|
420
|
+
* 取太小会让翻页里最热的首页被反复挤出,退化成没有缓存(不产生错误结果)。
|
|
421
|
+
*/
|
|
422
|
+
conditionalCacheSize: number;
|
|
423
|
+
}
|
|
424
|
+
/** `new RxDBAdapterHttp(rxdb, options)` 的配置。 */
|
|
425
|
+
export interface HttpAdapterOptions extends Partial<HttpNumericConfig> {
|
|
426
|
+
/** 相对 URL 的基地址;handler 返回绝对 URL 时忽略 */
|
|
427
|
+
baseUrl: string;
|
|
428
|
+
handlers: HttpHandlers;
|
|
429
|
+
auth?: HttpAuthHook;
|
|
430
|
+
/** 附加到所有请求的 header;与 auth hook 冲突时 auth hook 优先 */
|
|
431
|
+
headers?: Record<string, string>;
|
|
432
|
+
/**
|
|
433
|
+
* 启用 ETag / If-None-Match 条件请求(US-212 AC#28)。默认 `false`。
|
|
434
|
+
*
|
|
435
|
+
* @remarks
|
|
436
|
+
* **必须显式开启**,因为它只在远端真的发 `ETag` 并认 `If-None-Match` 时才有收益,
|
|
437
|
+
* 而这一点适配器无从探测。关闭时 `fetchMetadata` / `findByIds` 的行为与阶段 A 逐字相同:
|
|
438
|
+
* 不带条件头、不去重并发、304 照旧当错误。
|
|
439
|
+
*
|
|
440
|
+
* 开启后缓存的是**响应**(上次 200 的 JSON body),不是行——行缓存归 core 经本地适配器
|
|
441
|
+
* 落盘,本包按 AC#19 不碰。缓存按适配器实例存活、有界({@link HttpNumericConfig.conditionalCacheSize})、
|
|
442
|
+
* `disconnect()` 时清空。
|
|
443
|
+
*
|
|
444
|
+
* 三组 header 只有一组进请求指纹。{@link HttpRequestSpec.headers}(handler 逐请求给的)
|
|
445
|
+
* **进**——它是唯一会在同一条 URL 上区分投影的一组,不进就是两个租户共用一个条目。
|
|
446
|
+
* {@link HttpAdapterOptions.headers}(本实例恒定)与 auth hook 产出的**不进**:
|
|
447
|
+
* 前者进去只是给每条键加同一段前缀,后者进去会让每次 token 轮换都全量失效。
|
|
448
|
+
*
|
|
449
|
+
* **换用户必须走 `disconnect()` / `connect()`**:这是 auth header 不进指纹的代价——
|
|
450
|
+
* 同一实例上直接换 token 会读到上一个身份的响应。
|
|
451
|
+
*/
|
|
452
|
+
conditionalRequests?: boolean;
|
|
453
|
+
/**
|
|
454
|
+
* 条件请求开着、响应是 200、却读不到 `ETag` 时被调用(US-215)。
|
|
455
|
+
*
|
|
456
|
+
* @remarks
|
|
457
|
+
* 存在的理由:`conditionalRequests` 开启**前**远端认不认 `If-None-Match` 确实无从探测,
|
|
458
|
+
* 但开启**后**「一次都没生效」是适配器手上就有的铁证——一个 200 响应,条件请求开着,
|
|
459
|
+
* 却读不到 `ETag`。没有这个回调时它知道,只是没有嘴:请求照发、账单照付、缓存零命中,
|
|
460
|
+
* 而客户端侧一行日志都没有。
|
|
461
|
+
*
|
|
462
|
+
* 三条边界,缺一条这个回调就会变成新的麻烦:
|
|
463
|
+
*
|
|
464
|
+
* - **它不改数据路径。** 不配它时的行为与 US-215 之前逐字相同(丢弃该条目、正常返回);
|
|
465
|
+
* 配了它也一样,回调只是多一次调用。
|
|
466
|
+
* - **它不臆断成因**,只给事实(见 {@link HttpEtagUnreadableReport})。
|
|
467
|
+
* - **它按缓存 key 去重**,一个 key 只报一次;`disconnect()` 清缓存时一并清掉记录,
|
|
468
|
+
* 所以换了后端配置重连后会重新报。
|
|
469
|
+
*
|
|
470
|
+
* **回调抛出的错误被丢弃**——不是「有别的通道兜着」,是真的没地方去:此刻正在报告的
|
|
471
|
+
* 就是「本包没有输出通道」这件事本身。诊断通道不该成为新的故障源,所以宁可丢。
|
|
472
|
+
* 需要知道自己的上报失败了,请在回调内部自行处理。
|
|
473
|
+
*
|
|
474
|
+
* `conditionalRequests` 关着时**永不触发**:关着的开关不该产生噪音。
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```ts
|
|
478
|
+
* new RxDBAdapterHttp(rxdb, {
|
|
479
|
+
* baseUrl,
|
|
480
|
+
* handlers,
|
|
481
|
+
* conditionalRequests: true,
|
|
482
|
+
* onEtagUnreadable: report => myLogger.warn(report.message, report)
|
|
483
|
+
* });
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
onEtagUnreadable?: HttpEtagUnreadableHook;
|
|
487
|
+
/**
|
|
488
|
+
* 启用变更通知通道(US-023 AC#12)。**缺席即关闭**。
|
|
489
|
+
*
|
|
490
|
+
* @remarks
|
|
491
|
+
* 关着时行为与本故事之前逐字相同:零新增请求、零连接,远端变更靠下一次 `find()`
|
|
492
|
+
* 回远端校验发现。开着时远端一变,订阅同一实体的活查询立刻重跑。
|
|
493
|
+
*
|
|
494
|
+
* 与 `conditionalRequests` 同一条理由必须显式开启:不是所有后端都实现得了推送,
|
|
495
|
+
* 而适配器无从探测——一个不实现该端点的后端,表现是连接被拒,不是「没有变更」。
|
|
496
|
+
*
|
|
497
|
+
* **连不上时不降级成轮询。** 偷偷切一条「每 N 秒问一次」的二等通道,会让接入方拿到一个
|
|
498
|
+
* 说不清延迟上界的实时性,出问题还查不出走的是哪条路。连不上就是连不上,按退避重连并
|
|
499
|
+
* 通过 {@link HttpChangeFeedOptions.onUnavailable} 报出来。
|
|
500
|
+
*
|
|
501
|
+
* **连接成功(含每次重连)会对所有走本适配器的实体各上报一次失效。** 这是正确性要求
|
|
502
|
+
* 不是优化:断开期间发生的变更没有任何人会补发,不主动失效一次,客户端会把「没收到消息」
|
|
503
|
+
* 当成「没有变化」,而这次误判可能一直持续下去。代价是一次 metadata 往返,无变化则零行拉取。
|
|
504
|
+
*
|
|
505
|
+
* @example
|
|
506
|
+
* ```ts
|
|
507
|
+
* new RxDBAdapterHttp(rxdb, {
|
|
508
|
+
* baseUrl,
|
|
509
|
+
* handlers,
|
|
510
|
+
* changeFeed: { url: 'changes', onUnavailable: report => myLogger.warn(report.message, report) }
|
|
511
|
+
* });
|
|
512
|
+
* ```
|
|
513
|
+
*
|
|
514
|
+
* @experimental 不在 1.0 兼容承诺内:协议目前只有参考后端一个实现,wire 形态可能随第二个实现调整。
|
|
515
|
+
* 层级口径见 `requirements/versioning-policy.md`「实验性层级」。
|
|
516
|
+
*/
|
|
517
|
+
changeFeed?: HttpChangeFeedOptions;
|
|
518
|
+
}
|
|
519
|
+
//# sourceMappingURL=http.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.interface.d.ts","sourceRoot":"","sources":["../src/http.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,UAAU,CAAC;IACnB,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAC1B,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB;AAC7B,qDAAqD;AACnD,wBAAwB,EAAE;AAC5B,gEAAgE;GAC9D;IAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,eAAe,CAAC;IACpD,uDAAuD;IACvD,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;CACtE;AAED,6BAA6B;AAC7B,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,eAAe,CAAC;IAChD,sBAAsB;IACtB,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,EAAE,CAAC;CACxD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED,4BAA4B;AAC5B,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,eAAe,CAAC;IAC7C;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC;CACnD;AAED,4BAA4B;AAC5B,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,eAAe,CAAC;IAC7C,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC;CACnD;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,eAAe,CAAC;CAC9C;AAED,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC7B,OAAO,IAAI,eAAe,CAAC;IAC3B,yDAAyD;IACzD,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,GAAG,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe,CAAC;CACvD;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,oBAAoB,CAAC;IACtC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1F;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,gBAAgB,CAAC;AAEpG;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,YAAY,EAAE,gBAAgB,CAAC;IAC/B,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,WAAW,+BAA+B;IAC9C,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,MAAM,EAAE,qBAAqB,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;IACzE,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,MAAM,EAAE,+BAA+B,KAAK,IAAI,CAAC;AAE9F;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gCAAgC;IAC/C,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,8BAA8B,GAAG,CAAC,MAAM,EAAE,gCAAgC,KAAK,IAAI,CAAC;AAEhG;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sDAAsD;IACtD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,6BAA6B,CAAC;IAC9C;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,8BAA8B,CAAC;CACjD;AAED,0BAA0B;AAC1B,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAmB,SAAQ,OAAO,CAAC,iBAAiB,CAAC;IACpE,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview HTTP 远端适配器包入口(US-212)。
|
|
3
|
+
*
|
|
4
|
+
* v1 只服务 `SyncType.QueryCache` 的 remote 槽位:远端是权威源,本地 sqlite 行缓存由
|
|
5
|
+
* 使用方**独立注册**。changelog / 分支同步(Full、Filter)一律 unsupported throw,
|
|
6
|
+
* 不返回空数组或 `0` 装作「远端无变更」。
|
|
7
|
+
*
|
|
8
|
+
* 各模块导出约定:
|
|
9
|
+
* - `errors.ts` → `HttpAdapterError` 及具体错误子类(**判别位是类名**)
|
|
10
|
+
* - `http.interface.ts` → handler、配置与适配器选项类型
|
|
11
|
+
* - `config.ts` → 六个数值配置的默认值
|
|
12
|
+
* - `RxDBAdapterHttp.ts` → `RxDBAdapterHttp` 适配器主体与 `ADAPTER_NAME`
|
|
13
|
+
* - `rest.ts` → REST 资源 URL 模板工厂(阶段 B AC#27),产出的仍是普通 handler
|
|
14
|
+
*
|
|
15
|
+
* 翻页(`pagination.ts`)、分块(`chunking.ts`)、metadata 规范化(`metadata.ts`)与
|
|
16
|
+
* 条件请求缓存(`conditional-cache.ts`)是实现细节,不出现在公共 API 上:它们的终止条件、
|
|
17
|
+
* fail-fast 判据与「调用方之间不共享对象」是本包对上层的担保,一旦可被外部替换,
|
|
18
|
+
* 那些担保就没有单一负责人了。
|
|
19
|
+
*/
|
|
20
|
+
export { DEFAULT_HTTP_CONFIG } from './config.js';
|
|
21
|
+
export * from './errors.js';
|
|
22
|
+
export * from './http.interface.js';
|
|
23
|
+
export * from './rest.js';
|
|
24
|
+
export * from './RxDBAdapterHttp.js';
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC"}
|