@signaldb/core 2.0.0-beta.2 → 2.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/.vite/manifest.json +183 -80
  2. package/dist/AsyncDataAdapter.d.ts +53 -7
  3. package/dist/AutoFetchDataAdapter.d.ts +4 -6
  4. package/dist/Collection/Cursor.d.ts +56 -4
  5. package/dist/Collection/Observer.d.ts +33 -0
  6. package/dist/Collection/index.d.ts +66 -19
  7. package/dist/Collection/types.d.ts +9 -2
  8. package/dist/DataAdapter.d.ts +24 -6
  9. package/dist/DefaultDataAdapter.d.ts +5 -5
  10. package/dist/WorkerDataAdapter.d.ts +57 -5
  11. package/dist/WorkerDataAdapterHost.d.ts +9 -7
  12. package/dist/createIndex.d.ts +2 -2
  13. package/dist/createIndexProvider.d.ts +2 -2
  14. package/dist/createReactivityAdapter.d.ts +2 -2
  15. package/dist/createStorageAdapter.d.ts +1 -1
  16. package/dist/getIndexInfo.d.ts +3 -4
  17. package/dist/index.cjs.js +33 -31
  18. package/dist/index.d.ts +6 -1
  19. package/dist/index.mjs +17 -32
  20. package/dist/index10.cjs.js +11 -0
  21. package/dist/index10.mjs +10 -18
  22. package/dist/index11.cjs.js +23 -0
  23. package/dist/index11.mjs +22 -15
  24. package/dist/index12.cjs.js +45 -0
  25. package/dist/index12.mjs +44 -353
  26. package/dist/index13.cjs.js +22 -0
  27. package/dist/index13.mjs +21 -419
  28. package/dist/index14.cjs.js +45 -0
  29. package/dist/index14.mjs +44 -206
  30. package/dist/index15.cjs.js +86 -0
  31. package/dist/index15.mjs +85 -388
  32. package/dist/index16.cjs.js +15 -0
  33. package/dist/index16.mjs +14 -579
  34. package/dist/index17.cjs.js +141 -0
  35. package/dist/index17.mjs +140 -152
  36. package/dist/index18.cjs.js +47 -0
  37. package/dist/index18.mjs +46 -26
  38. package/dist/index19.cjs.js +15 -0
  39. package/dist/index19.mjs +14 -41
  40. package/dist/index2.cjs.js +33 -0
  41. package/dist/index2.mjs +32 -258
  42. package/dist/index20.cjs.js +23 -0
  43. package/dist/index20.mjs +22 -16
  44. package/dist/index21.cjs.js +37 -0
  45. package/dist/index21.mjs +36 -104
  46. package/dist/index22.cjs.js +35 -0
  47. package/dist/index22.mjs +34 -128
  48. package/dist/index23.cjs.js +21 -0
  49. package/dist/index23.mjs +20 -7
  50. package/dist/index24.cjs.js +19 -0
  51. package/dist/index24.mjs +18 -27
  52. package/dist/index25.cjs.js +157 -0
  53. package/dist/index25.mjs +156 -11
  54. package/dist/index26.cjs.js +38 -0
  55. package/dist/index26.mjs +37 -29
  56. package/dist/index27.cjs.js +42 -0
  57. package/dist/index27.mjs +41 -46
  58. package/dist/index28.cjs.js +347 -0
  59. package/dist/index28.mjs +345 -7
  60. package/dist/index29.cjs.js +602 -0
  61. package/dist/index29.mjs +601 -7
  62. package/dist/index3.cjs.js +19 -0
  63. package/dist/index3.mjs +18 -556
  64. package/dist/index30.cjs.js +11 -0
  65. package/dist/index30.mjs +10 -42
  66. package/dist/index31.cjs.js +11 -0
  67. package/dist/index31.mjs +10 -29
  68. package/dist/index32.cjs.js +90 -0
  69. package/dist/index32.mjs +89 -10
  70. package/dist/index33.cjs.js +53 -0
  71. package/dist/index33.mjs +52 -5
  72. package/dist/index34.cjs.js +453 -0
  73. package/dist/index34.mjs +453 -0
  74. package/dist/index35.cjs.js +72 -0
  75. package/dist/index35.mjs +72 -0
  76. package/dist/index36.cjs.js +580 -0
  77. package/dist/index36.mjs +580 -0
  78. package/dist/index37.cjs.js +21 -0
  79. package/dist/index37.mjs +21 -0
  80. package/dist/index38.cjs.js +363 -0
  81. package/dist/index38.mjs +363 -0
  82. package/dist/index39.cjs.js +513 -0
  83. package/dist/index39.mjs +513 -0
  84. package/dist/index4.cjs.js +209 -0
  85. package/dist/index4.mjs +204 -5
  86. package/dist/index5.cjs.js +187 -0
  87. package/dist/index5.mjs +186 -5
  88. package/dist/index6.cjs.js +303 -0
  89. package/dist/index6.mjs +301 -28
  90. package/dist/index7.cjs.js +125 -0
  91. package/dist/index7.mjs +124 -12
  92. package/dist/index8.cjs.js +33 -0
  93. package/dist/index8.mjs +32 -5
  94. package/dist/index9.cjs.js +12 -0
  95. package/dist/index9.mjs +11 -133
  96. package/dist/types/IndexProvider.d.ts +2 -2
  97. package/dist/types/Modifier.d.ts +1 -1
  98. package/dist/types/ReactivityAdapter.d.ts +1 -1
  99. package/dist/types/StorageAdapter.d.ts +9 -1
  100. package/dist/utils/applyQueryOptions.d.ts +15 -0
  101. package/dist/utils/createSignal.d.ts +2 -2
  102. package/dist/utils/getMatchingKeys.d.ts +2 -2
  103. package/dist/utils/idIndexQuery.d.ts +20 -0
  104. package/dist/utils/incrementalQueryUpdate.d.ts +62 -0
  105. package/dist/utils/isFieldExpression.d.ts +1 -1
  106. package/dist/utils/match.d.ts +1 -1
  107. package/dist/utils/modify.d.ts +1 -1
  108. package/dist/utils/projectItems.d.ts +12 -0
  109. package/dist/utils/queryDelta.d.ts +83 -0
  110. package/dist/utils/queryId.d.ts +2 -2
  111. package/dist/utils/reactiveOrAsync.d.ts +59 -0
  112. package/dist/utils/storageIndexQuery.d.ts +20 -0
  113. package/package.json +1 -1
  114. package/dist/index.cjs10.js +0 -18
  115. package/dist/index.cjs11.js +0 -15
  116. package/dist/index.cjs12.js +0 -353
  117. package/dist/index.cjs13.js +0 -419
  118. package/dist/index.cjs14.js +0 -206
  119. package/dist/index.cjs15.js +0 -388
  120. package/dist/index.cjs16.js +0 -579
  121. package/dist/index.cjs17.js +0 -152
  122. package/dist/index.cjs18.js +0 -26
  123. package/dist/index.cjs19.js +0 -42
  124. package/dist/index.cjs2.js +0 -259
  125. package/dist/index.cjs20.js +0 -16
  126. package/dist/index.cjs21.js +0 -104
  127. package/dist/index.cjs22.js +0 -129
  128. package/dist/index.cjs23.js +0 -7
  129. package/dist/index.cjs24.js +0 -27
  130. package/dist/index.cjs25.js +0 -10
  131. package/dist/index.cjs26.js +0 -29
  132. package/dist/index.cjs27.js +0 -46
  133. package/dist/index.cjs28.js +0 -8
  134. package/dist/index.cjs29.js +0 -7
  135. package/dist/index.cjs3.js +0 -557
  136. package/dist/index.cjs30.js +0 -42
  137. package/dist/index.cjs31.js +0 -29
  138. package/dist/index.cjs32.js +0 -9
  139. package/dist/index.cjs33.js +0 -5
  140. package/dist/index.cjs4.js +0 -5
  141. package/dist/index.cjs5.js +0 -5
  142. package/dist/index.cjs6.js +0 -29
  143. package/dist/index.cjs7.js +0 -12
  144. package/dist/index.cjs8.js +0 -5
  145. package/dist/index.cjs9.js +0 -133
@@ -1,3 +1,4 @@
1
+ import { QueryDelta } from '../utils/queryDelta';
1
2
  type AddedCallback<T> = (item: T) => void;
2
3
  type AddedBeforeCallback<T> = (item: T, before: T) => void;
3
4
  type ChangedCallback<T> = (item: T) => void;
@@ -42,9 +43,41 @@ export default class Observer<T extends {
42
43
  * @param getItems - A function that returns a promise resolving to the new items or the items themselves.
43
44
  */
44
45
  runChecks(getItems: () => Promise<T[]> | T[]): void;
46
+ /**
47
+ * Brings the observer up to date from a description of what changed, instead of from the new
48
+ * result.
49
+ *
50
+ * `runChecks` has to rediscover the change by comparing the whole new result against the whole
51
+ * old one — a cost proportional to the result, paid on every write, to find out that one row
52
+ * moved. When the change is already known it can simply be reported, and the cost becomes
53
+ * proportional to the change.
54
+ *
55
+ * The delta must have been computed against exactly the result this observer holds. If it was
56
+ * not, this reports nothing, falls back to `runChecks`, and returns `false`.
57
+ *
58
+ * Note that the reported moves are minimal, where a comparison reports every item whose
59
+ * neighbour changed. Applying them yields the same order either way — there are simply fewer of
60
+ * them.
61
+ * @param delta - The change to report.
62
+ * @param getItems - Used to fall back to a comparison when the delta cannot be applied.
63
+ * @returns Whether the delta was applied.
64
+ */
65
+ applyDelta(delta: QueryDelta<T>, getItems: () => Promise<T[]> | T[]): boolean;
66
+ /**
67
+ * Reports a delta and adopts the result it produces.
68
+ *
69
+ * The single place the callbacks are fired from, whether the change arrived as a delta or was
70
+ * found by comparing two results — so the two can never disagree about what a consumer is told.
71
+ * @param delta - The change to report.
72
+ * @param nextItems - The result the delta produces.
73
+ */
74
+ private emitDelta;
75
+ private finishCheck;
45
76
  private checkItems;
77
+ private stopped;
46
78
  /**
47
79
  * Stops the observer by unbinding all events and cleaning up resources.
80
+ * Safe to call multiple times - will only unbind once.
48
81
  */
49
82
  stop(): void;
50
83
  /**
@@ -1,14 +1,13 @@
1
- import type ReactivityAdapter from '../types/ReactivityAdapter';
2
- import EventEmitter from '../utils/EventEmitter';
3
- import type Selector from '../types/Selector';
4
- import type Modifier from '../types/Modifier';
5
- import type DataAdapter from '../DataAdapter';
6
- import type { QueryOptions } from '../DataAdapter';
7
- import type StorageAdapter from '../types/StorageAdapter';
8
- import Cursor from './Cursor';
9
- import type { BaseItem, FindOptions, Transform, TransformAll } from './types';
10
- export type { BaseItem, Transform, TransformAll, SortSpecifier, FieldSpecifier, FindOptions } from './types';
11
- export type { CursorOptions } from './Cursor';
1
+ import { default as ReactivityAdapter } from '../types/ReactivityAdapter';
2
+ import { default as EventEmitter } from '../utils/EventEmitter';
3
+ import { default as Selector } from '../types/Selector';
4
+ import { default as Modifier } from '../types/Modifier';
5
+ import { default as DataAdapter, QueryOptions } from '../DataAdapter';
6
+ import { default as StorageAdapter } from '../types/StorageAdapter';
7
+ import { default as Cursor } from './Cursor';
8
+ import { AsyncFindOptions, BaseItem, FindOptions, SyncFindOptions, Transform, TransformAll } from './types';
9
+ export type { AnyFindOptions, AsyncFindOptions, BaseItem, Transform, TransformAll, SortSpecifier, FieldSpecifier, FindOptions, SyncFindOptions, } from './types';
10
+ export type { CursorOptions, QueryStateAccessor } from './Cursor';
12
11
  export type { ObserveCallbacks } from './Observer';
13
12
  export { default as createIndex } from '../createIndex';
14
13
  export interface CollectionOptions<T extends BaseItem<I>, I, E extends BaseItem = T, U = E> {
@@ -34,8 +33,14 @@ interface CollectionEvents<T extends BaseItem, E extends BaseItem = T, U = E> {
34
33
  'removed': (item: T) => void;
35
34
  'observer.created': <O extends QueryOptions<T>>(selector?: Selector<T>, options?: O) => void;
36
35
  'observer.disposed': <O extends QueryOptions<T>>(selector?: Selector<T>, options?: O) => void;
36
+ /**
37
+ * A query backing at least one live cursor failed and will not deliver
38
+ * results. The cursor keeps returning its neutral empty value, so without
39
+ * listening here a consumer cannot distinguish failure from "no data".
40
+ */
41
+ 'query.error': <O extends QueryOptions<T>>(error: Error, selector?: Selector<T>, options?: O) => void;
37
42
  'getItems': (selector: Selector<T> | undefined) => void;
38
- 'find': <O extends FindOptions<T, Async>, Async extends boolean>(selector: Selector<T> | undefined, options: O | undefined, cursor: Cursor<E, U, Async>) => void;
43
+ 'find': <Async extends boolean, O extends FindOptions<T, Async>>(selector: Selector<T> | undefined, options: O | undefined, cursor: Cursor<E, U, Async>) => void;
39
44
  'findOne': <O extends QueryOptions<T>>(selector: Selector<T>, options: O | undefined, item: U | undefined) => void;
40
45
  'insert': (item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
41
46
  'updateOne': (selector: Selector<T>, modifier: Modifier<T>) => void;
@@ -45,8 +50,8 @@ interface CollectionEvents<T extends BaseItem, E extends BaseItem = T, U = E> {
45
50
  'removeMany': (selector: Selector<T>) => void;
46
51
  'validate': (item: T) => void;
47
52
  '_debug.getItems': (callstack: string, selector: Selector<T> | undefined, measuredTime: number) => void;
48
- '_debug.find': <O extends FindOptions<T, Async>, Async extends boolean>(callstack: string, selector: Selector<T> | undefined, options: O | undefined, cursor: Cursor<E, U, Async>) => void;
49
- '_debug.findOne': <O extends FindOptions<T, Async>, Async extends boolean>(callstack: string, selector: Selector<T>, options: O | undefined, item: U | undefined) => void;
53
+ '_debug.find': <Async extends boolean, O extends FindOptions<T, Async>>(callstack: string, selector: Selector<T> | undefined, options: O | undefined, cursor: Cursor<E, U, Async>) => void;
54
+ '_debug.findOne': <Async extends boolean, O extends FindOptions<T, Async>>(callstack: string, selector: Selector<T>, options: O | undefined, item: U | undefined) => void;
50
55
  '_debug.insert': (callstack: string, item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
51
56
  '_debug.updateOne': (callstack: string, selector: Selector<T>, modifier: Modifier<T>) => void;
52
57
  '_debug.updateMany': (callstack: string, selector: Selector<T>, modifier: Modifier<T>) => void;
@@ -69,7 +74,22 @@ export default class Collection<T extends BaseItem<I> = BaseItem, I = any, E ext
69
74
  private static fieldTracking;
70
75
  private static onCreationCallbacks;
71
76
  private static onDisposeCallbacks;
77
+ private static largeQueryWarningThreshold;
78
+ private static reportedLargeQueries;
72
79
  static getCollections(): Collection<any, any, any, any>[];
80
+ /**
81
+ * Reports live queries whose result is larger than `rows`, once each, with
82
+ * the stack that registered them.
83
+ *
84
+ * A reactive query is re-evaluated whenever the data under it changes, and
85
+ * one registered from a long-lived place — a navigation bar, a provider
86
+ * near the root — keeps that cost for the lifetime of the application. There
87
+ * is otherwise nothing to see: the query works, and its price is only
88
+ * visible as an application that has grown slow. Finding one such query in a
89
+ * real app took a purpose-built profiler and the better part of a day.
90
+ * @param rows - Result size to report above, or `null` to switch the check off.
91
+ */
92
+ static reportLargeQueries(rows: number | null): void;
73
93
  static onCreation(callback: (collection: Collection<any>) => void): void;
74
94
  static onDispose(callback: (collection: Collection<any>) => void): void;
75
95
  /**
@@ -87,11 +107,27 @@ export default class Collection<T extends BaseItem<I> = BaseItem, I = any, E ext
87
107
  * This improves performance by avoiding repetitive index recalculations and
88
108
  * provides atomicity for the batch of operations.
89
109
  * Supports both synchronous and asynchronous callbacks.
110
+ *
111
+ * **Without a `collections` argument this affects every collection in the
112
+ * process, not only the ones being written to.** Each of them defers every
113
+ * live query's requery until the batch ends. That is what makes a batch
114
+ * cheap for a handful of writes belonging to one event, and what makes it
115
+ * dangerous around a loop whose length is data-dependent: while it is open
116
+ * nothing anywhere updates, and everything deferred is flushed at once when
117
+ * it closes. One application wrapped a sync of roughly 1,100 records this
118
+ * way and its screens stopped resolving their data for the whole drain.
119
+ *
120
+ * Pass the collections being written to whenever that scope is known — it is
121
+ * both cheaper and safer. `Collection.batch([logs, versions], () => …)`
122
+ * defers those two and leaves everything else live.
123
+ * @param collections - The collections to batch. Omit to batch all of them.
90
124
  * @param callback - The batch operation to execute.
91
125
  * @returns A promise if the callback returns a promise, otherwise `void`.
92
126
  */
93
127
  static batch<ReturnType>(callback: () => Promise<ReturnType>): Promise<void>;
94
128
  static batch<ReturnType>(callback: () => ReturnType): void;
129
+ static batch<ReturnType>(collections: Collection<any, any, any, any>[], callback: () => Promise<ReturnType>): Promise<void>;
130
+ static batch<ReturnType>(collections: Collection<any, any, any, any>[], callback: () => ReturnType): void;
95
131
  readonly name: string;
96
132
  private backend;
97
133
  private options;
@@ -104,6 +140,7 @@ export default class Collection<T extends BaseItem<I> = BaseItem, I = any, E ext
104
140
  private postBatchCallbacks;
105
141
  private fieldTracking;
106
142
  private queryListenersMap;
143
+ private settledQueriesSet;
107
144
  /**
108
145
  * Initializes a new instance of the `Collection` class with optional configuration.
109
146
  * Sets up memory, persistence, reactivity, and indices as specified in the options.
@@ -125,6 +162,15 @@ export default class Collection<T extends BaseItem<I> = BaseItem, I = any, E ext
125
162
  */
126
163
  constructor(options?: CollectionOptions<T, I, E, U>);
127
164
  constructor(name: string, dataAdapter: DataAdapter, options?: CollectionOptions<T, I, E, U>);
165
+ /**
166
+ * Reports a live query the first time its result is found to be larger than
167
+ * the configured threshold. Once per query, because it re-runs on every
168
+ * write and a warning per write would be its own performance problem.
169
+ * @param selector - The query's selector.
170
+ * @param options - The query's options.
171
+ * @param registrationStack - Where the query was registered, if captured.
172
+ */
173
+ private reportIfLargeQuery;
128
174
  isBatchOperationInProgress(): boolean;
129
175
  /**
130
176
  * Checks whether the collection is currently performing a pull operation
@@ -200,23 +246,24 @@ export default class Collection<T extends BaseItem<I> = BaseItem, I = any, E ext
200
246
  /**
201
247
  * Finds multiple items in the collection based on a selector and optional options.
202
248
  * Returns a cursor for reactive data queries.
203
- * @template O - The options type for the find operation.
204
249
  * @param [selector] - The criteria to select items.
205
250
  * @param [options] - Options for the find operation, such as limit and sort.
206
251
  * @returns A cursor to fetch and observe the matching items.
207
252
  */
208
- find<Async extends boolean = false, O extends FindOptions<T, Async> = FindOptions<T, Async>>(selector?: Selector<T>, options?: O): Cursor<E, U, Async>;
253
+ find(selector?: Selector<T>, options?: SyncFindOptions<T>): Cursor<E, U, false>;
254
+ find(selector: Selector<T> | undefined, options: AsyncFindOptions<T>): Cursor<E, U, true>;
255
+ find(selector?: Selector<T>, options?: FindOptions<T, boolean>): Cursor<E, U, boolean>;
209
256
  /**
210
257
  * Finds a single item in the collection based on a selector and optional options.
211
258
  * ⚡️ this function is reactive!
212
259
  * Returns the found item or undefined if no item matches.
213
- * @template Async - Whether to perform the operation asynchronously.
214
- * @template O - The options type for the find operation.
215
260
  * @param selector - The criteria to select the item.
216
261
  * @param [options] - Options for the find operation, such as projection.
217
262
  * @returns The found item or `undefined`.
218
263
  */
219
- findOne<Async extends boolean = false, O extends Omit<FindOptions<T, Async>, 'limit'> = Omit<FindOptions<T, Async>, 'limit'>>(selector: Selector<T>, options?: O): Async extends true ? Promise<U | undefined> : U | undefined;
264
+ findOne(selector: Selector<T>, options?: Omit<SyncFindOptions<T>, 'limit'>): U | undefined;
265
+ findOne(selector: Selector<T>, options: Omit<AsyncFindOptions<T>, 'limit'>): Promise<U | undefined>;
266
+ findOne(selector: Selector<T>, options?: Omit<FindOptions<T, boolean>, 'limit'>): Promise<U | undefined> | U | undefined;
220
267
  /**
221
268
  * Performs a batch operation, deferring index rebuilds and allowing multiple
222
269
  * modifications to be made atomically. Executes any post-batch callbacks afterwards.
@@ -1,5 +1,5 @@
1
- import type { QueryOptions } from '../DataAdapter';
2
- import type ReactivityAdapter from '../types/ReactivityAdapter';
1
+ import { QueryOptions } from '../DataAdapter';
2
+ import { default as ReactivityAdapter } from '../types/ReactivityAdapter';
3
3
  export type BaseItem<I = any> = {
4
4
  id: I;
5
5
  } & Record<string, any>;
@@ -19,3 +19,10 @@ export interface FindOptions<T extends BaseItem, Async extends boolean> extends
19
19
  /** pass `true` to execute the query asynchronously */
20
20
  async?: Async;
21
21
  }
22
+ export type AsyncFindOptions<T extends BaseItem> = Omit<FindOptions<T, true>, 'async'> & {
23
+ async: true;
24
+ };
25
+ export type SyncFindOptions<T extends BaseItem> = Omit<FindOptions<T, false>, 'async'> & {
26
+ async?: false;
27
+ };
28
+ export type AnyFindOptions<T extends BaseItem> = AsyncFindOptions<T> | SyncFindOptions<T>;
@@ -1,7 +1,7 @@
1
- import type { BaseItem, FieldSpecifier, SortSpecifier } from './Collection';
2
- import type Collection from './Collection';
3
- import type Modifier from './types/Modifier';
4
- import type Selector from './types/Selector';
1
+ import { BaseItem, FieldSpecifier, SortSpecifier, default as Collection } from './Collection';
2
+ import { default as Modifier } from './types/Modifier';
3
+ import { default as Selector } from './types/Selector';
4
+ import { QueryDelta } from './utils/queryDelta';
5
5
  export interface QueryOptions<T extends BaseItem> {
6
6
  /** Sort order (default: natural order) */
7
7
  sort?: SortSpecifier<T> | undefined;
@@ -12,7 +12,19 @@ export interface QueryOptions<T extends BaseItem> {
12
12
  /** Dictionary of fields to return or exclude. */
13
13
  fields?: FieldSpecifier<T> | undefined;
14
14
  }
15
- export type StateChangeCallback = (state: 'active' | 'complete' | 'error') => void;
15
+ /**
16
+ * Notified when a query's state changes.
17
+ *
18
+ * A `'complete'` notification may carry a delta describing how the result changed since the last
19
+ * one. An adapter that can produce one saves its listeners from rediscovering the change by
20
+ * comparing the whole result against the whole previous result; one that cannot simply omits it,
21
+ * and its listeners fall back to exactly that comparison.
22
+ *
23
+ * A delta is only ever passed when it is relative to what `getQueryResult` returned the last time
24
+ * it was asked. An adapter that layers anything on top of its stored result — an optimistic write
25
+ * still in flight, for instance — must omit the delta for as long as it does.
26
+ */
27
+ export type StateChangeCallback<T extends BaseItem = BaseItem> = (state: 'active' | 'complete' | 'error', delta?: QueryDelta<T>) => void;
16
28
  export interface CollectionBackend<T extends BaseItem<I>, I> {
17
29
  insert(item: T): Promise<T>;
18
30
  updateOne(selector: Selector<T>, modifier: Modifier<T>): Promise<T[]>;
@@ -22,11 +34,17 @@ export interface CollectionBackend<T extends BaseItem<I>, I> {
22
34
  removeMany(selector: Selector<T>): Promise<T[]>;
23
35
  registerQuery<O extends QueryOptions<T>>(selector: Selector<T>, options: O): void;
24
36
  unregisterQuery<O extends QueryOptions<T>>(selector: Selector<T>, options: O): void;
37
+ /**
38
+ * Re-runs a query that is currently in the `'error'` state. Optional so
39
+ * existing custom adapters keep compiling — an adapter that never surfaces
40
+ * an error state has nothing to implement.
41
+ */
42
+ retryQuery?<O extends QueryOptions<T>>(selector: Selector<T>, options: O): void;
25
43
  getQueryState<O extends QueryOptions<T>>(selector: Selector<T>, options: O): 'active' | 'complete' | 'error';
26
44
  getQueryError<O extends QueryOptions<T>>(selector: Selector<T>, options: O): Error | null;
27
45
  getQueryResult<O extends QueryOptions<T>>(selector: Selector<T>, options: O): T[];
28
46
  executeQuery<O extends QueryOptions<T>>(selector: Selector<T>, options: O): Promise<T[]>;
29
- onQueryStateChange<O extends QueryOptions<T>>(selector: Selector<T>, options: O, callback: StateChangeCallback): () => void;
47
+ onQueryStateChange<O extends QueryOptions<T>>(selector: Selector<T>, options: O, callback: StateChangeCallback<T>): () => void;
30
48
  dispose(): Promise<void>;
31
49
  isReady(): Promise<void>;
32
50
  }
@@ -1,8 +1,6 @@
1
- import type { BaseItem } from './Collection';
2
- import type Collection from './Collection';
3
- import type DataAdapter from './DataAdapter';
4
- import type { CollectionBackend } from './DataAdapter';
5
- import type StorageAdapter from './types/StorageAdapter';
1
+ import { BaseItem, default as Collection } from './Collection';
2
+ import { default as DataAdapter, CollectionBackend } from './DataAdapter';
3
+ import { default as StorageAdapter } from './types/StorageAdapter';
6
4
  interface DefaultDataAdapterOptions {
7
5
  storage?: (name: string) => StorageAdapter<any, any> | undefined;
8
6
  onError?: (name: string, error: Error) => void;
@@ -11,6 +9,7 @@ export default class DefaultDataAdapter implements DataAdapter {
11
9
  private items;
12
10
  private options;
13
11
  private storageAdapters;
12
+ private collections;
14
13
  private indices;
15
14
  private activeQueries;
16
15
  private queryEmitters;
@@ -29,5 +28,6 @@ export default class DefaultDataAdapter implements DataAdapter {
29
28
  private executeAndCacheQuery;
30
29
  private updateQueries;
31
30
  createCollectionBackend<T extends BaseItem<I>, I = any, E extends BaseItem = T, U = E>(collection: Collection<T, I, E, U>, indices: string[]): CollectionBackend<T, I>;
31
+ fetchItemsFromStorage<T extends BaseItem<I>, I = any, E extends BaseItem = T, U = E>(collection?: Collection<T, I, E, U>): Promise<void>;
32
32
  }
33
33
  export {};
@@ -1,11 +1,15 @@
1
- import type { BaseItem } from './Collection';
2
- import type Collection from './Collection';
3
- import type DataAdapter from './DataAdapter';
4
- import type { CollectionBackend } from './DataAdapter';
1
+ import { BaseItem, default as Collection } from './Collection';
2
+ import { default as DataAdapter, CollectionBackend } from './DataAdapter';
5
3
  interface WorkerDataAdapterOptions {
6
4
  id?: string;
7
5
  log?: (message: string, ...args: any[]) => void;
8
6
  }
7
+ export interface WorkerDataAdapterEndpoint {
8
+ addEventListener: (type: 'message', listener: (event: MessageEvent) => void) => void;
9
+ removeEventListener: (type: 'message', listener: (event: MessageEvent) => void) => void;
10
+ postMessage: (message: unknown) => void;
11
+ terminate?: () => void;
12
+ }
9
13
  export default class WorkerDataAdapter implements DataAdapter {
10
14
  private worker;
11
15
  private options;
@@ -16,8 +20,56 @@ export default class WorkerDataAdapter implements DataAdapter {
16
20
  private collectionReady;
17
21
  private batchExecutionHelpers;
18
22
  private queries;
19
- constructor(worker: Worker, options: WorkerDataAdapterOptions);
23
+ private pendingRequests;
24
+ private pendingWrites;
25
+ private pendingWriteSeq;
26
+ private pendingWriteVersions;
27
+ private bumpPendingWriteVersion;
28
+ constructor(worker: WorkerDataAdapterEndpoint, options: WorkerDataAdapterOptions);
29
+ private resolveWorkerReady;
30
+ private handleWorkerMessage;
31
+ private handleQueryUpdate;
20
32
  private exec;
33
+ /**
34
+ * Issues a call whose result nobody is waiting for, and makes sure a failure has somewhere to
35
+ * go. A bare rejection here would surface as an uncaught error — which is what a disposed
36
+ * collection produced every time a cursor was cleaned up after it.
37
+ * @param method - The method to call on the worker.
38
+ * @param collectionName - The collection it applies to.
39
+ * @param args - The remaining arguments.
40
+ * @param onError - Called when the call fails, in place of merely logging it.
41
+ */
42
+ private execInBackground;
43
+ private queryItemsById;
44
+ private flattenPendingWrites;
45
+ private static pushPendingEntry;
46
+ private static dropPendingEntry;
47
+ private static writeFlatEntry;
48
+ private static providesFullItems;
49
+ private observableItems;
50
+ private observableItemsByIds;
51
+ private servedResult;
52
+ private advanceServedResult;
53
+ private changesetForIds;
54
+ private computeServedResult;
55
+ /**
56
+ * Registers a write's effect locally and notifies every active query it
57
+ * touches, then returns a function that drops it again once the write
58
+ * settles.
59
+ * @param collectionName - The collection the write targets.
60
+ * @param upserts - Items inserted or updated by the write.
61
+ * @param deletes - Ids removed by the write.
62
+ * @returns A function that drops the pending write and re-notifies.
63
+ */
64
+ private applyPendingWrite;
65
+ private affectedQueries;
66
+ private servedResults;
67
+ private notifyWithDeltas;
68
+ private matchObservableItems;
69
+ private resolveUpdate;
70
+ private resolveRemoval;
71
+ private resolveReplacement;
72
+ private withPendingWrite;
21
73
  private enqueueBatched;
22
74
  private updateQuery;
23
75
  createCollectionBackend<T extends BaseItem<I>, I = any, E extends BaseItem = T, U = E>(collection: Collection<T, I, E, U>, indices: string[]): CollectionBackend<T, I>;
@@ -1,9 +1,9 @@
1
- import type { BaseItem } from './Collection';
2
- import type { QueryOptions } from './DataAdapter';
3
- import type Modifier from './types/Modifier';
4
- import type StorageAdapter from './types/StorageAdapter';
5
- import type Selector from './types/Selector';
6
- interface WorkerContext {
1
+ import { BaseItem } from './Collection';
2
+ import { QueryOptions } from './DataAdapter';
3
+ import { default as Modifier } from './types/Modifier';
4
+ import { default as StorageAdapter } from './types/StorageAdapter';
5
+ import { default as Selector } from './types/Selector';
6
+ export interface WorkerDataAdapterHostEndpoint {
7
7
  addEventListener: (type: 'message', listener: (event: MessageEvent) => any) => void;
8
8
  postMessage: (message: any) => void;
9
9
  }
@@ -37,13 +37,15 @@ export default class WorkerDataAdapterHost<T extends BaseItem<I>, I = any> {
37
37
  private collectionIndices;
38
38
  private queries;
39
39
  private onError;
40
- constructor(workerContext: WorkerContext, options: WorkerDataAdapterHostOptions);
40
+ constructor(workerContext: WorkerDataAdapterHostEndpoint, options: WorkerDataAdapterHostOptions);
41
41
  private respond;
42
42
  private handleMessage;
43
43
  private getIndexInfo;
44
44
  private queryItems;
45
45
  private executeQuery;
46
46
  private ensureQuery;
47
+ private setQueryItems;
48
+ private queryItemIds;
47
49
  private emitQueryUpdate;
48
50
  private ensureStorageAdapter;
49
51
  private checkQueryUpdates;
@@ -1,7 +1,7 @@
1
- import type { BaseItem } from './Collection/types';
1
+ import { BaseItem } from './Collection/types';
2
2
  /**
3
3
  * creates an index for a specific field
4
4
  * @param field name of the field
5
5
  * @returns an index provider to pass to the `indices` option of the collection constructor
6
6
  */
7
- export default function createIndex<T extends BaseItem<I> = BaseItem, I = any>(field: string): import("./types/IndexProvider").default<T, I>;
7
+ export default function createIndex<T extends BaseItem<I> = BaseItem, I = any>(field: string): import('./types/IndexProvider').default<T, I>;
@@ -1,5 +1,5 @@
1
- import type { BaseItem } from './Collection';
2
- import type IndexProvider from './types/IndexProvider';
1
+ import { BaseItem } from './Collection';
2
+ import { default as IndexProvider } from './types/IndexProvider';
3
3
  /**
4
4
  * Creates an IndexProvider based on the given definition.
5
5
  * @param definition - The definition of the IndexProvider.
@@ -1,5 +1,5 @@
1
- import type Dependency from './types/Dependency';
2
- import type ReactivityAdapter from './types/ReactivityAdapter';
1
+ import { default as Dependency } from './types/Dependency';
2
+ import { default as ReactivityAdapter } from './types/ReactivityAdapter';
3
3
  /**
4
4
  * Creates an ReactivityAdapter based on the given definition.
5
5
  * @param definition - The definition of the ReactivityAdapter.
@@ -1,4 +1,4 @@
1
- import type StorageAdapter from './types/StorageAdapter';
1
+ import { default as StorageAdapter } from './types/StorageAdapter';
2
2
  /**
3
3
  * Creates an StorageAdapter based on the given definition.
4
4
  * @param definition - The definition of the StorageAdapter.
@@ -1,7 +1,6 @@
1
- import type { AsynchronousQueryFunction, SynchronousQueryFunction } from './types/IndexProvider';
2
- import type { FlatSelector } from './types/Selector';
3
- import type Selector from './types/Selector';
4
- import type { BaseItem } from './Collection/types';
1
+ import { AsynchronousQueryFunction, SynchronousQueryFunction } from './types/IndexProvider';
2
+ import { FlatSelector, default as Selector } from './types/Selector';
3
+ import { BaseItem } from './Collection/types';
5
4
  type IndexInfo<T extends BaseItem<I> = BaseItem, I = any> = {
6
5
  matched: boolean;
7
6
  ids: I[];
package/dist/index.cjs.js CHANGED
@@ -1,32 +1,34 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const Cursor = require("./index.cjs2.js");
4
- const index = require("./index.cjs3.js");
5
- const createStorageAdapter = require("./index.cjs4.js");
6
- const createReactivityAdapter = require("./index.cjs5.js");
7
- const isEqual = require("./index.cjs6.js");
8
- const modify = require("./index.cjs7.js");
9
- const randomId = require("./index.cjs8.js");
10
- const EventEmitter = require("./index.cjs9.js");
11
- const get = require("./index.cjs10.js");
12
- const serializeValue = require("./index.cjs11.js");
13
- const DefaultDataAdapter = require("./index.cjs12.js");
14
- const AsyncDataAdapter = require("./index.cjs13.js");
15
- const WorkerDataAdapter = require("./index.cjs14.js");
16
- const WorkerDataAdapterHost = require("./index.cjs15.js");
17
- const AutoFetchDataAdapter = require("./index.cjs16.js");
18
- exports.Cursor = Cursor.default;
19
- exports.Collection = index.default;
20
- exports.createStorageAdapter = createStorageAdapter;
21
- exports.createReactivityAdapter = createReactivityAdapter;
22
- exports.isEqual = isEqual;
23
- exports.modify = modify;
24
- exports.randomId = randomId;
25
- exports.EventEmitter = EventEmitter;
26
- exports.get = get;
27
- exports.serializeValue = serializeValue;
28
- exports.DefaultDataAdapter = DefaultDataAdapter;
29
- exports.AsyncDataAdapter = AsyncDataAdapter;
30
- exports.WorkerDataAdapter = WorkerDataAdapter;
31
- exports.WorkerDataAdapterHost = WorkerDataAdapterHost;
32
- exports.AutoFetchDataAdapter = AutoFetchDataAdapter;
2
+ const require_isEqual = require("./index2.cjs.js");
3
+ const require_Cursor = require("./index6.cjs.js");
4
+ const require_EventEmitter = require("./index7.cjs.js");
5
+ const require_randomId = require("./index9.cjs.js");
6
+ const require_get = require("./index11.cjs.js");
7
+ const require_serializeValue = require("./index13.cjs.js");
8
+ const require_modify = require("./index20.cjs.js");
9
+ const require_DefaultDataAdapter = require("./index28.cjs.js");
10
+ const require_index = require("./index29.cjs.js");
11
+ const require_createStorageAdapter = require("./index30.cjs.js");
12
+ const require_createReactivityAdapter = require("./index31.cjs.js");
13
+ const require_reactiveOrAsync = require("./index32.cjs.js");
14
+ const require_AsyncDataAdapter = require("./index34.cjs.js");
15
+ const require_WorkerDataAdapter = require("./index36.cjs.js");
16
+ const require_WorkerDataAdapterHost = require("./index38.cjs.js");
17
+ const require_AutoFetchDataAdapter = require("./index39.cjs.js");
18
+ exports.AsyncDataAdapter = require_AsyncDataAdapter.default;
19
+ exports.AutoFetchDataAdapter = require_AutoFetchDataAdapter.default;
20
+ exports.Collection = require_index.default;
21
+ exports.Cursor = require_Cursor.default;
22
+ exports.DefaultDataAdapter = require_DefaultDataAdapter.default;
23
+ exports.EventEmitter = require_EventEmitter.default;
24
+ exports.WorkerDataAdapter = require_WorkerDataAdapter.default;
25
+ exports.WorkerDataAdapterHost = require_WorkerDataAdapterHost.default;
26
+ exports.createReactivityAdapter = require_createReactivityAdapter.default;
27
+ exports.createStorageAdapter = require_createStorageAdapter.default;
28
+ exports.get = require_get.default;
29
+ exports.isEqual = require_isEqual.default;
30
+ exports.modify = require_modify.default;
31
+ exports.randomId = require_randomId.default;
32
+ exports.reactiveOrAsync = require_reactiveOrAsync.default;
33
+ exports.serializeValue = require_serializeValue.default;
34
+ exports.unwrap = require_reactiveOrAsync.unwrap;
package/dist/index.d.ts CHANGED
@@ -2,8 +2,10 @@ export type { default as ReactivityAdapter } from './types/ReactivityAdapter';
2
2
  export type { default as StorageAdapter, Changeset, } from './types/StorageAdapter';
3
3
  export type { default as Selector } from './types/Selector';
4
4
  export type { default as Modifier } from './types/Modifier';
5
- export type { BaseItem, ObserveCallbacks, CursorOptions, Transform, TransformAll, SortSpecifier, FieldSpecifier, FindOptions, CollectionOptions, } from './Collection';
5
+ export type { BaseItem, ObserveCallbacks, CursorOptions, Transform, TransformAll, SortSpecifier, FieldSpecifier, AnyFindOptions, AsyncFindOptions, FindOptions, SyncFindOptions, CollectionOptions, QueryStateAccessor, } from './Collection';
6
6
  export type { default as DataAdapter } from './DataAdapter';
7
+ export type { CollectionBackend, QueryOptions, StateChangeCallback, } from './DataAdapter';
8
+ export type { QueryDelta } from './utils/queryDelta';
7
9
  export { default as Cursor } from './Collection/Cursor';
8
10
  export { default as Collection } from './Collection';
9
11
  export { default as createStorageAdapter } from './createStorageAdapter';
@@ -14,8 +16,11 @@ export { default as randomId } from './utils/randomId';
14
16
  export { default as EventEmitter } from './utils/EventEmitter';
15
17
  export { default as get } from './utils/get';
16
18
  export { default as serializeValue } from './utils/serializeValue';
19
+ export { default as reactiveOrAsync, unwrap } from './utils/reactiveOrAsync';
17
20
  export { default as DefaultDataAdapter } from './DefaultDataAdapter';
18
21
  export { default as AsyncDataAdapter } from './AsyncDataAdapter';
19
22
  export { default as WorkerDataAdapter } from './WorkerDataAdapter';
20
23
  export { default as WorkerDataAdapterHost } from './WorkerDataAdapterHost';
24
+ export type { WorkerDataAdapterEndpoint } from './WorkerDataAdapter';
25
+ export type { WorkerDataAdapterHostEndpoint } from './WorkerDataAdapterHost';
21
26
  export { default as AutoFetchDataAdapter } from './AutoFetchDataAdapter';
package/dist/index.mjs CHANGED
@@ -1,32 +1,17 @@
1
- import { default as default2 } from "./index2.mjs";
2
- import { default as default3 } from "./index3.mjs";
3
- import { default as default4 } from "./index4.mjs";
4
- import { default as default5 } from "./index5.mjs";
5
- import { default as default6 } from "./index6.mjs";
6
- import { default as default7 } from "./index7.mjs";
7
- import { default as default8 } from "./index8.mjs";
8
- import { default as default9 } from "./index9.mjs";
9
- import { default as default10 } from "./index10.mjs";
10
- import { default as default11 } from "./index11.mjs";
11
- import { default as default12 } from "./index12.mjs";
12
- import { default as default13 } from "./index13.mjs";
13
- import { default as default14 } from "./index14.mjs";
14
- import { default as default15 } from "./index15.mjs";
15
- import { default as default16 } from "./index16.mjs";
16
- export {
17
- default13 as AsyncDataAdapter,
18
- default16 as AutoFetchDataAdapter,
19
- default3 as Collection,
20
- default2 as Cursor,
21
- default12 as DefaultDataAdapter,
22
- default9 as EventEmitter,
23
- default14 as WorkerDataAdapter,
24
- default15 as WorkerDataAdapterHost,
25
- default5 as createReactivityAdapter,
26
- default4 as createStorageAdapter,
27
- default10 as get,
28
- default6 as isEqual,
29
- default7 as modify,
30
- default8 as randomId,
31
- default11 as serializeValue
32
- };
1
+ import isEqual from "./index2.mjs";
2
+ import Cursor from "./index6.mjs";
3
+ import EventEmitter from "./index7.mjs";
4
+ import randomId from "./index9.mjs";
5
+ import get from "./index11.mjs";
6
+ import serializeValue from "./index13.mjs";
7
+ import modify from "./index20.mjs";
8
+ import DefaultDataAdapter from "./index28.mjs";
9
+ import Collection from "./index29.mjs";
10
+ import createStorageAdapter from "./index30.mjs";
11
+ import createReactivityAdapter from "./index31.mjs";
12
+ import reactiveOrAsync, { unwrap } from "./index32.mjs";
13
+ import AsyncDataAdapter from "./index34.mjs";
14
+ import WorkerDataAdapter from "./index36.mjs";
15
+ import WorkerDataAdapterHost from "./index38.mjs";
16
+ import AutoFetchDataAdapter from "./index39.mjs";
17
+ export { AsyncDataAdapter, AutoFetchDataAdapter, Collection, Cursor, DefaultDataAdapter, EventEmitter, WorkerDataAdapter, WorkerDataAdapterHost, createReactivityAdapter, createStorageAdapter, get, isEqual, modify, randomId, reactiveOrAsync, serializeValue, unwrap };
@@ -0,0 +1,11 @@
1
+ //#region src/createIndexProvider.ts
2
+ /**
3
+ * Creates an IndexProvider based on the given definition.
4
+ * @param definition - The definition of the IndexProvider.
5
+ * @returns The created IndexProvider.
6
+ */
7
+ function createIndexProvider(definition) {
8
+ return definition;
9
+ }
10
+ //#endregion
11
+ exports.default = createIndexProvider;