teamplay 0.5.0-alpha.2 → 0.5.0-alpha.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.
- package/dist/index.d.ts +22 -8
- package/dist/index.js +1 -4
- package/dist/orm/Aggregation.d.ts +6 -4
- package/dist/orm/Aggregation.js +39 -11
- package/dist/orm/Compat/SignalCompat.js +141 -409
- package/dist/orm/Compat/queryReadiness.d.ts +13 -5
- package/dist/orm/Compat/silentContext.js +4 -22
- package/dist/orm/Compat/startStopCompat.js +33 -0
- package/dist/orm/Doc.js +48 -3
- package/dist/orm/Query.d.ts +1 -0
- package/dist/orm/Query.js +67 -22
- package/dist/orm/Signal.d.ts +3 -3
- package/dist/orm/SignalBase.d.ts +27 -2
- package/dist/orm/SignalBase.js +296 -5
- package/dist/orm/addModel.d.ts +9 -2
- package/dist/orm/getSignal.js +0 -2
- package/dist/orm/index.d.ts +2 -2
- package/dist/orm/privateData.d.ts +7 -22
- package/dist/orm/signalMetadata.d.ts +1 -1
- package/dist/orm/signalMetadata.js +29 -3
- package/dist/orm/signalReads.d.ts +1 -1
- package/dist/orm/signalReads.js +7 -7
- package/dist/orm/signalSymbols.js +1 -1
- package/dist/orm/sub.d.ts +9 -1
- package/dist/orm/subscriptionGcDelay.js +2 -6
- package/dist/orm/types/baseMethods.d.ts +2 -1
- package/dist/orm/types/jsonSchema.d.ts +3 -3
- package/dist/orm/types/modelManifest.d.ts +12 -1
- package/dist/orm/types/query.d.ts +7 -1
- package/dist/orm/types/signal.d.ts +44 -15
- package/dist/react/convertToObserver.js +1 -4
- package/dist/react/promiseBatcher.js +1 -1
- package/dist/react/renderAttemptDestroyer.d.ts +0 -8
- package/dist/react/renderAttemptDestroyer.js +2 -28
- package/dist/react/trapRender.js +3 -3
- package/dist/react/useSub.d.ts +104 -5
- package/dist/react/useSub.js +191 -32
- package/dist/react/useSuspendMemo.js +1 -5
- package/dist/server.d.ts +1 -1
- package/package.json +16 -10
- package/dist/orm/Compat/hooksCompat.d.ts +0 -33
- package/dist/orm/Compat/hooksCompat.js +0 -360
- package/dist/react/compatComponentRegistry.d.ts +0 -4
- package/dist/react/compatComponentRegistry.js +0 -19
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export function
|
|
4
|
-
|
|
5
|
-
export function
|
|
1
|
+
import type { PathSegment } from '../types/path.js'
|
|
2
|
+
|
|
3
|
+
export function isDocReady (segments: readonly PathSegment[]): boolean
|
|
4
|
+
|
|
5
|
+
export function isQueryReady (
|
|
6
|
+
collection: string,
|
|
7
|
+
idsSegments: readonly PathSegment[],
|
|
8
|
+
docsSegments: readonly PathSegment[],
|
|
9
|
+
extraSegments: readonly PathSegment[],
|
|
10
|
+
aggregationSegments: readonly PathSegment[],
|
|
11
|
+
isAggregate: boolean,
|
|
12
|
+
hasExtraResult: boolean
|
|
13
|
+
): boolean
|
|
@@ -8,39 +8,21 @@ export function isModelEventsSilentContextActive() {
|
|
|
8
8
|
}
|
|
9
9
|
export function runInSilentContext(fn) {
|
|
10
10
|
silentDepth += 1;
|
|
11
|
-
let result;
|
|
12
11
|
try {
|
|
13
|
-
|
|
12
|
+
return fn();
|
|
14
13
|
}
|
|
15
|
-
|
|
14
|
+
finally {
|
|
16
15
|
silentDepth -= 1;
|
|
17
|
-
throw error;
|
|
18
16
|
}
|
|
19
|
-
if (result?.then) {
|
|
20
|
-
return Promise.resolve(result).finally(() => {
|
|
21
|
-
silentDepth -= 1;
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
silentDepth -= 1;
|
|
25
|
-
return result;
|
|
26
17
|
}
|
|
27
18
|
export function runInModelEventsSilentContext(fn) {
|
|
28
19
|
modelEventsSilentDepth += 1;
|
|
29
|
-
let result;
|
|
30
20
|
try {
|
|
31
|
-
|
|
21
|
+
return fn();
|
|
32
22
|
}
|
|
33
|
-
|
|
23
|
+
finally {
|
|
34
24
|
modelEventsSilentDepth -= 1;
|
|
35
|
-
throw error;
|
|
36
|
-
}
|
|
37
|
-
if (result?.then) {
|
|
38
|
-
return Promise.resolve(result).finally(() => {
|
|
39
|
-
modelEventsSilentDepth -= 1;
|
|
40
|
-
});
|
|
41
25
|
}
|
|
42
|
-
modelEventsSilentDepth -= 1;
|
|
43
|
-
return result;
|
|
44
26
|
}
|
|
45
27
|
export function __resetSilentContextForTests() {
|
|
46
28
|
silentDepth = 0;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { observe, raw, unobserve } from '@nx-js/observer-util';
|
|
2
|
+
import { getActiveDocOpContext } from '../Doc.js';
|
|
2
3
|
import { getRoot } from "../Root.js";
|
|
3
4
|
import { scheduleReaction } from '../batchScheduler.js';
|
|
4
5
|
const START_REACTIONS = Symbol('compat start reactions');
|
|
@@ -19,11 +20,15 @@ export function compatStartOnRoot($root, targetPath, ...depsAndGetter) {
|
|
|
19
20
|
const targetSegments = parsePathSegments(targetPath);
|
|
20
21
|
const $target = resolveSignal($root, targetSegments);
|
|
21
22
|
const targetKey = $target.path();
|
|
23
|
+
const depPaths = deps
|
|
24
|
+
.map(dep => getStartDepPath(dep, $root))
|
|
25
|
+
.filter(Boolean);
|
|
22
26
|
const store = getStartStore($root);
|
|
23
27
|
const existing = store.get(targetKey);
|
|
24
28
|
if (existing)
|
|
25
29
|
existing.stop();
|
|
26
30
|
let lastSourceSnapshot = UNSET;
|
|
31
|
+
let lastTargetSnapshot = UNSET;
|
|
27
32
|
const reaction = observe(() => {
|
|
28
33
|
const resolvedDeps = [];
|
|
29
34
|
for (const dep of deps) {
|
|
@@ -45,8 +50,23 @@ export function compatStartOnRoot($root, targetPath, ...depsAndGetter) {
|
|
|
45
50
|
if (lastSourceSnapshot !== UNSET && deepEqualStartValue(lastSourceSnapshot, sourceSnapshot)) {
|
|
46
51
|
return;
|
|
47
52
|
}
|
|
53
|
+
const currentTargetSnapshot = lastTargetSnapshot === UNSET
|
|
54
|
+
? UNSET
|
|
55
|
+
: detachStartValue($target.peek());
|
|
56
|
+
if (currentTargetSnapshot !== UNSET && deepEqualStartValue(currentTargetSnapshot, sourceSnapshot)) {
|
|
57
|
+
lastSourceSnapshot = sourceSnapshot;
|
|
58
|
+
lastTargetSnapshot = sourceSnapshot;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (currentTargetSnapshot !== UNSET &&
|
|
62
|
+
!deepEqualStartValue(lastTargetSnapshot, currentTargetSnapshot) &&
|
|
63
|
+
isActiveLocalDocOpForDeps(depPaths)) {
|
|
64
|
+
lastSourceSnapshot = sourceSnapshot;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
48
67
|
lastSourceSnapshot = sourceSnapshot;
|
|
49
68
|
const detachedValue = detachStartValue(sourceSnapshot);
|
|
69
|
+
lastTargetSnapshot = detachStartValue(detachedValue);
|
|
50
70
|
// Keep the detached snapshot to avoid aliasing source and target.
|
|
51
71
|
// Old racer start() writes through diffDeep by default. In compat mode we must preserve
|
|
52
72
|
// that behavior, but also avoid reading the target reactively inside start(), otherwise
|
|
@@ -104,9 +124,22 @@ function resolveStartDep(dep, $root) {
|
|
|
104
124
|
throw err;
|
|
105
125
|
}
|
|
106
126
|
}
|
|
127
|
+
function getStartDepPath(dep, $root) {
|
|
128
|
+
if (isSignalLike(dep))
|
|
129
|
+
return dep.path();
|
|
130
|
+
if (typeof dep === 'string')
|
|
131
|
+
return resolveSignal($root, parsePathSegments(dep)).path();
|
|
132
|
+
}
|
|
107
133
|
function getStartDepValue($signal) {
|
|
108
134
|
return readReactiveSnapshot($signal.get());
|
|
109
135
|
}
|
|
136
|
+
function isActiveLocalDocOpForDeps(depPaths) {
|
|
137
|
+
const context = getActiveDocOpContext();
|
|
138
|
+
if (!context?.source)
|
|
139
|
+
return false;
|
|
140
|
+
const docPath = `${context.collection}.${context.docId}`;
|
|
141
|
+
return depPaths.some(depPath => depPath === docPath || depPath.startsWith(docPath + '.'));
|
|
142
|
+
}
|
|
110
143
|
function readReactiveSnapshot(value) {
|
|
111
144
|
if (!value || typeof value !== 'object')
|
|
112
145
|
return value;
|
package/dist/orm/Doc.js
CHANGED
|
@@ -12,6 +12,43 @@ import { getRoot, ROOT_ID, GLOBAL_ROOT_ID, getRootTransportMode } from "./Root.j
|
|
|
12
12
|
import { registerRootOwnedDirectDocSubscription, unregisterRootOwnedDirectDocSubscription, getRootOwnedDirectDocSubscriptions, clearRootOwnedDirectDocSubscriptions } from "./rootContext.js";
|
|
13
13
|
const ERROR_ON_EXCESSIVE_UNSUBSCRIBES = false;
|
|
14
14
|
const DOC_FINALIZATION_TOKENS = new WeakMap();
|
|
15
|
+
const RECENT_DOC_OP_CONTEXT_TTL = 100;
|
|
16
|
+
const ACTIVE_DOC_OP_CONTEXTS = [];
|
|
17
|
+
let recentDocOpContext;
|
|
18
|
+
export function getActiveDocOpContext() {
|
|
19
|
+
return ACTIVE_DOC_OP_CONTEXTS[ACTIVE_DOC_OP_CONTEXTS.length - 1] || recentDocOpContext;
|
|
20
|
+
}
|
|
21
|
+
function pushActiveDocOpContext(collection, docId, source) {
|
|
22
|
+
const context = { collection, docId, source };
|
|
23
|
+
ACTIVE_DOC_OP_CONTEXTS.push(context);
|
|
24
|
+
recentDocOpContext = context;
|
|
25
|
+
}
|
|
26
|
+
function popActiveDocOpContext(collection, docId, source) {
|
|
27
|
+
const current = ACTIVE_DOC_OP_CONTEXTS[ACTIVE_DOC_OP_CONTEXTS.length - 1];
|
|
28
|
+
if (current?.collection === collection && current?.docId === docId && current?.source === source) {
|
|
29
|
+
ACTIVE_DOC_OP_CONTEXTS.pop();
|
|
30
|
+
clearRecentDocOpContext(current);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let index = -1;
|
|
34
|
+
for (let i = ACTIVE_DOC_OP_CONTEXTS.length - 1; i >= 0; i--) {
|
|
35
|
+
const context = ACTIVE_DOC_OP_CONTEXTS[i];
|
|
36
|
+
if (context.collection === collection && context.docId === docId && context.source === source) {
|
|
37
|
+
index = i;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (index === -1)
|
|
42
|
+
return;
|
|
43
|
+
const [context] = ACTIVE_DOC_OP_CONTEXTS.splice(index, 1);
|
|
44
|
+
clearRecentDocOpContext(context);
|
|
45
|
+
}
|
|
46
|
+
function clearRecentDocOpContext(context) {
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
if (recentDocOpContext === context)
|
|
49
|
+
recentDocOpContext = undefined;
|
|
50
|
+
}, RECENT_DOC_OP_CONTEXT_TTL);
|
|
51
|
+
}
|
|
15
52
|
function getDocFinalizationToken($doc) {
|
|
16
53
|
let token = DOC_FINALIZATION_TOKENS.get($doc);
|
|
17
54
|
if (!token) {
|
|
@@ -149,7 +186,15 @@ class Doc {
|
|
|
149
186
|
doc.on('create', () => this._refData());
|
|
150
187
|
doc.on('del', () => this._refMissingData());
|
|
151
188
|
if (isModelEventsEnabled()) {
|
|
152
|
-
doc.on('op',
|
|
189
|
+
doc.on('before op', (_op, source) => pushActiveDocOpContext(this.collection, this.docId, source));
|
|
190
|
+
doc.on('op', (op, source) => {
|
|
191
|
+
try {
|
|
192
|
+
emitDocOp(this.collection, this.docId, op, source);
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
popActiveDocOpContext(this.collection, this.docId, source);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
153
198
|
}
|
|
154
199
|
}
|
|
155
200
|
_refMissingData() {
|
|
@@ -870,7 +915,7 @@ function createPendingDestroyEntry() {
|
|
|
870
915
|
reject: rejectPending
|
|
871
916
|
};
|
|
872
917
|
}
|
|
873
|
-
function emitDocOp(collection, docId, op) {
|
|
918
|
+
function emitDocOp(collection, docId, op, source) {
|
|
874
919
|
if (!isModelEventsEnabled())
|
|
875
920
|
return;
|
|
876
921
|
const ops = Array.isArray(op) ? op : [op];
|
|
@@ -879,7 +924,7 @@ function emitDocOp(collection, docId, op) {
|
|
|
879
924
|
continue;
|
|
880
925
|
const baseSegments = [collection, docId];
|
|
881
926
|
let pathSegments = baseSegments.concat(component.p);
|
|
882
|
-
const meta = {};
|
|
927
|
+
const meta = { source };
|
|
883
928
|
let value;
|
|
884
929
|
let prevValue;
|
|
885
930
|
if (has(component, 'si') || has(component, 'sd')) {
|
package/dist/orm/Query.d.ts
CHANGED
|
@@ -113,5 +113,6 @@ export class QuerySubscriptions {
|
|
|
113
113
|
|
|
114
114
|
export const querySubscriptions: QuerySubscriptions
|
|
115
115
|
export function getQuerySignal (collectionName: string, params: unknown, options?: QuerySignalOptions): Signal
|
|
116
|
+
export function materializeQueryDataDocsToCollection (collectionName: string, docs: unknown): void
|
|
116
117
|
export function hashQuery (collectionName: string, params: unknown): string
|
|
117
118
|
export function parseQueryHash (hash: string): QueryHashParts
|
package/dist/orm/Query.js
CHANGED
|
@@ -465,7 +465,7 @@ export class QuerySubscriptions {
|
|
|
465
465
|
}
|
|
466
466
|
subscribe($query, { intent = 'subscribe' } = {}) {
|
|
467
467
|
const collectionName = $query[COLLECTION_NAME];
|
|
468
|
-
const params = cloneQueryParams($query[PARAMS]);
|
|
468
|
+
const params = cloneQueryParams(collectionName, $query[PARAMS]);
|
|
469
469
|
const transportHash = $query[HASH];
|
|
470
470
|
const rootId = getOwningRootId($query);
|
|
471
471
|
const ownerKey = getQueryOwnerKey(rootId, transportHash);
|
|
@@ -901,8 +901,26 @@ function maybeMaterializeQueryDocsToCollection(collectionName, shareDocs) {
|
|
|
901
901
|
_set([collectionName, doc.id], raw(doc.data));
|
|
902
902
|
}
|
|
903
903
|
}
|
|
904
|
+
export function materializeQueryDataDocsToCollection(collectionName, docs) {
|
|
905
|
+
if (!Array.isArray(docs))
|
|
906
|
+
return;
|
|
907
|
+
for (const doc of docs) {
|
|
908
|
+
const rawDoc = raw(doc);
|
|
909
|
+
if (!isPlainObject(rawDoc))
|
|
910
|
+
continue;
|
|
911
|
+
const docId = rawDoc._id ?? rawDoc.id;
|
|
912
|
+
if (docId == null)
|
|
913
|
+
continue;
|
|
914
|
+
const existing = getRaw([collectionName, docId]);
|
|
915
|
+
if (existing != null)
|
|
916
|
+
continue;
|
|
917
|
+
const idFields = getIdFieldsForSegments([collectionName, docId]);
|
|
918
|
+
injectIdFields(rawDoc, idFields, docId);
|
|
919
|
+
_set([collectionName, docId], rawDoc);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
904
922
|
export function hashQuery(collectionName, params) {
|
|
905
|
-
params = normalizeQueryParamsForHash(params);
|
|
923
|
+
params = normalizeQueryParamsForHash(collectionName, params);
|
|
906
924
|
// TODO: probably makes sense to use fast-stable-json-stringify for this because of the params
|
|
907
925
|
return JSON.stringify({ query: [collectionName, params] });
|
|
908
926
|
}
|
|
@@ -916,7 +934,7 @@ export function parseQueryHash(hash) {
|
|
|
916
934
|
}
|
|
917
935
|
}
|
|
918
936
|
export function getQuerySignal(collectionName, params, options) {
|
|
919
|
-
params = cloneQueryParams(params);
|
|
937
|
+
params = cloneQueryParams(collectionName, params);
|
|
920
938
|
const transportHash = hashQuery(collectionName, params);
|
|
921
939
|
const { root, signalOptions } = parseQuerySignalOptions(options);
|
|
922
940
|
const signalHash = getScopedSignalHash(root?.[ROOT_ID] ?? signalOptions.rootId, transportHash, 'querySignal');
|
|
@@ -969,10 +987,9 @@ function getOwningRootId($query) {
|
|
|
969
987
|
function getQueryOwnerKey(rootId, transportHash) {
|
|
970
988
|
return getScopedSignalHash(rootId, transportHash, 'queryOwner');
|
|
971
989
|
}
|
|
972
|
-
function cloneQueryParams(params) {
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
return cloneQueryParamsCompat(params);
|
|
990
|
+
export function cloneQueryParams(collectionName, params) {
|
|
991
|
+
warnIfCompatQueryParamsHaveUndefinedFields(collectionName, params);
|
|
992
|
+
return JSON.parse(JSON.stringify(params));
|
|
976
993
|
}
|
|
977
994
|
function parseQuerySignalOptions(options) {
|
|
978
995
|
if (!options || typeof options !== 'object') {
|
|
@@ -984,27 +1001,55 @@ function parseQuerySignalOptions(options) {
|
|
|
984
1001
|
const { root, ...signalOptions } = options;
|
|
985
1002
|
return { root, signalOptions };
|
|
986
1003
|
}
|
|
987
|
-
function normalizeQueryParamsForHash(params) {
|
|
1004
|
+
function normalizeQueryParamsForHash(collectionName, params) {
|
|
1005
|
+
warnIfCompatQueryParamsHaveUndefinedFields(collectionName, params);
|
|
1006
|
+
return params;
|
|
1007
|
+
}
|
|
1008
|
+
const warnedUndefinedQueryParamKeys = new Set();
|
|
1009
|
+
function warnIfCompatQueryParamsHaveUndefinedFields(collectionName, params) {
|
|
988
1010
|
if (!isCompatEnv())
|
|
989
|
-
return
|
|
990
|
-
|
|
1011
|
+
return;
|
|
1012
|
+
const paths = getUndefinedQueryParamFieldPaths(params);
|
|
1013
|
+
if (paths.length === 0)
|
|
1014
|
+
return;
|
|
1015
|
+
const key = `${collectionName || '<unknown>'}:${paths.join(',')}`;
|
|
1016
|
+
if (warnedUndefinedQueryParamKeys.has(key))
|
|
1017
|
+
return;
|
|
1018
|
+
warnedUndefinedQueryParamKeys.add(key);
|
|
1019
|
+
console.warn('[teamplay] Compat query params contain object fields with undefined values. ' +
|
|
1020
|
+
'TeamPlay now clones query params like non-compat mode, so these fields are dropped ' +
|
|
1021
|
+
'instead of being converted to null. Normalize query params explicitly.', {
|
|
1022
|
+
collectionName,
|
|
1023
|
+
paths
|
|
1024
|
+
}, new Error().stack);
|
|
1025
|
+
}
|
|
1026
|
+
function getUndefinedQueryParamFieldPaths(value) {
|
|
1027
|
+
const paths = [];
|
|
1028
|
+
collectUndefinedQueryParamFieldPaths(value, '', paths, new WeakSet());
|
|
1029
|
+
return paths;
|
|
991
1030
|
}
|
|
992
|
-
|
|
993
|
-
// instead of dropping them via JSON serialization.
|
|
994
|
-
function cloneQueryParamsCompat(value) {
|
|
995
|
-
if (value === undefined)
|
|
996
|
-
return null;
|
|
1031
|
+
function collectUndefinedQueryParamFieldPaths(value, path, paths, seen) {
|
|
997
1032
|
if (value == null || typeof value !== 'object')
|
|
998
|
-
return
|
|
999
|
-
if (
|
|
1000
|
-
return
|
|
1001
|
-
|
|
1033
|
+
return;
|
|
1034
|
+
if (seen.has(value))
|
|
1035
|
+
return;
|
|
1036
|
+
seen.add(value);
|
|
1037
|
+
if (Array.isArray(value)) {
|
|
1038
|
+
for (let i = 0; i < value.length; i++) {
|
|
1039
|
+
collectUndefinedQueryParamFieldPaths(value[i], `${path}[${i}]`, paths, seen);
|
|
1040
|
+
}
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1002
1043
|
for (const key in value) {
|
|
1003
|
-
if (Object.prototype.hasOwnProperty.call(value, key))
|
|
1004
|
-
|
|
1044
|
+
if (!Object.prototype.hasOwnProperty.call(value, key))
|
|
1045
|
+
continue;
|
|
1046
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
1047
|
+
if (value[key] === undefined) {
|
|
1048
|
+
paths.push(childPath);
|
|
1049
|
+
continue;
|
|
1005
1050
|
}
|
|
1051
|
+
collectUndefinedQueryParamFieldPaths(value[key], childPath, paths, seen);
|
|
1006
1052
|
}
|
|
1007
|
-
return object;
|
|
1008
1053
|
}
|
|
1009
1054
|
function createPendingDestroyEntry() {
|
|
1010
1055
|
let resolvePending;
|
package/dist/orm/Signal.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import SignalCompat from './Compat/SignalCompat.js';
|
|
2
2
|
import type { SignalConstructor } from './types/signal.js';
|
|
3
3
|
export type { FromJsonSchema, InferZodSchema, JsonSchema, JsonSchemaObject, ZodLikeSchema } from './types/jsonSchema.js';
|
|
4
|
-
export type { QueryParams } from './types/query.js';
|
|
4
|
+
export type { ComputedQueryParamsInput, QueryParams, QueryParamsInput } from './types/query.js';
|
|
5
5
|
export type { SignalArrayMutatorMethods, SignalArrayReaderMethods, SignalCollectionMethods, SignalMetadataMethods, SignalStringMutatorMethods, SignalValueMethods } from './types/baseMethods.js';
|
|
6
6
|
export type { AppendPath, JoinPath, PathSegment, SignalPath, WildcardPathSegment, WildcardSignalPath } from './types/path.js';
|
|
7
|
-
export type { AggregationSignal, AnySignal, ArraySignal, CollectionAggregationSignal, CollectionDocument, CollectionDocumentModel, CollectionQuerySignal, CollectionSignal, CollectionSignalFromSpec, CollectionSpec, DocumentSignal, JsonSchemaSpec, MaybePromise, MaybePromiseSubResult, PublicSignal, LocalSignalFactory, RegisteredAggregationInput, RuntimeSignalConstructor, RuntimeSignalInstance, QuerySignal, RootCollections, RootSignal, SignalBaseInstance, SignalChild, SignalChildren, SignalClass, SignalConstructor, SignalForKind, SignalKind, SignalInstance, SignalModelConstructor, SubResult, TypedAggregationInput, TypedAggregationSignal, TypedSignal, ZodSchemaSpec } from './types/signal.js';
|
|
8
|
-
export type { CollectionsFromManifest, ModelEntry, ModelManifest, PathModelsFromManifest } from './types/modelManifest.js';
|
|
7
|
+
export type { AggregationSignal, AnySignal, ArraySignal, CollectionAggregationSignal, CollectionDocument, CollectionDocumentModel, CollectionQuerySignal, CollectionSignal, CollectionSignalFromSpec, CollectionSpec, DocumentSignal, JsonSchemaSpec, MaybePromise, MaybePromiseSubResult, PublicSignal, LocalSignalFactory, RegisteredAggregationInput, RuntimeSignalConstructor, RuntimeSignalInstance, QuerySignal, RootCollections, RootSignal, SignalBaseInstance, SignalChild, SignalChildren, SignalClass, SignalConstructor, SignalForKind, SignalKind, SignalInstance, SignalModelConstructor, PrivateSignalFromSpec, RootPrivateCollections, SubResult, TypedAggregationInput, TypedAggregationSignal, TypedSignal, ZodSchemaSpec } from './types/signal.js';
|
|
8
|
+
export type { CollectionsFromManifest, ModelEntry, ModelManifest, PathModelsFromManifest, PrivateCollectionsFromManifest } from './types/modelManifest.js';
|
|
9
9
|
export { Signal, SEGMENTS, ARRAY_METHOD, GET, GETTERS, DEFAULT_GETTERS, regularBindings, extremelyLateBindings, isPublicCollectionSignal, isPublicDocumentSignal, isPublicCollection, isPrivateCollection } from './SignalBase.js';
|
|
10
10
|
export { SignalCompat };
|
|
11
11
|
declare const DefaultSignal: SignalConstructor;
|
package/dist/orm/SignalBase.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export declare class Signal<TValue = unknown> extends Function {
|
|
|
29
29
|
toString(): string;
|
|
30
30
|
/** Customize Object.prototype.toString.call($signal) for debugging. */
|
|
31
31
|
get [Symbol.toStringTag](): string;
|
|
32
|
+
/** Return the owning root signal. */
|
|
33
|
+
root(): this | import("./Root.js").RootSignalRuntime;
|
|
32
34
|
/**
|
|
33
35
|
* Return the parent signal `levels` above this signal.
|
|
34
36
|
* @param levels Number of parent levels to walk upward. Defaults to `1`.
|
|
@@ -51,11 +53,17 @@ export declare class Signal<TValue = unknown> extends Function {
|
|
|
51
53
|
/** Read the current value and track it for reactive rendering. */
|
|
52
54
|
get(): TValue;
|
|
53
55
|
/** Return document ids for a query or aggregation signal. */
|
|
54
|
-
getIds():
|
|
56
|
+
getIds(): string[];
|
|
57
|
+
/** Return query extra data, aggregation data, or undefined for ordinary signals. */
|
|
58
|
+
getExtra(): unknown;
|
|
59
|
+
/** Return a shallow copy of the current value. */
|
|
60
|
+
getCopy(): TValue;
|
|
61
|
+
/** Return a deep copy of the current value. */
|
|
62
|
+
getDeepCopy(): TValue;
|
|
55
63
|
/** Read the current value without tracking it for reactive rendering. */
|
|
56
64
|
peek(): TValue;
|
|
57
65
|
/** Return the document id represented by this document signal. */
|
|
58
|
-
getId(): string |
|
|
66
|
+
getId(): string | undefined;
|
|
59
67
|
/** Return the public collection name this signal belongs to. */
|
|
60
68
|
getCollection(): string;
|
|
61
69
|
/** Return association metadata registered on this signal's model class. */
|
|
@@ -98,6 +106,23 @@ export declare class Signal<TValue = unknown> extends Function {
|
|
|
98
106
|
* @param value New value to store at this signal path.
|
|
99
107
|
*/
|
|
100
108
|
set(value: TValue): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Replace this signal's value without deep-diffing object/array branches.
|
|
111
|
+
* @param value New value to store at this signal path.
|
|
112
|
+
*/
|
|
113
|
+
setReplace(value: TValue): Promise<void>;
|
|
114
|
+
/** Set the current value only when it is null or undefined. */
|
|
115
|
+
setNull(value: TValue): Promise<void>;
|
|
116
|
+
/** Replace the current value unless it is exactly equal to the new value. */
|
|
117
|
+
setDiff(value: TValue): Promise<void>;
|
|
118
|
+
/** Recursively diff objects and arrays at the current signal path. */
|
|
119
|
+
setDiffDeep(value: TValue): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Set multiple object fields with per-key replace semantics.
|
|
122
|
+
* Unlike assign(), null is stored as null and undefined follows setReplace() semantics.
|
|
123
|
+
* @param object Object containing fields to set.
|
|
124
|
+
*/
|
|
125
|
+
setEach(object: NonNullable<TValue> extends object ? Partial<NonNullable<TValue>> : never): Promise<void>;
|
|
101
126
|
/**
|
|
102
127
|
* Set multiple object fields at once. Fields set to `null` or `undefined` are deleted.
|
|
103
128
|
* @param value Object containing fields to set or delete.
|