@aiao/rxdb-angular 0.0.3 → 0.0.8

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Aiao Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,47 +1,423 @@
1
- import { RxDB } from '@aiao/rxdb';
2
- import { isPlatformBrowser } from '@angular/common';
1
+ import { isFunction, nextMicroTask, IS_BROWSER } from '@aiao/utils';
3
2
  import * as i0 from '@angular/core';
4
- import { InjectionToken, PLATFORM_ID, Injectable } from '@angular/core';
3
+ import { signal, effect, inject, DestroyRef, computed, untracked, ChangeDetectorRef, input, Directive, makeEnvironmentProviders } from '@angular/core';
4
+ import { toLazySignal } from 'ngxtension/to-lazy-signal';
5
+ import { Observable, debounceTime, auditTime } from 'rxjs';
6
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
+ import { getEntityStatus, RxDB } from '@aiao/rxdb';
5
8
 
6
- const RXDB_OPTIONS = new InjectionToken('RXDB_OPTIONS');
9
+ const useRepositoryQuery = (EntityType, method, defaultValue, options) => {
10
+ let _observer;
11
+ let sub;
12
+ const _has_sub = signal(false, ...(ngDevMode ? [{ debugName: "_has_sub" }] : []));
13
+ const _refresh = signal(0, ...(ngDevMode ? [{ debugName: "_refresh" }] : []));
14
+ const _eff = effect(() => {
15
+ if (_has_sub() === false)
16
+ return;
17
+ // re-run when refresh is called or options change
18
+ _refresh();
19
+ const opt = isFunction(options) ? options() : options;
20
+ if (sub)
21
+ sub.unsubscribe();
22
+ // reset state for a new request
23
+ isLoading.set(true);
24
+ error.set(undefined);
25
+ hasValue.set(false);
26
+ isEmpty.set(undefined);
27
+ // 优化:使用 Record<string, any> 替代 any,以提高类型安全性
28
+ const func = EntityType[method];
29
+ sub =
30
+ func &&
31
+ func(opt).subscribe({
32
+ next: (d) => {
33
+ isLoading.set(false);
34
+ hasValue.set(true);
35
+ if (Array.isArray(d)) {
36
+ isEmpty.set(d.length === 0);
37
+ }
38
+ else if (d == null) {
39
+ // null/undefined treated as empty
40
+ isEmpty.set(true);
41
+ }
42
+ else {
43
+ isEmpty.set(false);
44
+ }
45
+ _observer.next(d);
46
+ },
47
+ error: (e) => {
48
+ isLoading.set(false);
49
+ error.set(e);
50
+ },
51
+ complete: () => {
52
+ // ensure loading is false even if observable completes without next
53
+ isLoading.set(false);
54
+ }
55
+ });
56
+ }, ...(ngDevMode ? [{ debugName: "_eff" }] : []));
57
+ const ob = new Observable(observer => {
58
+ _has_sub.set(true);
59
+ _observer = observer;
60
+ _observer.next(defaultValue);
61
+ return () => {
62
+ _eff.destroy();
63
+ sub?.unsubscribe();
64
+ };
65
+ });
66
+ const value = toLazySignal(ob, {
67
+ initialValue: defaultValue
68
+ });
69
+ const error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : []));
70
+ const isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
71
+ const hasValue = signal(false, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
72
+ const isEmpty = signal(undefined, ...(ngDevMode ? [{ debugName: "isEmpty" }] : []));
73
+ return {
74
+ value,
75
+ error,
76
+ isLoading,
77
+ isEmpty,
78
+ hasValue
79
+ };
80
+ };
81
+ /*
82
+ * Repository
83
+ */
84
+ /**
85
+ * 通过 ID 获取单个实体
86
+ *
87
+ * @param EntityType 实体类
88
+ * @param options 实体 ID 或查询参数对象
89
+ * @returns 返回包含实体的资源 signal
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const user = useGet(User, 'user-1');
94
+ * ```
95
+ */
96
+ const useGet = (EntityType, options) => useRepositoryQuery(EntityType, 'get', undefined, options);
97
+ /**
98
+ * 查找第一个匹配条件的实体
99
+ *
100
+ * @param EntityType 实体类
101
+ * @param options 查询参数(where、排序等)
102
+ * @returns 返回包含实体的资源 signal
103
+ */
104
+ const useFindOne = (EntityType, options) => useRepositoryQuery(EntityType, 'findOne', undefined, options);
105
+ /**
106
+ * 查找匹配的实体,未找到则抛出错误
107
+ *
108
+ * @param EntityType 实体类
109
+ * @param options 查询参数
110
+ * @returns 返回包含实体的资源 signal
111
+ */
112
+ const useFindOneOrFail = (EntityType, options) => useRepositoryQuery(EntityType, 'findOneOrFail', undefined, options);
113
+ /**
114
+ * 查找符合条件的多个实体
115
+ *
116
+ * @param EntityType 实体类
117
+ * @param options 查询参数
118
+ * @returns 返回包含实体数组的资源 signal
119
+ */
120
+ const useFind = (EntityType, options) => useRepositoryQuery(EntityType, 'find', [], options);
121
+ /**
122
+ * 使用游标分页查找实体
123
+ *
124
+ * @param EntityType 实体类
125
+ * @param options 游标参数
126
+ * @returns 返回包含实体数组的资源 signal
127
+ */
128
+ const useFindByCursor = (EntityType, options) => useRepositoryQuery(EntityType, 'findByCursor', [], options);
129
+ /**
130
+ * 查找全部实体
131
+ *
132
+ * @param EntityType 实体类
133
+ * @param options 查询参数
134
+ * @returns 返回包含全部实体的资源 signal
135
+ */
136
+ const useFindAll = (EntityType, options) => useRepositoryQuery(EntityType, 'findAll', [], options);
137
+ /**
138
+ * 统计满足条件的实体数量
139
+ *
140
+ * @param EntityType 实体类
141
+ * @param options 查询参数
142
+ * @returns 返回包含数量的资源 signal
143
+ */
144
+ const useCount = (EntityType, options) => useRepositoryQuery(EntityType, 'count', undefined, options);
145
+ /*
146
+ * TreeRepository
147
+ */
148
+ /**
149
+ * 查找树结构中的所有子孙实体
150
+ *
151
+ * @param EntityType 实体类
152
+ * @param options 树查询参数(entityId、深度等)
153
+ * @returns 返回包含子孙实体的资源 signal
154
+ */
155
+ const useFindDescendants = (EntityType, options) => useRepositoryQuery(EntityType, 'findDescendants', [], options);
156
+ /**
157
+ * 统计树结构中的子孙数量
158
+ *
159
+ * @param EntityType 实体类
160
+ * @param options 树查询参数
161
+ * @returns 返回包含数量的资源 signal
162
+ */
163
+ const useCountDescendants = (EntityType, options) => useRepositoryQuery(EntityType, 'countDescendants', undefined, options);
164
+ /**
165
+ * 查找树结构中的所有祖先实体
166
+ *
167
+ * @param EntityType 实体类
168
+ * @param options 树查询参数
169
+ * @returns 返回包含祖先实体的资源 signal
170
+ */
171
+ const useFindAncestors = (EntityType, options) => useRepositoryQuery(EntityType, 'findAncestors', [], options);
172
+ /**
173
+ * 统计树结构中的祖先数量
174
+ *
175
+ * @param EntityType 实体类
176
+ * @param options 树查询参数
177
+ * @returns 返回包含数量的资源 signal
178
+ */
179
+ const useCountAncestors = (EntityType, options) => useRepositoryQuery(EntityType, 'countAncestors', undefined, options);
180
+ /*
181
+ * GraphRepository
182
+ */
183
+ /**
184
+ * 查找图结构中的邻接实体
185
+ *
186
+ * @param EntityType 实体类
187
+ * @param options 图查询参数(entityId、方向、层级等)
188
+ * @returns 返回包含邻居实体的资源 signal
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * const friends = useGraphNeighbors(User, {
193
+ * entityId: 'user-1',
194
+ * direction: 'out',
195
+ * level: 1
196
+ * });
197
+ * ```
198
+ */
199
+ const useGraphNeighbors = (EntityType, options) => useRepositoryQuery(EntityType, 'findNeighbors', [], options);
200
+ /**
201
+ * 统计图结构中的邻接数量
202
+ *
203
+ * @param EntityType 实体类
204
+ * @param options 图查询参数
205
+ * @returns 返回包含数量的资源 signal
206
+ */
207
+ const useCountNeighbors = (EntityType, options) => useRepositoryQuery(EntityType, 'countNeighbors', 0, options);
208
+ /**
209
+ * 查找图结构中两个实体之间的路径
210
+ *
211
+ * @param EntityType 实体类
212
+ * @param options 路径查询参数(fromId、toId、最大深度等)
213
+ * @returns 返回包含路径的资源 signal
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * const paths = useGraphPaths(User, {
218
+ * fromId: 'user-1',
219
+ * toId: 'user-2',
220
+ * maxDepth: 5
221
+ * });
222
+ * ```
223
+ */
224
+ const useGraphPaths = (EntityType, options) => useRepositoryQuery(EntityType, 'findPaths', [], options);
7
225
 
8
226
  /**
9
- * RxDB 配置
227
+ * 无限滚动的列表
10
228
  */
11
- const provideRxDB = (options, callback) => {
12
- return [
13
- {
14
- provide: RXDB_OPTIONS,
15
- useValue: options
16
- },
17
- {
18
- provide: RxDB,
19
- useFactory: (options, platformId) => {
20
- if (isPlatformBrowser(platformId)) {
21
- const db = new RxDB(options);
22
- if (callback)
23
- callback(db);
24
- return db;
229
+ class InfiniteScrollingList {
230
+ rxdb;
231
+ EntityType;
232
+ options;
233
+ #values = signal([], ...(ngDevMode ? [{ debugName: "#values" }] : []));
234
+ #destroy_ref = inject(DestroyRef);
235
+ #options_eff;
236
+ #is_initialized = false;
237
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : []));
238
+ isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
239
+ hasMore = signal(true, ...(ngDevMode ? [{ debugName: "hasMore" }] : []));
240
+ value = computed(() => this.#values().flat(), ...(ngDevMode ? [{ debugName: "value" }] : []));
241
+ hasValue = computed(() => this.value().length > 0, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
242
+ isEmpty = computed(() => !this.isLoading() && !this.hasValue() && this.#is_initialized, ...(ngDevMode ? [{ debugName: "isEmpty" }] : []));
243
+ constructor(rxdb, EntityType, options) {
244
+ this.rxdb = rxdb;
245
+ this.EntityType = EntityType;
246
+ this.options = options;
247
+ this.#options_eff = effect(() => {
248
+ if (isFunction(this.options)) {
249
+ this.options();
250
+ }
251
+ if (!this.#is_initialized) {
252
+ this.#is_initialized = true;
253
+ nextMicroTask(() => this.loadMore());
254
+ return;
255
+ }
256
+ untracked(() => this.#reset());
257
+ }, ...(ngDevMode ? [{ debugName: "#options_eff" }] : []));
258
+ this.#destroy_ref.onDestroy(() => {
259
+ this.#options_eff.destroy();
260
+ });
261
+ }
262
+ loadMore() {
263
+ if (this.isLoading() || !this.hasMore()) {
264
+ return;
265
+ }
266
+ this.isLoading.set(true);
267
+ this.error.set(undefined);
268
+ const last_entity = this.#get_last_entity();
269
+ const opt = isFunction(this.options) ? this.options() : this.options;
270
+ const options = structuredClone(opt);
271
+ if (last_entity) {
272
+ options.after = last_entity;
273
+ }
274
+ const current_index = this.#values().length;
275
+ this.rxdb.entityManager
276
+ .getRepository(this.EntityType)
277
+ .findByCursor(options)
278
+ .pipe(takeUntilDestroyed(this.#destroy_ref))
279
+ .subscribe({
280
+ next: result => {
281
+ this.isLoading.set(false);
282
+ this.#values.update(values => {
283
+ const updated = [...values];
284
+ updated[current_index] = result;
285
+ return updated;
286
+ });
287
+ if (result.length < (options.limit || 100)) {
288
+ this.hasMore.set(false);
25
289
  }
26
- return null;
27
290
  },
28
- deps: [RXDB_OPTIONS, PLATFORM_ID]
291
+ error: error => {
292
+ this.isLoading.set(false);
293
+ this.error.set(error);
294
+ },
295
+ complete: () => {
296
+ this.hasMore.set(false);
297
+ this.isLoading.set(false);
298
+ }
299
+ });
300
+ }
301
+ /**
302
+ * 刷新列表数据
303
+ */
304
+ refresh() {
305
+ // 强制重置状态,即使正在加载中
306
+ this.#values.set([]);
307
+ this.error.set(undefined);
308
+ this.isLoading.set(false); // 强制设置为 false,允许新的 loadMore
309
+ this.hasMore.set(true);
310
+ // 立即开始加载
311
+ this.loadMore();
312
+ }
313
+ #reset() {
314
+ this.#values.set([]);
315
+ this.error.set(undefined);
316
+ this.isLoading.set(false);
317
+ this.hasMore.set(true);
318
+ nextMicroTask(() => this.loadMore());
319
+ }
320
+ #get_last_entity() {
321
+ const values = this.#values();
322
+ if (values.length === 0)
323
+ return undefined;
324
+ const last_page = values[values.length - 1];
325
+ if (last_page.length === 0)
326
+ return undefined;
327
+ return last_page[last_page.length - 1];
328
+ }
329
+ }
330
+
331
+ /**
332
+ * RxDB 实体变化指令
333
+ * 如果你使用了 `changeDetection: ChangeDetectionStrategy.OnPush`
334
+ * 那么正在输入的变化不会触发 angular 渲染机制,使用这个指令可以实现实时渲染
335
+ *
336
+ * @example
337
+ * 当修改实体时,需要在多个地方预览修改变化时,可以使用这个指令
338
+ */
339
+ class RxDBEntityChangeDirective {
340
+ #destroyRef = inject(DestroyRef);
341
+ #changeDetectorRef = inject(ChangeDetectorRef);
342
+ #sub;
343
+ rxdbChangeDetector = input(...(ngDevMode ? [undefined, { debugName: "rxdbChangeDetector" }] : []));
344
+ debounceTime = input(0, ...(ngDevMode ? [{ debugName: "debounceTime" }] : []));
345
+ auditTime = input(0, ...(ngDevMode ? [{ debugName: "auditTime" }] : []));
346
+ constructor() {
347
+ effect(() => {
348
+ const rxdbChange = this.rxdbChangeDetector();
349
+ const dt = this.debounceTime();
350
+ const at = this.auditTime();
351
+ const status = getEntityStatus(rxdbChange);
352
+ this.#sub?.unsubscribe();
353
+ this.#sub = status.patches$
354
+ .pipe(takeUntilDestroyed(this.#destroyRef), debounceTime(dt), auditTime(at))
355
+ .subscribe(() => this.#changeDetectorRef.markForCheck());
356
+ });
357
+ }
358
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: RxDBEntityChangeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
359
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: RxDBEntityChangeDirective, isStandalone: true, selector: "[rxdbChangeDetector]", inputs: { rxdbChangeDetector: { classPropertyName: "rxdbChangeDetector", publicName: "rxdbChangeDetector", isSignal: true, isRequired: false, transformFunction: null }, debounceTime: { classPropertyName: "debounceTime", publicName: "debounceTime", isSignal: true, isRequired: false, transformFunction: null }, auditTime: { classPropertyName: "auditTime", publicName: "auditTime", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
360
+ }
361
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: RxDBEntityChangeDirective, decorators: [{
362
+ type: Directive,
363
+ args: [{ selector: '[rxdbChangeDetector]' }]
364
+ }], ctorParameters: () => [], propDecorators: { rxdbChangeDetector: [{ type: i0.Input, args: [{ isSignal: true, alias: "rxdbChangeDetector", required: false }] }], debounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceTime", required: false }] }], auditTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "auditTime", required: false }] }] } });
365
+
366
+ /**
367
+ * RxDB 配置
368
+ */
369
+ const provideRxDB = (useFactory) => makeEnvironmentProviders([
370
+ {
371
+ provide: RxDB,
372
+ useFactory
373
+ }
374
+ ]);
375
+
376
+ const action = (promiseFn) => {
377
+ const isPending = signal(false, ...(ngDevMode ? [{ debugName: "isPending" }] : []));
378
+ return {
379
+ isPending,
380
+ execute: async (options) => {
381
+ isPending.set(true);
382
+ try {
383
+ const d = await promiseFn(options);
384
+ return d;
385
+ }
386
+ finally {
387
+ isPending.set(false);
388
+ }
29
389
  }
30
- ];
390
+ };
31
391
  };
392
+ const useAction = (promiseFn) => action(promiseFn);
32
393
 
33
- class RxDBService {
34
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RxDBService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
35
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RxDBService, providedIn: 'root' });
394
+ function state(namespace) {
395
+ return (name) => {
396
+ const signal$1 = (initialValue, options) => {
397
+ if (IS_BROWSER) {
398
+ const value = localStorage.getItem(`${namespace}:${name}`);
399
+ if (value) {
400
+ initialValue = JSON.parse(value);
401
+ }
402
+ }
403
+ const a = signal(initialValue, options);
404
+ effect(() => {
405
+ if (IS_BROWSER) {
406
+ localStorage.setItem(`${namespace}:${name}`, JSON.stringify(a()));
407
+ }
408
+ });
409
+ return a;
410
+ };
411
+ return {
412
+ signal: signal$1
413
+ };
414
+ };
36
415
  }
37
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RxDBService, decorators: [{
38
- type: Injectable,
39
- args: [{ providedIn: 'root' }]
40
- }] });
416
+ const useState = (namespace) => state(namespace);
41
417
 
42
418
  /**
43
419
  * Generated bundle index. Do not edit.
44
420
  */
45
421
 
46
- export { RxDBService, provideRxDB };
422
+ export { InfiniteScrollingList, RxDBEntityChangeDirective, provideRxDB, useAction, useCount, useCountAncestors, useCountDescendants, useCountNeighbors, useFind, useFindAll, useFindAncestors, useFindByCursor, useFindDescendants, useFindOne, useFindOneOrFail, useGet, useGraphNeighbors, useGraphPaths, useRepositoryQuery, useState };
47
423
  //# sourceMappingURL=aiao-rxdb-angular.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"aiao-rxdb-angular.mjs","sources":["../tmp-esm2022/rxdb.interface.js","../tmp-esm2022/rxdb.provider.js","../tmp-esm2022/rxdb.service.js","../tmp-esm2022/aiao-rxdb-angular.js"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nexport const RXDB_OPTIONS = new InjectionToken('RXDB_OPTIONS');\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnhkYi5pbnRlcmZhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9yeGRiLWFuZ3VsYXIvc3JjL3J4ZGIuaW50ZXJmYWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFL0MsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLElBQUksY0FBYyxDQUFjLGNBQWMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUnhEQk9wdGlvbnMgfSBmcm9tICdAYWlhby9yeGRiJztcbmltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBjb25zdCBSWERCX09QVElPTlMgPSBuZXcgSW5qZWN0aW9uVG9rZW48UnhEQk9wdGlvbnM+KCdSWERCX09QVElPTlMnKTtcbiJdfQ==","import { RxDB } from '@aiao/rxdb';\nimport { isPlatformBrowser } from '@angular/common';\nimport { PLATFORM_ID } from '@angular/core';\nimport { RXDB_OPTIONS } from './rxdb.interface';\n/**\n * RxDB 配置\n */\nexport const provideRxDB = (options, callback) => {\n return [\n {\n provide: RXDB_OPTIONS,\n useValue: options\n },\n {\n provide: RxDB,\n useFactory: (options, platformId) => {\n if (isPlatformBrowser(platformId)) {\n const db = new RxDB(options);\n if (callback)\n callback(db);\n return db;\n }\n return null;\n },\n deps: [RXDB_OPTIONS, PLATFORM_ID]\n }\n ];\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnhkYi5wcm92aWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL3J4ZGItYW5ndWxhci9zcmMvcnhkYi5wcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFlLE1BQU0sWUFBWSxDQUFDO0FBQy9DLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxXQUFXLEVBQVksTUFBTSxlQUFlLENBQUM7QUFDdEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWhEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLENBQUMsT0FBb0IsRUFBRSxRQUE2QixFQUFjLEVBQUU7SUFDN0YsT0FBTztRQUNMO1lBQ0UsT0FBTyxFQUFFLFlBQVk7WUFDckIsUUFBUSxFQUFFLE9BQU87U0FDbEI7UUFDRDtZQUNFLE9BQU8sRUFBRSxJQUFJO1lBQ2IsVUFBVSxFQUFFLENBQUMsT0FBb0IsRUFBRSxVQUFlLEVBQUUsRUFBRTtnQkFDcEQsSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO29CQUNsQyxNQUFNLEVBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDN0IsSUFBSSxRQUFRO3dCQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFDM0IsT0FBTyxFQUFFLENBQUM7Z0JBQ1osQ0FBQztnQkFDRCxPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7WUFDRCxJQUFJLEVBQUUsQ0FBQyxZQUFZLEVBQUUsV0FBVyxDQUFDO1NBQ2xDO0tBQ0YsQ0FBQztBQUNKLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJ4REIsIFJ4REJPcHRpb25zIH0gZnJvbSAnQGFpYW8vcnhkYic7XG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBQTEFURk9STV9JRCwgUHJvdmlkZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJYREJfT1BUSU9OUyB9IGZyb20gJy4vcnhkYi5pbnRlcmZhY2UnO1xuXG4vKipcbiAqIFJ4REIg6YWN572uXG4gKi9cbmV4cG9ydCBjb25zdCBwcm92aWRlUnhEQiA9IChvcHRpb25zOiBSeERCT3B0aW9ucywgY2FsbGJhY2s/OiAoZGI6IFJ4REIpID0+IHZvaWQpOiBQcm92aWRlcltdID0+IHtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBSWERCX09QVElPTlMsXG4gICAgICB1c2VWYWx1ZTogb3B0aW9uc1xuICAgIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogUnhEQixcbiAgICAgIHVzZUZhY3Rvcnk6IChvcHRpb25zOiBSeERCT3B0aW9ucywgcGxhdGZvcm1JZDogYW55KSA9PiB7XG4gICAgICAgIGlmIChpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKSkge1xuICAgICAgICAgIGNvbnN0IGRiID0gbmV3IFJ4REIob3B0aW9ucyk7XG4gICAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjayhkYik7XG4gICAgICAgICAgcmV0dXJuIGRiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSxcbiAgICAgIGRlcHM6IFtSWERCX09QVElPTlMsIFBMQVRGT1JNX0lEXVxuICAgIH1cbiAgXTtcbn07XG4iXX0=","import { Injectable } from '@angular/core';\nimport * as i0 from \"@angular/core\";\nexport class RxDBService {\n static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"20.1.7\", ngImport: i0, type: RxDBService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });\n static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"20.1.7\", ngImport: i0, type: RxDBService, providedIn: 'root' });\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"20.1.7\", ngImport: i0, type: RxDBService, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }] });\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnhkYi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGFja2FnZXMvcnhkYi1hbmd1bGFyL3NyYy9yeGRiLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFHM0MsTUFBTSxPQUFPLFdBQVc7dUdBQVgsV0FBVzsyR0FBWCxXQUFXLGNBREUsTUFBTTs7MkZBQ25CLFdBQVc7a0JBRHZCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFJ4REJTZXJ2aWNlIHt9XG4iXX0=","/**\n * Generated bundle index. Do not edit.\n */\nexport * from './index';\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWlhby1yeGRiLWFuZ3VsYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9yeGRiLWFuZ3VsYXIvc3JjL2FpYW8tcnhkYi1hbmd1bGFyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19"],"names":[],"mappings":";;;;;AACO,MAAM,YAAY,GAAG,IAAI,cAAc,CAAC,cAAc,CAAC;;ACG9D;AACA;AACA;AACY,MAAC,WAAW,GAAG,CAAC,OAAO,EAAE,QAAQ,KAAK;AAClD,IAAI,OAAO;AACX,QAAQ;AACR,YAAY,OAAO,EAAE,YAAY;AACjC,YAAY,QAAQ,EAAE;AACtB,SAAS;AACT,QAAQ;AACR,YAAY,OAAO,EAAE,IAAI;AACzB,YAAY,UAAU,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK;AACjD,gBAAgB,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE;AACnD,oBAAoB,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC;AAChD,oBAAoB,IAAI,QAAQ;AAChC,wBAAwB,QAAQ,CAAC,EAAE,CAAC;AACpC,oBAAoB,OAAO,EAAE;AAC7B,gBAAgB;AAChB,gBAAgB,OAAO,IAAI;AAC3B,YAAY,CAAC;AACb,YAAY,IAAI,EAAE,CAAC,YAAY,EAAE,WAAW;AAC5C;AACA,KAAK;AACL;;ACzBO,MAAM,WAAW,CAAC;AACzB,IAAI,OAAO,IAAI,GAAG,EAAE,CAAC,kBAAkB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,UAAU,EAAE,CAAC;AACtK,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC,qBAAqB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AAC7I;AACA,EAAE,CAAC,wBAAwB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACrH,YAAY,IAAI,EAAE,UAAU;AAC5B,YAAY,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE;AACzC,SAAS,CAAC,EAAE,CAAC;;ACTb;AACA;AACA;;;;"}
1
+ {"version":3,"file":"aiao-rxdb-angular.mjs","sources":["../../../../packages/rxdb-angular/src/hooks.ts","../../../../packages/rxdb-angular/src/InfiniteScrollingList.ts","../../../../packages/rxdb-angular/src/rxdb-change-detector.directive.ts","../../../../packages/rxdb-angular/src/rxdb.provider.ts","../../../../packages/rxdb-angular/src/use-action.ts","../../../../packages/rxdb-angular/src/use-state.ts","../../../../packages/rxdb-angular/src/aiao-rxdb-angular.ts"],"sourcesContent":["import { EntityStaticType, EntityType, TreeEntityType } from '@aiao/rxdb';\nimport { GraphEntityType } from '@aiao/rxdb-plugin-graph';\nimport { isFunction } from '@aiao/utils';\nimport { effect, Signal, signal } from '@angular/core';\nimport { toLazySignal } from 'ngxtension/to-lazy-signal';\nimport { Observable, Subscriber, Subscription } from 'rxjs';\n\ntype UseOptions<T> = T | (() => T);\n\nexport interface RxDBResource<T> {\n /**\n * 资源的值\n */\n readonly value: Signal<T>;\n /**\n * 资源的错误\n */\n readonly error: Signal<Error | undefined>;\n /**\n * 资源的加载状态\n */\n readonly isLoading: Signal<boolean>;\n /**\n * 资源是否为空\n */\n readonly isEmpty: Signal<boolean | undefined>;\n /**\n * 资源是否有值\n */\n readonly hasValue: Signal<boolean>;\n}\n\nexport const useRepositoryQuery = <T extends EntityType, RT>(\n EntityType: T,\n method: string,\n defaultValue: any,\n options: UseOptions<any>\n): RxDBResource<RT> => {\n let _observer: Subscriber<any>;\n let sub: Subscription;\n\n const _has_sub = signal<boolean>(false);\n const _refresh = signal<number>(0);\n\n const _eff = effect(() => {\n if (_has_sub() === false) return;\n // re-run when refresh is called or options change\n _refresh();\n const opt = isFunction(options) ? options() : options;\n if (sub) sub.unsubscribe();\n // reset state for a new request\n isLoading.set(true);\n error.set(undefined);\n hasValue.set(false);\n isEmpty.set(undefined);\n // 优化:使用 Record<string, any> 替代 any,以提高类型安全性\n const func = (EntityType as unknown as Record<string, any>)[method];\n sub =\n func &&\n func(opt).subscribe({\n next: (d: any) => {\n isLoading.set(false);\n hasValue.set(true);\n if (Array.isArray(d)) {\n isEmpty.set(d.length === 0);\n } else if (d == null) {\n // null/undefined treated as empty\n isEmpty.set(true);\n } else {\n isEmpty.set(false);\n }\n _observer.next(d);\n },\n error: (e: any) => {\n isLoading.set(false);\n error.set(e);\n },\n complete: () => {\n // ensure loading is false even if observable completes without next\n isLoading.set(false);\n }\n });\n });\n const ob = new Observable<RT>(observer => {\n _has_sub.set(true);\n _observer = observer;\n _observer.next(defaultValue);\n return () => {\n _eff.destroy();\n sub?.unsubscribe();\n };\n });\n\n const value = toLazySignal<RT>(ob, {\n initialValue: defaultValue\n }) as Signal<RT>;\n const error = signal<Error | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n const hasValue = signal<boolean>(false);\n const isEmpty = signal<boolean | undefined>(undefined);\n return {\n value,\n error,\n isLoading,\n isEmpty,\n hasValue\n };\n};\n\n/*\n * Repository\n */\n\n/**\n * 通过 ID 获取单个实体\n *\n * @param EntityType 实体类\n * @param options 实体 ID 或查询参数对象\n * @returns 返回包含实体的资源 signal\n *\n * @example\n * ```typescript\n * const user = useGet(User, 'user-1');\n * ```\n */\nexport const useGet = <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, 'getOptions'>>) =>\n useRepositoryQuery<T, InstanceType<T>>(EntityType, 'get', undefined, options);\n\n/**\n * 查找第一个匹配条件的实体\n *\n * @param EntityType 实体类\n * @param options 查询参数(where、排序等)\n * @returns 返回包含实体的资源 signal\n */\nexport const useFindOne = <T extends EntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findOneOptions'>>\n) => useRepositoryQuery<T, InstanceType<T> | undefined>(EntityType, 'findOne', undefined, options);\n\n/**\n * 查找匹配的实体,未找到则抛出错误\n *\n * @param EntityType 实体类\n * @param options 查询参数\n * @returns 返回包含实体的资源 signal\n */\nexport const useFindOneOrFail = <T extends EntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findOneOrFailOptions'>>\n) => useRepositoryQuery<T, InstanceType<T>>(EntityType, 'findOneOrFail', undefined, options);\n\n/**\n * 查找符合条件的多个实体\n *\n * @param EntityType 实体类\n * @param options 查询参数\n * @returns 返回包含实体数组的资源 signal\n */\nexport const useFind = <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, 'findOptions'>>) =>\n useRepositoryQuery<T, InstanceType<T>[]>(EntityType, 'find', [], options);\n\n/**\n * 使用游标分页查找实体\n *\n * @param EntityType 实体类\n * @param options 游标参数\n * @returns 返回包含实体数组的资源 signal\n */\nexport const useFindByCursor = <T extends EntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findByCursorOptions'>>\n) => useRepositoryQuery<T, InstanceType<T>[]>(EntityType, 'findByCursor', [], options);\n\n/**\n * 查找全部实体\n *\n * @param EntityType 实体类\n * @param options 查询参数\n * @returns 返回包含全部实体的资源 signal\n */\nexport const useFindAll = <T extends EntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findAllOptions'>>\n) => useRepositoryQuery<T, InstanceType<T>[]>(EntityType, 'findAll', [], options);\n\n/**\n * 统计满足条件的实体数量\n *\n * @param EntityType 实体类\n * @param options 查询参数\n * @returns 返回包含数量的资源 signal\n */\nexport const useCount = <T extends EntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'countOptions'>>\n) => useRepositoryQuery<T, number>(EntityType, 'count', undefined, options);\n\n/*\n * TreeRepository\n */\n\n/**\n * 查找树结构中的所有子孙实体\n *\n * @param EntityType 实体类\n * @param options 树查询参数(entityId、深度等)\n * @returns 返回包含子孙实体的资源 signal\n */\nexport const useFindDescendants = <T extends TreeEntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findTreeOptions'>>\n) => useRepositoryQuery<T, InstanceType<T>[]>(EntityType, 'findDescendants', [], options);\n\n/**\n * 统计树结构中的子孙数量\n *\n * @param EntityType 实体类\n * @param options 树查询参数\n * @returns 返回包含数量的资源 signal\n */\nexport const useCountDescendants = <T extends TreeEntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findTreeOptions'>>\n) => useRepositoryQuery<T, number>(EntityType, 'countDescendants', undefined, options);\n\n/**\n * 查找树结构中的所有祖先实体\n *\n * @param EntityType 实体类\n * @param options 树查询参数\n * @returns 返回包含祖先实体的资源 signal\n */\nexport const useFindAncestors = <T extends TreeEntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findTreeOptions'>>\n) => useRepositoryQuery<T, InstanceType<T>[]>(EntityType, 'findAncestors', [], options);\n\n/**\n * 统计树结构中的祖先数量\n *\n * @param EntityType 实体类\n * @param options 树查询参数\n * @returns 返回包含数量的资源 signal\n */\nexport const useCountAncestors = <T extends TreeEntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findTreeOptions'>>\n) => useRepositoryQuery<T, number>(EntityType, 'countAncestors', undefined, options);\n\n/*\n * GraphRepository\n */\n\n/**\n * 查找图结构中的邻接实体\n *\n * @param EntityType 实体类\n * @param options 图查询参数(entityId、方向、层级等)\n * @returns 返回包含邻居实体的资源 signal\n *\n * @example\n * ```typescript\n * const friends = useGraphNeighbors(User, {\n * entityId: 'user-1',\n * direction: 'out',\n * level: 1\n * });\n * ```\n */\nexport const useGraphNeighbors = <T extends GraphEntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findNeighborsOptions'>>\n) => useRepositoryQuery<T, InstanceType<T>[]>(EntityType, 'findNeighbors', [], options);\n\n/**\n * 统计图结构中的邻接数量\n *\n * @param EntityType 实体类\n * @param options 图查询参数\n * @returns 返回包含数量的资源 signal\n */\nexport const useCountNeighbors = <T extends GraphEntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findNeighborsOptions'>>\n) => useRepositoryQuery<T, number>(EntityType, 'countNeighbors', 0, options);\n\n/**\n * 查找图结构中两个实体之间的路径\n *\n * @param EntityType 实体类\n * @param options 路径查询参数(fromId、toId、最大深度等)\n * @returns 返回包含路径的资源 signal\n *\n * @example\n * ```typescript\n * const paths = useGraphPaths(User, {\n * fromId: 'user-1',\n * toId: 'user-2',\n * maxDepth: 5\n * });\n * ```\n */\nexport const useGraphPaths = <T extends GraphEntityType>(\n EntityType: T,\n options: UseOptions<EntityStaticType<T, 'findPathsOptions'>>\n) => useRepositoryQuery<T, any[]>(EntityType, 'findPaths', [], options);\n","import { EntityType, FindByCursorOptions, RxDB } from '@aiao/rxdb';\nimport { isFunction, nextMicroTask } from '@aiao/utils';\nimport { computed, DestroyRef, effect, EffectRef, inject, Signal, signal, untracked } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\ntype OptionsInput<T extends EntityType> = FindByCursorOptions<T> | Signal<FindByCursorOptions<T>>;\n\n/**\n * 无限滚动的列表\n */\nexport class InfiniteScrollingList<T extends EntityType> {\n readonly #values = signal<InstanceType<T>[][]>([]);\n readonly #destroy_ref = inject(DestroyRef);\n readonly #options_eff: EffectRef;\n\n #is_initialized = false;\n\n readonly error = signal<Error | undefined>(undefined);\n readonly isLoading = signal<boolean>(false);\n readonly hasMore = signal<boolean>(true);\n readonly value = computed<InstanceType<T>[]>(() => this.#values().flat());\n readonly hasValue = computed<boolean>(() => this.value().length > 0);\n readonly isEmpty = computed<boolean>(() => !this.isLoading() && !this.hasValue() && this.#is_initialized);\n\n constructor(\n private readonly rxdb: RxDB,\n private readonly EntityType: T,\n private readonly options: OptionsInput<T>\n ) {\n this.#options_eff = effect(() => {\n if (isFunction(this.options)) {\n this.options();\n }\n if (!this.#is_initialized) {\n this.#is_initialized = true;\n nextMicroTask(() => this.loadMore());\n return;\n }\n untracked(() => this.#reset());\n });\n\n this.#destroy_ref.onDestroy(() => {\n this.#options_eff.destroy();\n });\n }\n\n loadMore(): void {\n if (this.isLoading() || !this.hasMore()) {\n return;\n }\n\n this.isLoading.set(true);\n this.error.set(undefined);\n\n const last_entity = this.#get_last_entity();\n const opt = isFunction(this.options) ? this.options() : this.options;\n const options = structuredClone(opt);\n\n if (last_entity) {\n options.after = last_entity;\n }\n\n const current_index = this.#values().length;\n\n this.rxdb.entityManager\n .getRepository(this.EntityType)\n .findByCursor(options)\n .pipe(takeUntilDestroyed(this.#destroy_ref))\n .subscribe({\n next: result => {\n this.isLoading.set(false);\n this.#values.update(values => {\n const updated = [...values];\n updated[current_index] = result;\n return updated;\n });\n\n if (result.length < (options.limit || 100)) {\n this.hasMore.set(false);\n }\n },\n error: error => {\n this.isLoading.set(false);\n this.error.set(error);\n },\n complete: () => {\n this.hasMore.set(false);\n this.isLoading.set(false);\n }\n });\n }\n\n /**\n * 刷新列表数据\n */\n refresh(): void {\n // 强制重置状态,即使正在加载中\n this.#values.set([]);\n this.error.set(undefined);\n this.isLoading.set(false); // 强制设置为 false,允许新的 loadMore\n this.hasMore.set(true);\n\n // 立即开始加载\n this.loadMore();\n }\n #reset(): void {\n this.#values.set([]);\n this.error.set(undefined);\n this.isLoading.set(false);\n this.hasMore.set(true);\n nextMicroTask(() => this.loadMore());\n }\n\n #get_last_entity(): InstanceType<T> | undefined {\n const values = this.#values();\n if (values.length === 0) return undefined;\n\n const last_page = values[values.length - 1];\n if (last_page.length === 0) return undefined;\n\n return last_page[last_page.length - 1];\n }\n}\n","import { EntityType, getEntityStatus } from '@aiao/rxdb';\nimport { ChangeDetectorRef, DestroyRef, Directive, effect, inject, input } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { auditTime, debounceTime, Subscription } from 'rxjs';\n\n/**\n * RxDB 实体变化指令\n * 如果你使用了 `changeDetection: ChangeDetectionStrategy.OnPush`\n * 那么正在输入的变化不会触发 angular 渲染机制,使用这个指令可以实现实时渲染\n *\n * @example\n * 当修改实体时,需要在多个地方预览修改变化时,可以使用这个指令\n */\n@Directive({ selector: '[rxdbChangeDetector]' })\nexport class RxDBEntityChangeDirective {\n #destroyRef = inject(DestroyRef);\n #changeDetectorRef = inject(ChangeDetectorRef);\n #sub?: Subscription;\n public readonly rxdbChangeDetector = input<InstanceType<EntityType>>();\n public readonly debounceTime = input<number>(0);\n public readonly auditTime = input<number>(0);\n\n constructor() {\n effect(() => {\n const rxdbChange = this.rxdbChangeDetector();\n const dt = this.debounceTime();\n const at = this.auditTime();\n const status = getEntityStatus(rxdbChange);\n this.#sub?.unsubscribe();\n this.#sub = status.patches$\n .pipe(takeUntilDestroyed(this.#destroyRef), debounceTime(dt), auditTime(at))\n .subscribe(() => this.#changeDetectorRef.markForCheck());\n });\n }\n}\n","import { RxDB } from '@aiao/rxdb';\nimport { makeEnvironmentProviders } from '@angular/core';\n\n/**\n * RxDB 配置\n */\nexport const provideRxDB = (useFactory?: () => RxDB) =>\n makeEnvironmentProviders([\n {\n provide: RxDB,\n useFactory\n }\n ]);\n","import { signal } from '@angular/core';\n\nconst action = <Options = any, RT = any>(promiseFn: (options?: Options) => Promise<RT>) => {\n const isPending = signal<boolean>(false);\n return {\n isPending,\n execute: async (options?: Options) => {\n isPending.set(true);\n try {\n const d = await promiseFn(options);\n return d;\n } finally {\n isPending.set(false);\n }\n }\n };\n};\n\nexport const useAction = <Options = any, RT = any>(promiseFn: (options?: Options) => Promise<RT>) =>\n action<Options, RT>(promiseFn);\n","import { IS_BROWSER } from '@aiao/utils';\nimport { CreateSignalOptions, effect, signal as ngSignal, WritableSignal } from '@angular/core';\n\nfunction state(namespace: string) {\n return (name: string) => {\n const signal = <T>(initialValue: T, options?: CreateSignalOptions<T>): WritableSignal<T> => {\n if (IS_BROWSER) {\n const value = localStorage.getItem(`${namespace}:${name}`);\n if (value) {\n initialValue = JSON.parse(value);\n }\n }\n const a = ngSignal<T>(initialValue, options);\n effect(() => {\n if (IS_BROWSER) {\n localStorage.setItem(`${namespace}:${name}`, JSON.stringify(a()));\n }\n });\n return a;\n };\n\n return {\n signal\n };\n };\n}\n\nexport const useState = (namespace: string) => state(namespace);\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["signal","ngSignal"],"mappings":"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"}
package/package.json CHANGED
@@ -1,23 +1,26 @@
1
1
  {
2
2
  "name": "@aiao/rxdb-angular",
3
- "version": "0.0.3",
4
3
  "peerDependencies": {
5
- "@aiao/rxdb": "0.0.3",
6
- "@angular/core": "~20.1.6",
7
- "@angular/common": "~20.1.6"
4
+ "@aiao/rxdb": "^0.0.8",
5
+ "@aiao/rxdb-plugin-graph": "^0.0.8",
6
+ "@aiao/utils": "^0.0.8",
7
+ "@angular/core": ">=20.0.0",
8
+ "ngxtension": "^7.0.1",
9
+ "rxjs": "^7.8.2"
8
10
  },
9
- "sideEffects": false,
10
11
  "publishConfig": {
11
12
  "access": "public"
12
13
  },
14
+ "sideEffects": false,
15
+ "version": "0.0.8",
13
16
  "module": "fesm2022/aiao-rxdb-angular.mjs",
14
- "typings": "index.d.ts",
17
+ "typings": "types/aiao-rxdb-angular.d.ts",
15
18
  "exports": {
16
19
  "./package.json": {
17
20
  "default": "./package.json"
18
21
  },
19
22
  ".": {
20
- "types": "./index.d.ts",
23
+ "types": "./types/aiao-rxdb-angular.d.ts",
21
24
  "default": "./fesm2022/aiao-rxdb-angular.mjs"
22
25
  }
23
26
  },
@@ -0,0 +1,222 @@
1
+ import { EntityType, EntityStaticType, TreeEntityType, RxDB, FindByCursorOptions } from '@aiao/rxdb';
2
+ import { GraphEntityType } from '@aiao/rxdb-plugin-graph';
3
+ import * as _angular_core from '@angular/core';
4
+ import { Signal, CreateSignalOptions, WritableSignal } from '@angular/core';
5
+
6
+ type UseOptions<T> = T | (() => T);
7
+ interface RxDBResource<T> {
8
+ /**
9
+ * 资源的值
10
+ */
11
+ readonly value: Signal<T>;
12
+ /**
13
+ * 资源的错误
14
+ */
15
+ readonly error: Signal<Error | undefined>;
16
+ /**
17
+ * 资源的加载状态
18
+ */
19
+ readonly isLoading: Signal<boolean>;
20
+ /**
21
+ * 资源是否为空
22
+ */
23
+ readonly isEmpty: Signal<boolean | undefined>;
24
+ /**
25
+ * 资源是否有值
26
+ */
27
+ readonly hasValue: Signal<boolean>;
28
+ }
29
+ declare const useRepositoryQuery: <T extends EntityType, RT>(EntityType: T, method: string, defaultValue: any, options: UseOptions<any>) => RxDBResource<RT>;
30
+ /**
31
+ * 通过 ID 获取单个实体
32
+ *
33
+ * @param EntityType 实体类
34
+ * @param options 实体 ID 或查询参数对象
35
+ * @returns 返回包含实体的资源 signal
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const user = useGet(User, 'user-1');
40
+ * ```
41
+ */
42
+ declare const useGet: <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "getOptions">>) => RxDBResource<InstanceType<T>>;
43
+ /**
44
+ * 查找第一个匹配条件的实体
45
+ *
46
+ * @param EntityType 实体类
47
+ * @param options 查询参数(where、排序等)
48
+ * @returns 返回包含实体的资源 signal
49
+ */
50
+ declare const useFindOne: <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findOneOptions">>) => RxDBResource<InstanceType<T> | undefined>;
51
+ /**
52
+ * 查找匹配的实体,未找到则抛出错误
53
+ *
54
+ * @param EntityType 实体类
55
+ * @param options 查询参数
56
+ * @returns 返回包含实体的资源 signal
57
+ */
58
+ declare const useFindOneOrFail: <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findOneOrFailOptions">>) => RxDBResource<InstanceType<T>>;
59
+ /**
60
+ * 查找符合条件的多个实体
61
+ *
62
+ * @param EntityType 实体类
63
+ * @param options 查询参数
64
+ * @returns 返回包含实体数组的资源 signal
65
+ */
66
+ declare const useFind: <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findOptions">>) => RxDBResource<InstanceType<T>[]>;
67
+ /**
68
+ * 使用游标分页查找实体
69
+ *
70
+ * @param EntityType 实体类
71
+ * @param options 游标参数
72
+ * @returns 返回包含实体数组的资源 signal
73
+ */
74
+ declare const useFindByCursor: <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findByCursorOptions">>) => RxDBResource<InstanceType<T>[]>;
75
+ /**
76
+ * 查找全部实体
77
+ *
78
+ * @param EntityType 实体类
79
+ * @param options 查询参数
80
+ * @returns 返回包含全部实体的资源 signal
81
+ */
82
+ declare const useFindAll: <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findAllOptions">>) => RxDBResource<InstanceType<T>[]>;
83
+ /**
84
+ * 统计满足条件的实体数量
85
+ *
86
+ * @param EntityType 实体类
87
+ * @param options 查询参数
88
+ * @returns 返回包含数量的资源 signal
89
+ */
90
+ declare const useCount: <T extends EntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "countOptions">>) => RxDBResource<number>;
91
+ /**
92
+ * 查找树结构中的所有子孙实体
93
+ *
94
+ * @param EntityType 实体类
95
+ * @param options 树查询参数(entityId、深度等)
96
+ * @returns 返回包含子孙实体的资源 signal
97
+ */
98
+ declare const useFindDescendants: <T extends TreeEntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findTreeOptions">>) => RxDBResource<InstanceType<T>[]>;
99
+ /**
100
+ * 统计树结构中的子孙数量
101
+ *
102
+ * @param EntityType 实体类
103
+ * @param options 树查询参数
104
+ * @returns 返回包含数量的资源 signal
105
+ */
106
+ declare const useCountDescendants: <T extends TreeEntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findTreeOptions">>) => RxDBResource<number>;
107
+ /**
108
+ * 查找树结构中的所有祖先实体
109
+ *
110
+ * @param EntityType 实体类
111
+ * @param options 树查询参数
112
+ * @returns 返回包含祖先实体的资源 signal
113
+ */
114
+ declare const useFindAncestors: <T extends TreeEntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findTreeOptions">>) => RxDBResource<InstanceType<T>[]>;
115
+ /**
116
+ * 统计树结构中的祖先数量
117
+ *
118
+ * @param EntityType 实体类
119
+ * @param options 树查询参数
120
+ * @returns 返回包含数量的资源 signal
121
+ */
122
+ declare const useCountAncestors: <T extends TreeEntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findTreeOptions">>) => RxDBResource<number>;
123
+ /**
124
+ * 查找图结构中的邻接实体
125
+ *
126
+ * @param EntityType 实体类
127
+ * @param options 图查询参数(entityId、方向、层级等)
128
+ * @returns 返回包含邻居实体的资源 signal
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * const friends = useGraphNeighbors(User, {
133
+ * entityId: 'user-1',
134
+ * direction: 'out',
135
+ * level: 1
136
+ * });
137
+ * ```
138
+ */
139
+ declare const useGraphNeighbors: <T extends GraphEntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findNeighborsOptions">>) => RxDBResource<InstanceType<T>[]>;
140
+ /**
141
+ * 统计图结构中的邻接数量
142
+ *
143
+ * @param EntityType 实体类
144
+ * @param options 图查询参数
145
+ * @returns 返回包含数量的资源 signal
146
+ */
147
+ declare const useCountNeighbors: <T extends GraphEntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findNeighborsOptions">>) => RxDBResource<number>;
148
+ /**
149
+ * 查找图结构中两个实体之间的路径
150
+ *
151
+ * @param EntityType 实体类
152
+ * @param options 路径查询参数(fromId、toId、最大深度等)
153
+ * @returns 返回包含路径的资源 signal
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * const paths = useGraphPaths(User, {
158
+ * fromId: 'user-1',
159
+ * toId: 'user-2',
160
+ * maxDepth: 5
161
+ * });
162
+ * ```
163
+ */
164
+ declare const useGraphPaths: <T extends GraphEntityType>(EntityType: T, options: UseOptions<EntityStaticType<T, "findPathsOptions">>) => RxDBResource<any[]>;
165
+
166
+ type OptionsInput<T extends EntityType> = FindByCursorOptions<T> | Signal<FindByCursorOptions<T>>;
167
+ /**
168
+ * 无限滚动的列表
169
+ */
170
+ declare class InfiniteScrollingList<T extends EntityType> {
171
+ #private;
172
+ private readonly rxdb;
173
+ private readonly EntityType;
174
+ private readonly options;
175
+ readonly error: _angular_core.WritableSignal<Error | undefined>;
176
+ readonly isLoading: _angular_core.WritableSignal<boolean>;
177
+ readonly hasMore: _angular_core.WritableSignal<boolean>;
178
+ readonly value: Signal<InstanceType<T>[]>;
179
+ readonly hasValue: Signal<boolean>;
180
+ readonly isEmpty: Signal<boolean>;
181
+ constructor(rxdb: RxDB, EntityType: T, options: OptionsInput<T>);
182
+ loadMore(): void;
183
+ /**
184
+ * 刷新列表数据
185
+ */
186
+ refresh(): void;
187
+ }
188
+
189
+ /**
190
+ * RxDB 实体变化指令
191
+ * 如果你使用了 `changeDetection: ChangeDetectionStrategy.OnPush`
192
+ * 那么正在输入的变化不会触发 angular 渲染机制,使用这个指令可以实现实时渲染
193
+ *
194
+ * @example
195
+ * 当修改实体时,需要在多个地方预览修改变化时,可以使用这个指令
196
+ */
197
+ declare class RxDBEntityChangeDirective {
198
+ #private;
199
+ readonly rxdbChangeDetector: _angular_core.InputSignal<any>;
200
+ readonly debounceTime: _angular_core.InputSignal<number>;
201
+ readonly auditTime: _angular_core.InputSignal<number>;
202
+ constructor();
203
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<RxDBEntityChangeDirective, never>;
204
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RxDBEntityChangeDirective, "[rxdbChangeDetector]", never, { "rxdbChangeDetector": { "alias": "rxdbChangeDetector"; "required": false; "isSignal": true; }; "debounceTime": { "alias": "debounceTime"; "required": false; "isSignal": true; }; "auditTime": { "alias": "auditTime"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
205
+ }
206
+
207
+ /**
208
+ * RxDB 配置
209
+ */
210
+ declare const provideRxDB: (useFactory?: () => RxDB) => _angular_core.EnvironmentProviders;
211
+
212
+ declare const useAction: <Options = any, RT = any>(promiseFn: (options?: Options) => Promise<RT>) => {
213
+ isPending: _angular_core.WritableSignal<boolean>;
214
+ execute: (options?: Options | undefined) => Promise<RT>;
215
+ };
216
+
217
+ declare const useState: (namespace: string) => (name: string) => {
218
+ signal: <T>(initialValue: T, options?: CreateSignalOptions<T>) => WritableSignal<T>;
219
+ };
220
+
221
+ export { InfiniteScrollingList, RxDBEntityChangeDirective, provideRxDB, useAction, useCount, useCountAncestors, useCountDescendants, useCountNeighbors, useFind, useFindAll, useFindAncestors, useFindByCursor, useFindDescendants, useFindOne, useFindOneOrFail, useGet, useGraphNeighbors, useGraphPaths, useRepositoryQuery, useState };
222
+ export type { RxDBResource };
package/index.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import { RxDBOptions, RxDB } from '@aiao/rxdb';
2
- import * as i0 from '@angular/core';
3
- import { Provider } from '@angular/core';
4
-
5
- /**
6
- * RxDB 配置
7
- */
8
- declare const provideRxDB: (options: RxDBOptions, callback?: (db: RxDB) => void) => Provider[];
9
-
10
- declare class RxDBService {
11
- static ɵfac: i0.ɵɵFactoryDeclaration<RxDBService, never>;
12
- static ɵprov: i0.ɵɵInjectableDeclaration<RxDBService>;
13
- }
14
-
15
- export { RxDBService, provideRxDB };