teamplay 0.5.0-alpha.8 → 0.5.0

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 (92) hide show
  1. package/README.md +3 -3
  2. package/dist/config.d.ts +2 -0
  3. package/dist/config.js +1 -0
  4. package/dist/connect/index.d.ts +1 -1
  5. package/dist/connect/index.js +6 -2
  6. package/dist/connect/offline/index.d.ts +1 -1
  7. package/dist/connect/offline/index.js +8 -4
  8. package/dist/connect/offline/react-native.d.ts +1 -1
  9. package/dist/connect/offline/web.d.ts +1 -1
  10. package/dist/connect/test.d.ts +1 -1
  11. package/dist/connect/test.js +5 -1
  12. package/dist/index.d.ts +9 -5
  13. package/dist/index.js +6 -5
  14. package/dist/orm/$.js +1 -1
  15. package/dist/orm/Aggregation.d.ts +5 -3
  16. package/dist/orm/Aggregation.js +39 -15
  17. package/dist/orm/Doc.js +0 -55
  18. package/dist/orm/Query.d.ts +1 -0
  19. package/dist/orm/Query.js +25 -82
  20. package/dist/orm/Root.d.ts +4 -0
  21. package/dist/orm/Root.js +16 -0
  22. package/dist/orm/Signal.d.ts +0 -2
  23. package/dist/orm/Signal.js +1 -4
  24. package/dist/orm/SignalBase.d.ts +21 -1
  25. package/dist/orm/SignalBase.js +259 -56
  26. package/dist/orm/batchScheduler.d.ts +7 -7
  27. package/dist/orm/connection.d.ts +0 -4
  28. package/dist/orm/connection.js +0 -12
  29. package/dist/orm/dataTree.d.ts +12 -12
  30. package/dist/orm/dataTree.js +55 -107
  31. package/dist/orm/disposeRootContext.js +0 -14
  32. package/dist/orm/events.d.ts +6 -0
  33. package/dist/orm/events.js +48 -0
  34. package/dist/orm/getSignal.d.ts +1 -1
  35. package/dist/orm/getSignal.js +4 -33
  36. package/dist/orm/idFields.d.ts +10 -1
  37. package/dist/orm/idFields.js +102 -14
  38. package/dist/orm/index.d.ts +2 -0
  39. package/dist/orm/index.js +1 -0
  40. package/dist/orm/initModels.js +1 -1
  41. package/dist/orm/privateData.d.ts +7 -22
  42. package/dist/orm/privateData.js +20 -1
  43. package/dist/orm/queryReadiness.d.ts +13 -0
  44. package/dist/orm/{Compat/queryReadiness.js → queryReadiness.js} +10 -10
  45. package/dist/orm/reaction.d.ts +11 -0
  46. package/dist/orm/reaction.js +47 -0
  47. package/dist/orm/rootContext.d.ts +0 -16
  48. package/dist/orm/rootContext.js +0 -28
  49. package/dist/orm/signalMetadata.js +3 -3
  50. package/dist/orm/signalReads.js +3 -9
  51. package/dist/orm/signalStorageMutations.d.ts +0 -2
  52. package/dist/orm/signalStorageMutations.js +0 -9
  53. package/dist/orm/signalSymbols.js +1 -1
  54. package/dist/orm/signalValueMutations.d.ts +1 -1
  55. package/dist/orm/signalValueMutations.js +0 -3
  56. package/dist/orm/sub.d.ts +12 -7
  57. package/dist/orm/sub.js +87 -30
  58. package/dist/orm/subscriptionGcDelay.js +2 -6
  59. package/dist/react/convertToObserver.js +1 -4
  60. package/dist/react/promiseBatcher.js +1 -1
  61. package/dist/react/renderAttemptDestroyer.d.ts +0 -8
  62. package/dist/react/renderAttemptDestroyer.js +2 -28
  63. package/dist/react/trapRender.js +3 -3
  64. package/dist/react/useSub.d.ts +86 -5
  65. package/dist/react/useSub.js +191 -32
  66. package/dist/react/useSuspendMemo.js +1 -5
  67. package/dist/server.d.ts +2 -3
  68. package/dist/server.js +5 -3
  69. package/package.json +16 -14
  70. package/dist/orm/Compat/SignalCompat.d.ts +0 -3
  71. package/dist/orm/Compat/SignalCompat.js +0 -1267
  72. package/dist/orm/Compat/eventsCompat.d.ts +0 -3
  73. package/dist/orm/Compat/eventsCompat.js +0 -73
  74. package/dist/orm/Compat/hooksCompat.d.ts +0 -33
  75. package/dist/orm/Compat/hooksCompat.js +0 -360
  76. package/dist/orm/Compat/modelEvents.d.ts +0 -6
  77. package/dist/orm/Compat/modelEvents.js +0 -228
  78. package/dist/orm/Compat/queryReadiness.d.ts +0 -5
  79. package/dist/orm/Compat/refFallback.d.ts +0 -13
  80. package/dist/orm/Compat/refFallback.js +0 -65
  81. package/dist/orm/Compat/refRegistry.d.ts +0 -6
  82. package/dist/orm/Compat/refRegistry.js +0 -54
  83. package/dist/orm/Compat/silentContext.d.ts +0 -5
  84. package/dist/orm/Compat/silentContext.js +0 -48
  85. package/dist/orm/Compat/startStopCompat.d.ts +0 -3
  86. package/dist/orm/Compat/startStopCompat.js +0 -217
  87. package/dist/orm/compatEnv.d.ts +0 -1
  88. package/dist/orm/compatEnv.js +0 -4
  89. package/dist/react/compatComponentRegistry.d.ts +0 -4
  90. package/dist/react/compatComponentRegistry.js +0 -19
  91. /package/dist/orm/{Reaction.d.ts → reactionSubscriptions.d.ts} +0 -0
  92. /package/dist/orm/{Reaction.js → reactionSubscriptions.js} +0 -0
package/dist/orm/sub.js CHANGED
@@ -3,9 +3,11 @@ import Signal, { SEGMENTS, isPublicCollectionSignal, isPublicDocumentSignal } fr
3
3
  import { docSubscriptions } from './Doc.js';
4
4
  import { querySubscriptions, getQuerySignal } from './Query.js';
5
5
  import { aggregationSubscriptions, getAggregationSignal } from './Aggregation.js';
6
- import { getRoot } from "./Root.js";
6
+ import { getRoot, ROOT_ID } from "./Root.js";
7
+ import { isRootContextClosed } from "./rootContext.js";
7
8
  import isServer from "../utils/isServer.js";
8
- export default function sub($signal, params) {
9
+ const SUB_RECORDS = new WeakMap();
10
+ export default function sub($signal, params, options) {
9
11
  // TODO: temporarily disable support for multiple subscriptions
10
12
  // since this has to be properly cached using useDeferredSignal() in useSub()
11
13
  // if (Array.isArray($signal)) {
@@ -16,26 +18,26 @@ export default function sub($signal, params) {
16
18
  if (Array.isArray($signal))
17
19
  throw Error('sub() does not support multiple subscriptions yet');
18
20
  if (isRuntimePublicDocumentSignal($signal)) {
19
- if (arguments.length > 1) {
21
+ if (arguments.length > 2) {
20
22
  throw Error(ERRORS.subDocArguments($signal, ...Array.from(arguments).slice(1)));
21
23
  }
22
- return doc$($signal);
24
+ return doc$($signal, parseSubOptions(params));
23
25
  }
24
26
  else if (isRuntimePublicCollectionSignal($signal)) {
25
- if (arguments.length !== 2) {
27
+ if (arguments.length < 2 || arguments.length > 3) {
26
28
  throw Error(ERRORS.subQueryArguments($signal, params, ...Array.from(arguments).slice(2)));
27
29
  }
28
- return query$($signal, params);
30
+ return query$($signal, params, parseSubOptions(options));
29
31
  }
30
32
  else if (isClientAggregationFunction($signal)) {
31
- return getAggregationFromFunction($signal, $signal.collection, params);
33
+ return getAggregationFromFunction($signal, $signal.collection, params, parseSubOptions(options));
32
34
  }
33
35
  else if (isAggregationHeader($signal)) {
34
36
  const aggregationParams = {
35
37
  $aggregationName: $signal.name,
36
38
  $params: sanitizeAggregationParams(params)
37
39
  };
38
- return aggregation$($signal.collection, aggregationParams);
40
+ return aggregation$($signal.collection, aggregationParams, undefined, parseSubOptions(options));
39
41
  }
40
42
  else if (isAggregationFunction($signal)) {
41
43
  if (isServer) {
@@ -46,7 +48,7 @@ export default function sub($signal, params) {
46
48
  }
47
49
  const aggregationParams = { ...serverParams };
48
50
  delete aggregationParams.$collection;
49
- return getAggregationFromFunction($signal, collection, aggregationParams);
51
+ return getAggregationFromFunction($signal, collection, aggregationParams, parseSubOptions(options));
50
52
  }
51
53
  else {
52
54
  throw Error(ERRORS.gotAggregationFunction($signal));
@@ -59,7 +61,25 @@ export default function sub($signal, params) {
59
61
  throw Error('Invalid args passed for sub()');
60
62
  }
61
63
  }
62
- function getAggregationFromFunction(fn, collection, params) {
64
+ export function unsub($signal) {
65
+ if (!($signal instanceof Signal))
66
+ return;
67
+ const record = takeSubRecord($signal);
68
+ if (!record)
69
+ return;
70
+ record.disposed = true;
71
+ const $root = getRoot($signal);
72
+ const rootId = $root?.[ROOT_ID];
73
+ if (isRootContextClosed(rootId))
74
+ return;
75
+ if (record.kind === 'doc')
76
+ return docSubscriptions.unsubscribe($signal, { intent: record.intent });
77
+ if (record.kind === 'query')
78
+ return querySubscriptions.unsubscribe($signal, { intent: record.intent });
79
+ if (record.kind === 'aggregation')
80
+ return aggregationSubscriptions.unsubscribe($signal, { intent: record.intent });
81
+ }
82
+ function getAggregationFromFunction(fn, collection, params, subOptions) {
63
83
  const aggregationParams = sanitizeAggregationParams(params);
64
84
  let session;
65
85
  if (isRecord(aggregationParams) && aggregationParams.$session) {
@@ -70,15 +90,13 @@ function getAggregationFromFunction(fn, collection, params) {
70
90
  // should match the context in @teamplay/backend/features/serverAggregate.js
71
91
  const context = { collection, session, isServer };
72
92
  const result = fn(aggregationParams, context);
73
- return aggregation$(collection, Array.isArray(result) ? { $aggregate: result } : result);
93
+ return aggregation$(collection, Array.isArray(result) ? { $aggregate: result } : result, undefined, subOptions);
74
94
  }
75
- function doc$($doc) {
76
- const promise = docSubscriptions.subscribe($doc);
77
- if (!promise)
78
- return $doc;
79
- return new Promise(resolve => promise.then(() => resolve($doc)));
95
+ function doc$($doc, subOptions) {
96
+ const promise = docSubscriptions.subscribe($doc, { intent: subOptions.intent });
97
+ return returnSubscribedSignal($doc, 'doc', subOptions.intent, promise);
80
98
  }
81
- function query$($collection, params) {
99
+ function query$($collection, params, subOptions) {
82
100
  const collectionName = $collection[SEGMENTS][0];
83
101
  if (typeof collectionName !== 'string')
84
102
  throw Error(ERRORS.queryCollectionName($collection));
@@ -86,20 +104,17 @@ function query$($collection, params) {
86
104
  throw Error(ERRORS.queryParamsObject(collectionName, params));
87
105
  const signalOptions = getQuerySignalOptions($collection);
88
106
  const queryParams = params;
89
- if (queryParams?.$aggregate || queryParams?.$aggregationName)
90
- return aggregation$(collectionName, params, signalOptions);
107
+ if (queryParams?.$aggregate || queryParams?.$aggregationName) {
108
+ return aggregation$(collectionName, params, signalOptions, subOptions);
109
+ }
91
110
  const $query = getQuerySignal(collectionName, params, signalOptions);
92
- const promise = querySubscriptions.subscribe($query);
93
- if (!promise)
94
- return $query;
95
- return new Promise(resolve => promise.then(() => resolve($query)));
111
+ const promise = querySubscriptions.subscribe($query, { intent: subOptions.intent });
112
+ return returnSubscribedSignal($query, 'query', subOptions.intent, promise);
96
113
  }
97
- function aggregation$(collectionName, params, signalOptions) {
114
+ function aggregation$(collectionName, params, signalOptions, subOptions = parseSubOptions()) {
98
115
  const $aggregationQuery = getAggregationSignal(collectionName, params, signalOptions);
99
- const promise = aggregationSubscriptions.subscribe($aggregationQuery);
100
- if (!promise)
101
- return $aggregationQuery;
102
- return new Promise(resolve => promise.then(() => resolve($aggregationQuery)));
116
+ const promise = aggregationSubscriptions.subscribe($aggregationQuery, { intent: subOptions.intent });
117
+ return returnSubscribedSignal($aggregationQuery, 'aggregation', subOptions.intent, promise);
103
118
  }
104
119
  function api$(_fn, _args) {
105
120
  throw Error('sub() for async functions is not implemented yet');
@@ -133,14 +148,56 @@ function isRuntimePublicCollectionSignal(value) {
133
148
  function isApiFunction(value) {
134
149
  return typeof value === 'function' && !(value instanceof Signal);
135
150
  }
151
+ function parseSubOptions(options) {
152
+ const mode = options?.mode ?? 'auto';
153
+ if (mode !== 'auto' && mode !== 'fetch' && mode !== 'subscribe') {
154
+ throw Error(`sub() option mode must be "auto", "fetch", or "subscribe". Got: ${mode}`);
155
+ }
156
+ return {
157
+ intent: mode === 'fetch' ? 'fetch' : 'subscribe'
158
+ };
159
+ }
160
+ function returnSubscribedSignal($signal, kind, intent, promise) {
161
+ if (!promise) {
162
+ addSubRecord($signal, kind, intent);
163
+ return $signal;
164
+ }
165
+ return promise.then(() => {
166
+ addSubRecord($signal, kind, intent);
167
+ return $signal;
168
+ });
169
+ }
170
+ function addSubRecord($signal, kind, intent) {
171
+ let records = SUB_RECORDS.get($signal);
172
+ if (!records) {
173
+ records = [];
174
+ SUB_RECORDS.set($signal, records);
175
+ }
176
+ records.push({ kind, intent, disposed: false });
177
+ }
178
+ function takeSubRecord($signal) {
179
+ const records = SUB_RECORDS.get($signal);
180
+ if (!records)
181
+ return;
182
+ for (let i = records.length - 1; i >= 0; i--) {
183
+ const record = records[i];
184
+ if (record.disposed)
185
+ continue;
186
+ records.splice(i, 1);
187
+ if (records.length === 0)
188
+ SUB_RECORDS.delete($signal);
189
+ return record;
190
+ }
191
+ SUB_RECORDS.delete($signal);
192
+ }
136
193
  const ERRORS = {
137
194
  subDocArguments: ($signal, ...args) => `
138
- sub($doc) accepts only 1 argument - the document signal to subscribe to
195
+ sub($doc) accepts one or two arguments - the document signal and optional options.
139
196
  Doc: ${$signal[SEGMENTS]}
140
197
  Got args: ${[$signal, ...args]}
141
198
  `,
142
199
  subQueryArguments: ($signal, params, ...args) => `
143
- sub($collection, params) accepts 2 arguments - the collection signal and an object with query params.
200
+ sub($collection, params) accepts two or three arguments - the collection signal, query params, and optional options.
144
201
  If you want to subscribe to all documents in a collection, pass an empty object: sub($collection, {}).
145
202
  Collection: ${$signal[SEGMENTS]}
146
203
  Params: ${params}
@@ -1,6 +1,4 @@
1
- import { isCompatEnv } from './compatEnv.js';
2
- const DEFAULT_COMPAT_SUBSCRIPTION_GC_DELAY = 3000;
3
- const DEFAULT_SUBSCRIPTION_GC_DELAY = 0;
1
+ const DEFAULT_SUBSCRIPTION_GC_DELAY = 3000;
4
2
  let subscriptionGcDelay = getDefaultSubscriptionGcDelay();
5
3
  export function getSubscriptionGcDelay() {
6
4
  return subscriptionGcDelay;
@@ -17,9 +15,7 @@ export function setSubscriptionGcDelay(ms) {
17
15
  return subscriptionGcDelay;
18
16
  }
19
17
  export function getDefaultSubscriptionGcDelay() {
20
- return isCompatEnv()
21
- ? DEFAULT_COMPAT_SUBSCRIPTION_GC_DELAY
22
- : DEFAULT_SUBSCRIPTION_GC_DELAY;
18
+ return DEFAULT_SUBSCRIPTION_GC_DELAY;
23
19
  }
24
20
  export function __resetSubscriptionGcDelayForTests() {
25
21
  subscriptionGcDelay = getDefaultSubscriptionGcDelay();
@@ -7,7 +7,6 @@ import executionContextTracker from "./executionContextTracker.js";
7
7
  import { pipeComponentMeta, useUnmount, useId, useTriggerUpdate } from "./helpers.js";
8
8
  import trapRender from './trapRender.js';
9
9
  import { scheduleReaction } from '../orm/batchScheduler.js';
10
- import { isCompatComponent, unmarkCompatComponent } from "./compatComponentRegistry.js";
11
10
  const DEFAULT_THROTTLE_TIMEOUT = 100;
12
11
  export default function convertToObserver(BaseComponent, { forwardRef, cache: enableCache = true, throttle, ...options } = {}) {
13
12
  throttle = normalizeThrottle(throttle);
@@ -33,7 +32,7 @@ export default function convertToObserver(BaseComponent, { forwardRef, cache: en
33
32
  hasDeferredUpdateAfterExecutionContext = false;
34
33
  triggerUpdate();
35
34
  }
36
- else if (isCompatComponent(componentId)) {
35
+ else {
37
36
  if (hasDeferredUpdateAfterExecutionContext)
38
37
  return;
39
38
  hasDeferredUpdateAfterExecutionContext = true;
@@ -53,7 +52,6 @@ export default function convertToObserver(BaseComponent, { forwardRef, cache: en
53
52
  if (!reactionRef.current)
54
53
  throw Error(`NO REACTION REF - ${where}`);
55
54
  destroyRef.current = undefined;
56
- unmarkCompatComponent(componentId);
57
55
  unobserve(reactionRef.current);
58
56
  reactionRef.current = undefined;
59
57
  destroyCache(where);
@@ -71,7 +69,6 @@ export default function convertToObserver(BaseComponent, { forwardRef, cache: en
71
69
  }
72
70
  // clean up observer on unmount
73
71
  useUnmount(() => {
74
- unmarkCompatComponent(componentId);
75
72
  destroyRef.current?.('useUnmount()');
76
73
  });
77
74
  return reactionRef.current(...args);
@@ -95,7 +95,7 @@ function warnAboutChecksDelay(checks) {
95
95
  state
96
96
  };
97
97
  });
98
- console.warn('[teamplay] useBatch() is waiting for data materialization checks.', details);
98
+ console.warn('[teamplay] useBatchSub() is waiting for data materialization checks.', details);
99
99
  }
100
100
  function isDevMode() {
101
101
  const processLike = globalThis.process;
@@ -1,17 +1,9 @@
1
- type DestroyAttempt = () => unknown | Promise<unknown>;
2
1
  declare class RenderAttemptDestroyer {
3
- fns: DestroyAttempt[];
4
- compatAttemptCleanupArmed: boolean;
5
2
  suspenseGateArmed: boolean;
6
3
  constructor();
7
- add(fn: DestroyAttempt | undefined, { compat }?: {
8
- compat?: boolean;
9
- }): void;
10
- armCompatAttemptCleanup(): void;
11
4
  armSuspenseGate(): void;
12
5
  consumeThenableHandling(): {
13
6
  shouldKeepShellAlive: boolean;
14
- destroyAttempt?: () => Promise<void>;
15
7
  };
16
8
  reset(): void;
17
9
  }
@@ -1,45 +1,19 @@
1
1
  class RenderAttemptDestroyer {
2
- fns;
3
- compatAttemptCleanupArmed;
4
2
  suspenseGateArmed;
5
3
  constructor() {
6
- this.fns = [];
7
- this.compatAttemptCleanupArmed = false;
8
4
  this.suspenseGateArmed = false;
9
5
  }
10
- add(fn, { compat = false } = {}) {
11
- if (typeof fn !== 'function')
12
- return;
13
- this.fns.push(fn);
14
- if (compat)
15
- this.compatAttemptCleanupArmed = true;
16
- }
17
- armCompatAttemptCleanup() {
18
- this.compatAttemptCleanupArmed = true;
19
- }
20
6
  armSuspenseGate() {
21
7
  this.suspenseGateArmed = true;
22
8
  }
23
9
  consumeThenableHandling() {
24
- const shouldRunAttemptCleanup = this.compatAttemptCleanupArmed && this.fns.length > 0;
25
- const shouldKeepShellAlive = this.suspenseGateArmed || shouldRunAttemptCleanup;
26
- let destroyAttempt;
27
- if (shouldRunAttemptCleanup) {
28
- const fns = [...this.fns];
29
- destroyAttempt = async () => {
30
- await Promise.allSettled(fns.map(fn => fn()));
31
- fns.length = 0;
32
- };
33
- }
10
+ const shouldKeepShellAlive = this.suspenseGateArmed;
34
11
  this.reset();
35
12
  return {
36
- shouldKeepShellAlive,
37
- destroyAttempt
13
+ shouldKeepShellAlive
38
14
  };
39
15
  }
40
16
  reset() {
41
- this.fns.length = 0;
42
- this.compatAttemptCleanupArmed = false;
43
17
  this.suspenseGateArmed = false;
44
18
  }
45
19
  }
@@ -13,7 +13,7 @@ export default function trapRender({ render, cache, destroy, componentId }) {
13
13
  promiseBatcher.reset();
14
14
  const res = render(...args);
15
15
  if (isDevMode() && promiseBatcher.isActive()) {
16
- throw Error('[teamplay] useBatch* hooks were used without a closing useBatch() call.');
16
+ throw Error('[teamplay] batch subscriptions were used without a closing useBatchSub() call or useSub(undefined, undefined, { batch: true }) call.');
17
17
  }
18
18
  return res;
19
19
  }
@@ -24,9 +24,9 @@ export default function trapRender({ render, cache, destroy, componentId }) {
24
24
  destroyed = true;
25
25
  throw err;
26
26
  }
27
- const { shouldKeepShellAlive, destroyAttempt } = renderAttemptDestroyer.consumeThenableHandling();
27
+ const { shouldKeepShellAlive } = renderAttemptDestroyer.consumeThenableHandling();
28
28
  if (shouldKeepShellAlive) {
29
- throw Promise.resolve(err).then(() => destroyAttempt?.());
29
+ throw Promise.resolve(err);
30
30
  }
31
31
  // TODO: this might only be needed only if promise is thrown
32
32
  // (check if useUnmount in convertToObserver is called if a regular error is thrown)
@@ -1,5 +1,5 @@
1
1
  import type { AggregationFunction, AggregationParams, ClientAggregationFunction } from '@teamplay/utils/aggregation';
2
- import type { CollectionSignal, ComputedQueryParamsInput, DocumentSignal, QueryParams, RegisteredAggregationInput, SignalModelConstructor, SubResult, TypedAggregationInput, TypedAggregationSignal, WildcardSignalPath } from '../orm/Signal.js';
2
+ import { type CollectionSignal, type ComputedQueryParamsInput, type DocumentSignal, type QueryParams, type RegisteredAggregationInput, type SignalModelConstructor, type SubResult, type TypedAggregationInput, type TypedAggregationSignal, type WildcardSignalPath } from '../orm/Signal.js';
3
3
  export interface UseSubOptions {
4
4
  /** Return `undefined` while loading instead of throwing a Suspense promise. */
5
5
  async?: boolean;
@@ -7,9 +7,14 @@ export interface UseSubOptions {
7
7
  defer?: boolean | number;
8
8
  /** Batch Suspense promises across multiple subscriptions in one render attempt. */
9
9
  batch?: boolean;
10
- /** Enable compatibility cleanup for legacy observer render attempts. */
11
- compatAttemptCleanup?: boolean;
12
10
  }
11
+ /**
12
+ * Subscribe to a document signal in React async mode.
13
+ * @param signal Document signal to subscribe to.
14
+ * @param params Must be omitted for document subscriptions.
15
+ * @param options Subscription behavior options.
16
+ */
17
+ export declare function useAsyncSub<TSignal extends DocumentSignal<any, any, any>>(signal: TSignal, options?: UseSubOptions): SubResult<TSignal>;
13
18
  /**
14
19
  * Subscribe to a document signal in React async mode.
15
20
  * @param signal Document signal to subscribe to.
@@ -61,6 +66,82 @@ export declare function useAsyncSub<TDocument, TDocumentModel extends SignalMode
61
66
  * @param options Subscription behavior options.
62
67
  */
63
68
  export declare function useAsyncSub<TOutput = unknown, TCollection extends string = string>(signal: AggregationFunction<TOutput, TCollection>, params?: AggregationParams, options?: UseSubOptions): SubResult<AggregationFunction<TOutput, TCollection>, AggregationParams | undefined>;
69
+ /**
70
+ * Close a batch subscription barrier opened by previous `useBatchSub()` calls in this render.
71
+ */
72
+ export declare function useBatchSub(): void;
73
+ /**
74
+ * Subscribe to a document signal in React batch mode.
75
+ * @param signal Document signal to subscribe to.
76
+ * @param params Must be omitted for document subscriptions.
77
+ * @param options Subscription behavior options.
78
+ */
79
+ export declare function useBatchSub<TSignal extends DocumentSignal<any, any, any>>(signal: TSignal, options?: UseSubOptions): SubResult<TSignal>;
80
+ /**
81
+ * Subscribe to a document signal in React batch mode.
82
+ * @param signal Document signal to subscribe to.
83
+ * @param params Must be omitted for document subscriptions.
84
+ * @param options Subscription behavior options.
85
+ */
86
+ export declare function useBatchSub<TSignal extends DocumentSignal<any, any, any>>(signal: TSignal, params?: undefined, options?: UseSubOptions): SubResult<TSignal>;
87
+ /**
88
+ * Subscribe to a collection query in React batch mode.
89
+ * @param signal Collection signal to query.
90
+ * @param params Mongo-style query params, including filters and `$sort`.
91
+ * @param options Subscription behavior options.
92
+ */
93
+ export declare function useBatchSub<TDocument, TCollectionModel extends SignalModelConstructor<TDocument[]>, TDocumentModel extends SignalModelConstructor<TDocument>, TCollectionPath extends WildcardSignalPath>(signal: CollectionSignal<TDocument, TCollectionModel, TDocumentModel, TCollectionPath>, params: QueryParams<TDocument>, options?: UseSubOptions): SubResult<CollectionSignal<TDocument, TCollectionModel, TDocumentModel, TCollectionPath>, QueryParams<TDocument>>;
94
+ /**
95
+ * Subscribe to a collection query with computed string keys in React batch mode.
96
+ * This fallback preserves Mongo-style computed paths such as `{ [`likes.${id}`]: true }`.
97
+ * Literal query objects should use the stricter overload above.
98
+ * @param signal Collection signal to query.
99
+ * @param params Mongo-style query params with a widened computed key.
100
+ * @param options Subscription behavior options.
101
+ */
102
+ export declare function useBatchSub<TDocument, TCollectionModel extends SignalModelConstructor<TDocument[]>, TDocumentModel extends SignalModelConstructor<TDocument>, TCollectionPath extends WildcardSignalPath, TParams extends object>(signal: CollectionSignal<TDocument, TCollectionModel, TDocumentModel, TCollectionPath>, params: TParams & ComputedQueryParamsInput<TParams>, options?: UseSubOptions): SubResult<CollectionSignal<TDocument, TCollectionModel, TDocumentModel, TCollectionPath>, TParams>;
103
+ /**
104
+ * Subscribe to a registered collection aggregation in React batch mode.
105
+ * @param signal Aggregation header generated by StartupJS model loading.
106
+ * @param params Parameters passed to the aggregation.
107
+ * @param options Subscription behavior options.
108
+ */
109
+ export declare function useBatchSub<TCollection extends string, TOutput = unknown>(signal: RegisteredAggregationInput<TCollection, TOutput>, params?: AggregationParams, options?: UseSubOptions): SubResult<RegisteredAggregationInput<TCollection, TOutput>>;
110
+ /**
111
+ * Subscribe to a client aggregation in React batch mode.
112
+ * @param signal Aggregation function created with `aggregation(collection, fn)`.
113
+ * @param params Parameters passed to the aggregation.
114
+ * @param options Subscription behavior options.
115
+ */
116
+ export declare function useBatchSub<TOutput, TCollection extends string>(signal: ClientAggregationFunction<TOutput, TCollection>, params?: AggregationParams, options?: UseSubOptions): SubResult<ClientAggregationFunction<TOutput, TCollection>>;
117
+ /**
118
+ * Subscribe to an aggregation with explicit output typing in React batch mode.
119
+ * @param signal Typed aggregation input.
120
+ * @param params Parameters passed to the aggregation.
121
+ * @param options Subscription behavior options.
122
+ */
123
+ export declare function useBatchSub<TDocument, TDocumentModel extends SignalModelConstructor<TDocument>>(signal: TypedAggregationInput<TDocument, TDocumentModel>, params?: AggregationParams, options?: UseSubOptions): TypedAggregationSignal<TDocument, TDocumentModel>;
124
+ /**
125
+ * Subscribe to an unregistered aggregation in React batch mode.
126
+ * @param signal Aggregation function.
127
+ * @param params Parameters passed to the aggregation.
128
+ * @param options Subscription behavior options.
129
+ */
130
+ export declare function useBatchSub<TOutput = unknown, TCollection extends string = string>(signal: AggregationFunction<TOutput, TCollection>, params?: AggregationParams, options?: UseSubOptions): SubResult<AggregationFunction<TOutput, TCollection>, AggregationParams | undefined>;
131
+ /**
132
+ * Close a batch subscription barrier opened by previous `useSub(..., { batch: true })`
133
+ * calls in this render.
134
+ */
135
+ export default function useSub(signal: undefined, params: undefined, options: UseSubOptions & {
136
+ batch: true;
137
+ }): void;
138
+ /**
139
+ * Subscribe to a document signal in React.
140
+ * @param signal Document signal to subscribe to.
141
+ * @param params Must be omitted for document subscriptions.
142
+ * @param options Subscription behavior options.
143
+ */
144
+ export default function useSub<TSignal extends DocumentSignal<any, any, any>>(signal: TSignal, options?: UseSubOptions): SubResult<TSignal>;
64
145
  /**
65
146
  * Subscribe to a document signal in React.
66
147
  * @param signal Document signal to subscribe to.
@@ -112,8 +193,8 @@ export default function useSub<TDocument, TDocumentModel extends SignalModelCons
112
193
  * @param options Subscription behavior options.
113
194
  */
114
195
  export default function useSub<TOutput = unknown, TCollection extends string = string>(signal: AggregationFunction<TOutput, TCollection>, params?: AggregationParams, options?: UseSubOptions): SubResult<AggregationFunction<TOutput, TCollection>, AggregationParams | undefined>;
115
- export declare function useSubDeferred(signal: unknown, params?: unknown, { async, defer, batch, compatAttemptCleanup }?: UseSubOptions): unknown;
116
- export declare function useSubClassic(signal: unknown, params?: unknown, { async, batch, compatAttemptCleanup }?: UseSubOptions): unknown;
196
+ export declare function useSubDeferred(signal: unknown, params?: unknown, { async, defer, batch }?: UseSubOptions): unknown;
197
+ export declare function useSubClassic(signal: unknown, params?: unknown, { async, batch }?: UseSubOptions): unknown;
117
198
  export declare function setTestThrottling(ms: number): void;
118
199
  export declare function resetTestThrottling(): void;
119
200
  export declare function setUseDeferredValue(value: boolean): void;