teamplay 0.4.0 → 0.5.0-alpha.1
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/babel-loader.cjs +1 -0
- package/babel.cjs +1 -0
- package/dist/connect/index.d.ts +1 -0
- package/dist/connect/index.js +9 -0
- package/dist/connect/lib/sharedb-crosstab-pubsub.d.cts +10 -0
- package/dist/connect/offline/index.d.ts +1 -0
- package/dist/connect/offline/index.js +126 -0
- package/dist/connect/offline/react-native.d.ts +10 -0
- package/dist/connect/offline/react-native.js +25 -0
- package/dist/connect/offline/web.d.ts +9 -0
- package/dist/connect/offline/web.js +12 -0
- package/dist/connect/sharedbConnection.d.cts +2 -0
- package/dist/connect/test.d.ts +1 -0
- package/dist/connect/test.js +12 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +74 -0
- package/dist/orm/$.d.ts +9 -0
- package/dist/orm/$.js +34 -0
- package/dist/orm/Aggregation.d.ts +17 -0
- package/dist/orm/Aggregation.js +115 -0
- package/dist/orm/Cache.d.ts +9 -0
- package/dist/orm/Cache.js +32 -0
- package/dist/orm/Compat/SignalCompat.d.ts +3 -0
- package/dist/orm/Compat/SignalCompat.js +1542 -0
- package/dist/orm/Compat/eventsCompat.d.ts +3 -0
- package/dist/orm/Compat/eventsCompat.js +73 -0
- package/dist/orm/Compat/hooksCompat.d.ts +33 -0
- package/dist/orm/Compat/hooksCompat.js +360 -0
- package/dist/orm/Compat/modelEvents.d.ts +6 -0
- package/dist/orm/Compat/modelEvents.js +228 -0
- package/dist/orm/Compat/queryReadiness.d.ts +5 -0
- package/dist/orm/Compat/queryReadiness.js +185 -0
- package/dist/orm/Compat/refFallback.d.ts +13 -0
- package/dist/orm/Compat/refFallback.js +65 -0
- package/dist/orm/Compat/refRegistry.d.ts +6 -0
- package/dist/orm/Compat/refRegistry.js +54 -0
- package/dist/orm/Compat/silentContext.d.ts +5 -0
- package/dist/orm/Compat/silentContext.js +48 -0
- package/dist/orm/Compat/startStopCompat.d.ts +3 -0
- package/dist/orm/Compat/startStopCompat.js +217 -0
- package/dist/orm/Doc.d.ts +96 -0
- package/dist/orm/Doc.js +966 -0
- package/dist/orm/Query.d.ts +117 -0
- package/dist/orm/Query.js +1111 -0
- package/dist/orm/Reaction.d.ts +10 -0
- package/dist/orm/Reaction.js +41 -0
- package/dist/orm/Root.d.ts +22 -0
- package/dist/orm/Root.js +85 -0
- package/dist/orm/Signal.d.ts +12 -0
- package/dist/orm/Signal.js +7 -0
- package/dist/orm/SignalBase.d.ts +168 -0
- package/dist/orm/SignalBase.js +625 -0
- package/dist/orm/SubscriptionState.d.ts +17 -0
- package/dist/orm/SubscriptionState.js +123 -0
- package/dist/orm/Value.d.ts +9 -0
- package/dist/orm/Value.js +25 -0
- package/dist/orm/addModel.d.ts +6 -0
- package/dist/orm/addModel.js +39 -0
- package/dist/orm/associations.d.ts +18 -0
- package/dist/orm/associations.js +70 -0
- package/dist/orm/batchScheduler.d.ts +7 -0
- package/dist/orm/batchScheduler.js +62 -0
- package/dist/orm/compatEnv.d.ts +1 -0
- package/dist/orm/compatEnv.js +4 -0
- package/dist/orm/connection.d.ts +26 -0
- package/dist/orm/connection.js +38 -0
- package/dist/orm/dataTree.d.ts +34 -0
- package/dist/orm/dataTree.js +880 -0
- package/dist/orm/disposeRootContext.d.ts +4 -0
- package/dist/orm/disposeRootContext.js +59 -0
- package/dist/orm/getSignal.d.ts +16 -0
- package/dist/orm/getSignal.js +133 -0
- package/dist/orm/idFields.d.ts +14 -0
- package/dist/orm/idFields.js +95 -0
- package/dist/orm/index.d.ts +7 -0
- package/dist/orm/index.js +6 -0
- package/dist/orm/initModels.d.ts +5 -0
- package/dist/orm/initModels.js +74 -0
- package/dist/orm/missingDoc.d.ts +1 -0
- package/dist/orm/missingDoc.js +3 -0
- package/dist/orm/pluralize.d.ts +12 -0
- package/dist/orm/privateData.d.ts +22 -0
- package/dist/orm/privateData.js +170 -0
- package/dist/orm/rootContext.d.ts +78 -0
- package/dist/orm/rootContext.js +297 -0
- package/dist/orm/rootScope.d.ts +12 -0
- package/dist/orm/rootScope.js +46 -0
- package/dist/orm/signalArrayReaders.d.ts +22 -0
- package/dist/orm/signalArrayReaders.js +42 -0
- package/dist/orm/signalMetadata.d.ts +17 -0
- package/dist/orm/signalMetadata.js +56 -0
- package/dist/orm/signalMutationGuards.d.ts +4 -0
- package/dist/orm/signalMutationGuards.js +14 -0
- package/dist/orm/signalPathKind.d.ts +2 -0
- package/dist/orm/signalPathKind.js +10 -0
- package/dist/orm/signalPathRules.d.ts +6 -0
- package/dist/orm/signalPathRules.js +28 -0
- package/dist/orm/signalReads.d.ts +26 -0
- package/dist/orm/signalReads.js +64 -0
- package/dist/orm/signalRuntimeAccess.d.ts +16 -0
- package/dist/orm/signalRuntimeAccess.js +24 -0
- package/dist/orm/signalRuntimeDescriptor.d.ts +19 -0
- package/dist/orm/signalRuntimeDescriptor.js +97 -0
- package/dist/orm/signalStorageMutations.d.ts +18 -0
- package/dist/orm/signalStorageMutations.js +26 -0
- package/dist/orm/signalSymbols.d.ts +5 -0
- package/dist/orm/signalSymbols.js +5 -0
- package/dist/orm/signalValueMutations.d.ts +14 -0
- package/dist/orm/signalValueMutations.js +36 -0
- package/dist/orm/sub.d.ts +37 -0
- package/dist/orm/sub.js +187 -0
- package/dist/orm/subscriptionGcDelay.d.ts +4 -0
- package/dist/orm/subscriptionGcDelay.js +26 -0
- package/dist/orm/types/baseMethods.d.ts +43 -0
- package/dist/orm/types/baseMethods.js +1 -0
- package/dist/orm/types/jsonSchema.d.ts +75 -0
- package/dist/orm/types/jsonSchema.js +1 -0
- package/dist/orm/types/modelManifest.d.ts +37 -0
- package/dist/orm/types/modelManifest.js +1 -0
- package/dist/orm/types/path.d.ts +8 -0
- package/dist/orm/types/path.js +1 -0
- package/dist/orm/types/query.d.ts +29 -0
- package/dist/orm/types/query.js +1 -0
- package/dist/orm/types/signal.d.ts +132 -0
- package/dist/orm/types/signal.js +1 -0
- package/dist/react/compatComponentRegistry.d.ts +4 -0
- package/dist/react/compatComponentRegistry.js +19 -0
- package/dist/react/convertToObserver.d.ts +26 -0
- package/dist/react/convertToObserver.js +114 -0
- package/dist/react/executionContextTracker.d.ts +11 -0
- package/dist/react/executionContextTracker.js +28 -0
- package/dist/react/helpers.d.ts +34 -0
- package/dist/react/helpers.js +134 -0
- package/dist/react/observer.d.ts +22 -0
- package/dist/react/observer.js +8 -0
- package/dist/react/promiseBatcher.d.ts +13 -0
- package/dist/react/promiseBatcher.js +118 -0
- package/dist/react/renderAttemptDestroyer.d.ts +19 -0
- package/dist/react/renderAttemptDestroyer.js +46 -0
- package/dist/react/trapRender.d.ts +6 -0
- package/dist/react/trapRender.js +48 -0
- package/dist/react/universal$.d.ts +1 -0
- package/dist/react/universal$.js +18 -0
- package/dist/react/universalSub.d.ts +1 -0
- package/dist/react/universalSub.js +22 -0
- package/dist/react/useApi.d.ts +13 -0
- package/dist/react/useApi.js +67 -0
- package/dist/react/useSub.d.ts +102 -0
- package/dist/react/useSub.js +189 -0
- package/dist/react/useSuspendMemo.d.ts +3 -0
- package/dist/react/useSuspendMemo.js +102 -0
- package/dist/react/wrapIntoSuspense.d.ts +9 -0
- package/dist/react/wrapIntoSuspense.js +102 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.js +28 -0
- package/dist/utils/MockFinalizationRegistry.d.ts +37 -0
- package/dist/utils/MockFinalizationRegistry.js +85 -0
- package/dist/utils/MockWeakRef.d.ts +12 -0
- package/dist/utils/MockWeakRef.js +23 -0
- package/dist/utils/isServer.d.ts +3 -0
- package/dist/utils/isServer.js +18 -0
- package/dist/utils/setDiffDeep.d.ts +1 -0
- package/dist/utils/setDiffDeep.js +61 -0
- package/dist/utils/useIsomorphicLayoutEffect.d.ts +3 -0
- package/dist/utils/useIsomorphicLayoutEffect.js +3 -0
- package/file-based-models.js +3 -0
- package/file-based-models.node.js +6 -0
- package/package.json +77 -32
- package/teamplay.models.auto-init.virtual.js +1 -0
- package/teamplay.models.virtual.js +1 -0
- package/connect/index.js +0 -9
- package/connect/offline/index.js +0 -124
- package/connect/offline/react-native.js +0 -28
- package/connect/offline/web.js +0 -15
- package/connect/test.js +0 -12
- package/index.d.ts +0 -106
- package/index.js +0 -125
- package/orm/$.js +0 -38
- package/orm/Aggregation.js +0 -117
- package/orm/Cache.js +0 -46
- package/orm/Compat/README.md +0 -1064
- package/orm/Compat/SignalCompat.js +0 -1479
- package/orm/Compat/eventsCompat.js +0 -79
- package/orm/Compat/hooksCompat.js +0 -374
- package/orm/Compat/modelEvents.js +0 -225
- package/orm/Compat/queryReadiness.js +0 -191
- package/orm/Compat/refFallback.js +0 -62
- package/orm/Compat/refRegistry.js +0 -61
- package/orm/Compat/silentContext.js +0 -51
- package/orm/Compat/startStopCompat.js +0 -207
- package/orm/Doc.js +0 -969
- package/orm/Query.js +0 -1127
- package/orm/Reaction.js +0 -48
- package/orm/Root.js +0 -88
- package/orm/Signal.js +0 -22
- package/orm/SignalBase.js +0 -696
- package/orm/SubscriptionState.js +0 -138
- package/orm/Value.js +0 -30
- package/orm/addModel.js +0 -31
- package/orm/associations.js +0 -97
- package/orm/batchScheduler.js +0 -62
- package/orm/compatEnv.js +0 -4
- package/orm/connection.js +0 -46
- package/orm/dataTree.js +0 -869
- package/orm/disposeRootContext.js +0 -68
- package/orm/getSignal.js +0 -130
- package/orm/idFields.js +0 -88
- package/orm/index.d.ts +0 -6
- package/orm/index.js +0 -5
- package/orm/missingDoc.js +0 -3
- package/orm/privateData.js +0 -181
- package/orm/rootContext.js +0 -313
- package/orm/rootScope.js +0 -51
- package/orm/sub.js +0 -151
- package/orm/subscriptionGcDelay.js +0 -32
- package/react/compatComponentRegistry.js +0 -20
- package/react/convertToObserver.js +0 -117
- package/react/executionContextTracker.js +0 -32
- package/react/helpers.js +0 -141
- package/react/observer.js +0 -9
- package/react/promiseBatcher.js +0 -115
- package/react/renderAttemptDestroyer.js +0 -47
- package/react/trapRender.js +0 -50
- package/react/universal$.js +0 -18
- package/react/universalSub.js +0 -21
- package/react/useApi.js +0 -63
- package/react/useSub.js +0 -169
- package/react/useSuspendMemo.js +0 -96
- package/react/wrapIntoSuspense.js +0 -119
- package/server.js +0 -31
- package/utils/MockFinalizationRegistry.js +0 -94
- package/utils/MockWeakRef.js +0 -25
- package/utils/isServer.js +0 -17
- package/utils/setDiffDeep.js +0 -58
- package/utils/useIsomorphicLayoutEffect.js +0 -4
- /package/{connect → dist/connect}/lib/sharedb-crosstab-pubsub.cjs +0 -0
- /package/{connect → dist/connect}/sharedbConnection.cjs +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { useLayoutEffect } from 'react';
|
|
2
|
+
import { isModelEventsEnabled, normalizePattern, onModelEvent, removeModelListener, __resetModelEventsForTests } from './modelEvents.js';
|
|
3
|
+
const listeners = new Map();
|
|
4
|
+
export function emit(eventName, ...args) {
|
|
5
|
+
const subs = listeners.get(eventName);
|
|
6
|
+
if (!subs)
|
|
7
|
+
return;
|
|
8
|
+
const snapshot = Array.from(subs);
|
|
9
|
+
for (const handler of snapshot) {
|
|
10
|
+
handler(...args);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function on(eventName, handler) {
|
|
14
|
+
if (!listeners.has(eventName))
|
|
15
|
+
listeners.set(eventName, new Set());
|
|
16
|
+
const subs = listeners.get(eventName);
|
|
17
|
+
subs.add(handler);
|
|
18
|
+
return handler;
|
|
19
|
+
}
|
|
20
|
+
export function removeListener(eventName, handler) {
|
|
21
|
+
const subs = listeners.get(eventName);
|
|
22
|
+
if (!subs)
|
|
23
|
+
return;
|
|
24
|
+
subs.delete(handler);
|
|
25
|
+
if (!subs.size)
|
|
26
|
+
listeners.delete(eventName);
|
|
27
|
+
}
|
|
28
|
+
export function useOn(eventName, patternOrHandler, handler, deps) {
|
|
29
|
+
const isModelEvent = eventName === 'change' || eventName === 'all';
|
|
30
|
+
const isCustom = !isModelEvent || typeof patternOrHandler === 'function';
|
|
31
|
+
if (isCustom) {
|
|
32
|
+
if (typeof patternOrHandler !== 'function')
|
|
33
|
+
throw Error('useOn() expects a handler function');
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
if (typeof handler !== 'function')
|
|
37
|
+
throw Error('useOn() expects a handler function');
|
|
38
|
+
}
|
|
39
|
+
const normalizedPattern = isCustom ? null : normalizePatternMaybe(patternOrHandler);
|
|
40
|
+
useLayoutEffect(() => {
|
|
41
|
+
if (isCustom) {
|
|
42
|
+
const listener = on(eventName, patternOrHandler);
|
|
43
|
+
return () => {
|
|
44
|
+
removeListener(eventName, listener);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (normalizedPattern == null) {
|
|
48
|
+
handler(patternOrHandler);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (!isModelEventsEnabled())
|
|
52
|
+
return;
|
|
53
|
+
const listener = onModelEvent(undefined, eventName, normalizedPattern, handler);
|
|
54
|
+
return () => {
|
|
55
|
+
removeModelListener(undefined, eventName, listener);
|
|
56
|
+
};
|
|
57
|
+
}, [eventName, patternOrHandler, handler, deps, normalizedPattern, isCustom]);
|
|
58
|
+
}
|
|
59
|
+
export function useEmit() {
|
|
60
|
+
return emit;
|
|
61
|
+
}
|
|
62
|
+
export function __resetEventsForTests() {
|
|
63
|
+
listeners.clear();
|
|
64
|
+
__resetModelEventsForTests();
|
|
65
|
+
}
|
|
66
|
+
function normalizePatternMaybe(pattern) {
|
|
67
|
+
try {
|
|
68
|
+
return normalizePattern(pattern);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const useValue: any
|
|
2
|
+
export const useValue$: any
|
|
3
|
+
export const useModel: any
|
|
4
|
+
export const useLocal: any
|
|
5
|
+
export const useLocal$: any
|
|
6
|
+
export const useLocalDoc: any
|
|
7
|
+
export const useLocalDoc$: any
|
|
8
|
+
export const useSession: any
|
|
9
|
+
export const useSession$: any
|
|
10
|
+
export const usePage: any
|
|
11
|
+
export const usePage$: any
|
|
12
|
+
export const useBatch: any
|
|
13
|
+
export const useDoc: any
|
|
14
|
+
export const useDoc$: any
|
|
15
|
+
export const useBatchDoc: any
|
|
16
|
+
export const useBatchDoc$: any
|
|
17
|
+
export const useAsyncDoc: any
|
|
18
|
+
export const useAsyncDoc$: any
|
|
19
|
+
export const useQuery: any
|
|
20
|
+
export const useQuery$: any
|
|
21
|
+
export const useAsyncQuery: any
|
|
22
|
+
export const useAsyncQuery$: any
|
|
23
|
+
export const useBatchQuery: any
|
|
24
|
+
export const useBatchQuery$: any
|
|
25
|
+
export const useQueryIds: any
|
|
26
|
+
export const useBatchQueryIds: any
|
|
27
|
+
export const useAsyncQueryIds: any
|
|
28
|
+
export const useQueryDoc: any
|
|
29
|
+
export const useQueryDoc$: any
|
|
30
|
+
export const useBatchQueryDoc: any
|
|
31
|
+
export const useBatchQueryDoc$: any
|
|
32
|
+
export const useAsyncQueryDoc: any
|
|
33
|
+
export const useAsyncQueryDoc$: any
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { getRootSignal, GLOBAL_ROOT_ID } from "../Root.js";
|
|
2
|
+
import useSub, { useAsyncSub } from "../../react/useSub.js";
|
|
3
|
+
import universal$ from "../../react/universal$.js";
|
|
4
|
+
import * as promiseBatcher from "../../react/promiseBatcher.js";
|
|
5
|
+
import { isCompatEnv } from '../compatEnv.js';
|
|
6
|
+
import { isQueryReady } from './queryReadiness.js';
|
|
7
|
+
const $root = getRootSignal({ rootId: GLOBAL_ROOT_ID, rootFunction: universal$ });
|
|
8
|
+
const emittedCompatWarnings = new Set();
|
|
9
|
+
// Hook-compatible wrapper around $() for compatibility mode.
|
|
10
|
+
export function useValue$(defaultValue) {
|
|
11
|
+
return $root(defaultValue);
|
|
12
|
+
}
|
|
13
|
+
// Returns [value, $signal] similar to useState, but backed by $().
|
|
14
|
+
export function useValue(defaultValue) {
|
|
15
|
+
const $sig = useValue$(defaultValue);
|
|
16
|
+
return [$sig.get(), $sig];
|
|
17
|
+
}
|
|
18
|
+
export function useModel(path) {
|
|
19
|
+
if (arguments.length === 0 || path == null)
|
|
20
|
+
return $root;
|
|
21
|
+
if (path && typeof path.path === 'function')
|
|
22
|
+
return path;
|
|
23
|
+
if (typeof path !== 'string')
|
|
24
|
+
throw Error('useModel() expects a string path or a signal');
|
|
25
|
+
const segments = path.split('.').filter(Boolean);
|
|
26
|
+
if (segments.length === 0)
|
|
27
|
+
return $root;
|
|
28
|
+
let $cursor = $root;
|
|
29
|
+
for (const segment of segments) {
|
|
30
|
+
$cursor = $cursor[segment];
|
|
31
|
+
}
|
|
32
|
+
return $cursor;
|
|
33
|
+
}
|
|
34
|
+
export function useLocal$(path) {
|
|
35
|
+
const resolvedPath = resolveLocalPath(path);
|
|
36
|
+
if (!resolvedPath)
|
|
37
|
+
return $root;
|
|
38
|
+
const segments = resolvedPath.split('.').filter(Boolean);
|
|
39
|
+
let $cursor = $root;
|
|
40
|
+
for (const segment of segments) {
|
|
41
|
+
$cursor = $cursor[segment];
|
|
42
|
+
}
|
|
43
|
+
return $cursor;
|
|
44
|
+
}
|
|
45
|
+
export function useLocal(path) {
|
|
46
|
+
const $sig = useLocal$(path);
|
|
47
|
+
return [$sig.get(), $sig];
|
|
48
|
+
}
|
|
49
|
+
export function useLocalDoc$(collection, id) {
|
|
50
|
+
if (collection == null)
|
|
51
|
+
throw Error('useLocalDoc() expects a collection name');
|
|
52
|
+
if (id == null)
|
|
53
|
+
return undefined;
|
|
54
|
+
return $root[collection][id];
|
|
55
|
+
}
|
|
56
|
+
export function useLocalDoc(collection, id) {
|
|
57
|
+
const $doc = useLocalDoc$(collection, id);
|
|
58
|
+
if (!$doc)
|
|
59
|
+
return [undefined, undefined];
|
|
60
|
+
return [$doc.get(), $doc];
|
|
61
|
+
}
|
|
62
|
+
export function useSession$(path) {
|
|
63
|
+
return useLocal$(prefixLocalPath('_session', path));
|
|
64
|
+
}
|
|
65
|
+
export function useSession(path) {
|
|
66
|
+
return useLocal(prefixLocalPath('_session', path));
|
|
67
|
+
}
|
|
68
|
+
export function usePage$(path) {
|
|
69
|
+
return useLocal$(prefixLocalPath('_page', path));
|
|
70
|
+
}
|
|
71
|
+
export function usePage(path) {
|
|
72
|
+
return useLocal(prefixLocalPath('_page', path));
|
|
73
|
+
}
|
|
74
|
+
export function useBatch() {
|
|
75
|
+
const promise = promiseBatcher.getPromiseAll();
|
|
76
|
+
if (promise)
|
|
77
|
+
throw promise;
|
|
78
|
+
}
|
|
79
|
+
export function useDoc$(collection, id, options) {
|
|
80
|
+
const $doc = getDocSignal(collection, id, 'useDoc');
|
|
81
|
+
const normalizedOptions = normalizeSyncSubOptions(options);
|
|
82
|
+
return useSub($doc, undefined, normalizedOptions);
|
|
83
|
+
}
|
|
84
|
+
export function useDoc(collection, id, options) {
|
|
85
|
+
const $doc = useDoc$(collection, id, options);
|
|
86
|
+
return [$doc.get(), $doc];
|
|
87
|
+
}
|
|
88
|
+
export function useBatchDoc(collection, id, options) {
|
|
89
|
+
const $doc = useBatchDoc$(collection, id, options);
|
|
90
|
+
if (!$doc)
|
|
91
|
+
return [undefined, undefined];
|
|
92
|
+
return [$doc.get(), $doc];
|
|
93
|
+
}
|
|
94
|
+
export function useBatchDoc$(collection, id, _options) {
|
|
95
|
+
const $doc = getDocSignal(collection, id, 'useBatchDoc');
|
|
96
|
+
const options = _options ? { ..._options, ...BATCH_SUB_OPTIONS } : BATCH_SUB_OPTIONS;
|
|
97
|
+
return useSub($doc, undefined, options);
|
|
98
|
+
}
|
|
99
|
+
export function useAsyncDoc$(collection, id, options) {
|
|
100
|
+
const $doc = getDocSignal(collection, id, 'useAsyncDoc');
|
|
101
|
+
return useAsyncSub($doc, undefined, options);
|
|
102
|
+
}
|
|
103
|
+
export function useAsyncDoc(collection, id, options) {
|
|
104
|
+
const $doc = useAsyncDoc$(collection, id, options);
|
|
105
|
+
if (!$doc)
|
|
106
|
+
return [undefined, undefined];
|
|
107
|
+
return [$doc.get(), $doc];
|
|
108
|
+
}
|
|
109
|
+
function useSubscribedQuery(collection, query, options, hookName, subscribe) {
|
|
110
|
+
const normalizedQuery = normalizeQuery(query, hookName);
|
|
111
|
+
const $collection = getCollectionSignal(collection, query, hookName);
|
|
112
|
+
const $query = subscribe($collection, normalizedQuery, options);
|
|
113
|
+
return {
|
|
114
|
+
normalizedQuery,
|
|
115
|
+
$collection,
|
|
116
|
+
$query: getExtraQuerySignal($query, normalizedQuery)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function getExtraQuerySignal($query, normalizedQuery) {
|
|
120
|
+
if (!$query)
|
|
121
|
+
return $query;
|
|
122
|
+
return isExtraQuery(normalizedQuery) ? $query.extra : $query;
|
|
123
|
+
}
|
|
124
|
+
export function useQuery$(collection, query, options) {
|
|
125
|
+
const normalizedOptions = normalizeSyncSubOptions(options);
|
|
126
|
+
const { $query } = useSubscribedQuery(collection, query, normalizedOptions, 'useQuery', useSub);
|
|
127
|
+
return $query;
|
|
128
|
+
}
|
|
129
|
+
export function useQuery(collection, query, options) {
|
|
130
|
+
const normalizedOptions = normalizeSyncSubOptions(options);
|
|
131
|
+
const { $collection, $query } = useSubscribedQuery(collection, query, normalizedOptions, 'useQuery', useSub);
|
|
132
|
+
return [$query.get(), $collection];
|
|
133
|
+
}
|
|
134
|
+
export function useAsyncQuery$(collection, query, options) {
|
|
135
|
+
const { $query } = useSubscribedQuery(collection, query, options, 'useAsyncQuery', useAsyncSub);
|
|
136
|
+
return $query;
|
|
137
|
+
}
|
|
138
|
+
export function useAsyncQuery(collection, query, options) {
|
|
139
|
+
const { $collection, $query } = useSubscribedQuery(collection, query, options, 'useAsyncQuery', useAsyncSub);
|
|
140
|
+
if (!$query)
|
|
141
|
+
return [undefined, $collection];
|
|
142
|
+
return [$query.get(), $collection];
|
|
143
|
+
}
|
|
144
|
+
export function useBatchQuery$(collection, query, _options) {
|
|
145
|
+
const options = normalizeBatchSubOptions(_options);
|
|
146
|
+
const { $query } = useSubscribedQuery(collection, query, options, 'useBatchQuery', useSub);
|
|
147
|
+
return $query;
|
|
148
|
+
}
|
|
149
|
+
export function useBatchQuery(collection, query, _options) {
|
|
150
|
+
const options = normalizeBatchSubOptions(_options);
|
|
151
|
+
const { $collection, $query } = useSubscribedQuery(collection, query, options, 'useBatchQuery', useSub);
|
|
152
|
+
if (!$query)
|
|
153
|
+
return [undefined, $collection];
|
|
154
|
+
return [$query.get(), $collection];
|
|
155
|
+
}
|
|
156
|
+
export function useQueryIds(collection, ids = [], options = {}) {
|
|
157
|
+
const list = Array.isArray(ids) ? ids.slice() : [];
|
|
158
|
+
if (options?.reverse)
|
|
159
|
+
list.reverse();
|
|
160
|
+
const [docs, $collection] = useQuery(collection, { _id: { $in: list } }, options);
|
|
161
|
+
if (!docs)
|
|
162
|
+
return [docs, $collection];
|
|
163
|
+
const docsById = new Map();
|
|
164
|
+
for (const doc of docs) {
|
|
165
|
+
const id = doc?._id ?? doc?.id;
|
|
166
|
+
if (id != null)
|
|
167
|
+
docsById.set(id, doc);
|
|
168
|
+
}
|
|
169
|
+
const items = list.map(id => docsById.get(id)).filter(Boolean);
|
|
170
|
+
return [items, $collection];
|
|
171
|
+
}
|
|
172
|
+
export function useBatchQueryIds(collection, ids = [], options = {}) {
|
|
173
|
+
const list = Array.isArray(ids) ? ids.slice() : [];
|
|
174
|
+
if (options?.reverse)
|
|
175
|
+
list.reverse();
|
|
176
|
+
const [docs, $collection] = useBatchQuery(collection, { _id: { $in: list } }, options);
|
|
177
|
+
if (!docs)
|
|
178
|
+
return [docs, $collection];
|
|
179
|
+
const docsById = new Map();
|
|
180
|
+
for (const doc of docs) {
|
|
181
|
+
const id = doc?._id ?? doc?.id;
|
|
182
|
+
if (id != null)
|
|
183
|
+
docsById.set(id, doc);
|
|
184
|
+
}
|
|
185
|
+
const items = list.map(id => docsById.get(id)).filter(Boolean);
|
|
186
|
+
return [items, $collection];
|
|
187
|
+
}
|
|
188
|
+
export function useAsyncQueryIds(collection, ids = [], options = {}) {
|
|
189
|
+
const list = Array.isArray(ids) ? ids.slice() : [];
|
|
190
|
+
if (options?.reverse)
|
|
191
|
+
list.reverse();
|
|
192
|
+
const [docs, $collection] = useAsyncQuery(collection, { _id: { $in: list } }, options);
|
|
193
|
+
if (docs == null)
|
|
194
|
+
return [undefined, $collection];
|
|
195
|
+
const docsById = new Map();
|
|
196
|
+
for (const doc of docs) {
|
|
197
|
+
const id = doc?._id ?? doc?.id;
|
|
198
|
+
if (id != null)
|
|
199
|
+
docsById.set(id, doc);
|
|
200
|
+
}
|
|
201
|
+
const items = list.map(id => docsById.get(id)).filter(Boolean);
|
|
202
|
+
return [items, $collection];
|
|
203
|
+
}
|
|
204
|
+
export function useQueryDoc(collection, query, options) {
|
|
205
|
+
const normalized = normalizeQuery(query, 'useQueryDoc');
|
|
206
|
+
const queryDoc = {
|
|
207
|
+
...normalized,
|
|
208
|
+
$limit: 1,
|
|
209
|
+
$sort: normalized.$sort || { createdAt: -1 }
|
|
210
|
+
};
|
|
211
|
+
const [docs, $collection] = useQuery(collection, queryDoc, options);
|
|
212
|
+
const doc = docs && docs[0];
|
|
213
|
+
const docId = doc?._id ?? doc?.id;
|
|
214
|
+
const $doc = docId != null ? $collection[docId] : undefined;
|
|
215
|
+
return [doc, $doc];
|
|
216
|
+
}
|
|
217
|
+
export function useQueryDoc$(collection, query, options) {
|
|
218
|
+
const [, $doc] = useQueryDoc(collection, query, options);
|
|
219
|
+
return $doc;
|
|
220
|
+
}
|
|
221
|
+
export function useBatchQueryDoc(collection, query, options) {
|
|
222
|
+
const normalized = normalizeQuery(query, 'useBatchQueryDoc');
|
|
223
|
+
const queryDoc = {
|
|
224
|
+
...normalized,
|
|
225
|
+
$limit: 1,
|
|
226
|
+
$sort: normalized.$sort || { createdAt: -1 }
|
|
227
|
+
};
|
|
228
|
+
const [docs, $collection] = useBatchQuery(collection, queryDoc, options);
|
|
229
|
+
if (!docs)
|
|
230
|
+
return [undefined, undefined];
|
|
231
|
+
const doc = docs && docs[0];
|
|
232
|
+
const docId = doc?._id ?? doc?.id;
|
|
233
|
+
const $doc = docId != null ? $collection[docId] : undefined;
|
|
234
|
+
return [doc, $doc];
|
|
235
|
+
}
|
|
236
|
+
export function useBatchQueryDoc$(collection, query, options) {
|
|
237
|
+
const [, $doc] = useBatchQueryDoc(collection, query, options);
|
|
238
|
+
return $doc;
|
|
239
|
+
}
|
|
240
|
+
export function useAsyncQueryDoc(collection, query, options) {
|
|
241
|
+
const normalized = normalizeQuery(query, 'useAsyncQueryDoc');
|
|
242
|
+
const queryDoc = {
|
|
243
|
+
...normalized,
|
|
244
|
+
$limit: 1,
|
|
245
|
+
$sort: normalized.$sort || { createdAt: -1 }
|
|
246
|
+
};
|
|
247
|
+
const [docs, $collection] = useAsyncQuery(collection, queryDoc, options);
|
|
248
|
+
if (docs == null)
|
|
249
|
+
return [undefined, undefined];
|
|
250
|
+
const doc = docs && docs[0];
|
|
251
|
+
const docId = doc?._id ?? doc?.id;
|
|
252
|
+
const $doc = docId != null ? $collection[docId] : undefined;
|
|
253
|
+
return [doc, $doc];
|
|
254
|
+
}
|
|
255
|
+
export function useAsyncQueryDoc$(collection, query, options) {
|
|
256
|
+
const [, $doc] = useAsyncQueryDoc(collection, query, options);
|
|
257
|
+
return $doc;
|
|
258
|
+
}
|
|
259
|
+
function resolveLocalPath(path) {
|
|
260
|
+
if (path && typeof path.path === 'function')
|
|
261
|
+
return path.path();
|
|
262
|
+
if (typeof path === 'string')
|
|
263
|
+
return path;
|
|
264
|
+
if (path == null)
|
|
265
|
+
return '';
|
|
266
|
+
throw Error('useLocal() expects a string path or a signal');
|
|
267
|
+
}
|
|
268
|
+
function prefixLocalPath(prefix, path) {
|
|
269
|
+
if (path == null || path === '')
|
|
270
|
+
return prefix;
|
|
271
|
+
let resolved = path;
|
|
272
|
+
if (path && typeof path.path === 'function')
|
|
273
|
+
resolved = path.path();
|
|
274
|
+
if (typeof resolved !== 'string')
|
|
275
|
+
throw Error(`${prefix} hook expects a string path or a signal`);
|
|
276
|
+
if (resolved.startsWith(prefix + '.'))
|
|
277
|
+
return resolved;
|
|
278
|
+
if (resolved === prefix)
|
|
279
|
+
return resolved;
|
|
280
|
+
return `${prefix}.${resolved}`;
|
|
281
|
+
}
|
|
282
|
+
function getDocSignal(collection, id, hookName) {
|
|
283
|
+
if (typeof collection !== 'string') {
|
|
284
|
+
throw Error(`[${hookName}] collection must be a string. Got: ${collection}`);
|
|
285
|
+
}
|
|
286
|
+
if (id == null) {
|
|
287
|
+
warnCompatOnce(`doc:${hookName}:${collection}:${id}`, `
|
|
288
|
+
[${hookName}] You are trying to subscribe to an undefined document id:
|
|
289
|
+
${collection}.${id}
|
|
290
|
+
Falling back to '__NULL__' document to prevent critical crash.
|
|
291
|
+
You should prevent situations when the \`id\` is undefined.
|
|
292
|
+
`);
|
|
293
|
+
id = '__NULL__';
|
|
294
|
+
}
|
|
295
|
+
return $root[collection][id];
|
|
296
|
+
}
|
|
297
|
+
function getCollectionSignal(collection, query, hookName) {
|
|
298
|
+
if (typeof collection !== 'string') {
|
|
299
|
+
throw Error(`[${hookName}] collection must be a string. Got: ${collection}`);
|
|
300
|
+
}
|
|
301
|
+
if (query == null) {
|
|
302
|
+
warnCompatOnce(`query:${hookName}:${collection}`, `
|
|
303
|
+
[${hookName}] Query is undefined. Got:
|
|
304
|
+
${collection}, ${query}
|
|
305
|
+
Falling back to {_id: '__NON_EXISTENT__'} query to prevent critical crash.
|
|
306
|
+
You should prevent situations when the \`query\` is undefined.
|
|
307
|
+
`);
|
|
308
|
+
}
|
|
309
|
+
return $root[collection];
|
|
310
|
+
}
|
|
311
|
+
function warnCompatOnce(key, message) {
|
|
312
|
+
if (emittedCompatWarnings.has(key))
|
|
313
|
+
return;
|
|
314
|
+
emittedCompatWarnings.add(key);
|
|
315
|
+
console.warn(message);
|
|
316
|
+
}
|
|
317
|
+
export function __resetCompatWarningsForTests() {
|
|
318
|
+
emittedCompatWarnings.clear();
|
|
319
|
+
}
|
|
320
|
+
function normalizeQuery(query, hookName) {
|
|
321
|
+
if (query == null)
|
|
322
|
+
return { _id: '__NON_EXISTENT__' };
|
|
323
|
+
if (typeof query !== 'object') {
|
|
324
|
+
throw Error(`[${hookName}] query must be an object. Got: ${query}`);
|
|
325
|
+
}
|
|
326
|
+
return query;
|
|
327
|
+
}
|
|
328
|
+
function isExtraQuery(query) {
|
|
329
|
+
if (!query || typeof query !== 'object')
|
|
330
|
+
return false;
|
|
331
|
+
return !!(query.$count ||
|
|
332
|
+
query.$queryName ||
|
|
333
|
+
query.$aggregationName);
|
|
334
|
+
}
|
|
335
|
+
const BATCH_SUB_OPTIONS = Object.freeze({
|
|
336
|
+
async: false,
|
|
337
|
+
batch: true,
|
|
338
|
+
compatAttemptCleanup: true,
|
|
339
|
+
// Batch hooks are a hard suspense barrier. Deferred params can skip the barrier
|
|
340
|
+
// on route transitions and cause immediate reads from stale/empty local nodes.
|
|
341
|
+
defer: false
|
|
342
|
+
});
|
|
343
|
+
function normalizeSyncSubOptions(options) {
|
|
344
|
+
if (!isCompatEnv()) {
|
|
345
|
+
return options ? { ...options, async: false } : options;
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
...(options || {}),
|
|
349
|
+
async: false,
|
|
350
|
+
compatAttemptCleanup: true,
|
|
351
|
+
// Compat sync hooks are strict by design: no deferred snapshots between route/tab switches.
|
|
352
|
+
defer: false
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function normalizeBatchSubOptions(options) {
|
|
356
|
+
return options ? { ...options, ...BATCH_SUB_OPTIONS } : BATCH_SUB_OPTIONS;
|
|
357
|
+
}
|
|
358
|
+
export const __COMPAT_BATCH_READY__ = {
|
|
359
|
+
isQueryReady
|
|
360
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function isModelEventsEnabled(): boolean;
|
|
2
|
+
export function normalizePattern(pattern: any, methodName: any): string | null;
|
|
3
|
+
export function onModelEvent(rootId: any, eventName: any, pattern: any, handler: any): any;
|
|
4
|
+
export function removeModelListener(rootId: any, eventName: any, handler: any): void;
|
|
5
|
+
export function emitModelChange(path: any, value: any, prevValue: any, meta: any): void;
|
|
6
|
+
export function __resetModelEventsForTests(): void;
|