jazz-tools 0.19.2 → 0.19.4
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/.svelte-kit/__package__/jazz.class.svelte.d.ts +2 -2
- package/.svelte-kit/__package__/jazz.class.svelte.d.ts.map +1 -1
- package/.svelte-kit/__package__/jazz.class.svelte.js +15 -17
- package/.turbo/turbo-build.log +54 -54
- package/CHANGELOG.md +24 -0
- package/dist/{chunk-NCNM6UDZ.js → chunk-PT7FCV26.js} +148 -78
- package/dist/chunk-PT7FCV26.js.map +1 -0
- package/dist/index.js +14 -7
- package/dist/index.js.map +1 -1
- package/dist/inspector/{custom-element-ABVPHX53.js → custom-element-P76EIWEV.js} +322 -146
- package/dist/inspector/custom-element-P76EIWEV.js.map +1 -0
- package/dist/inspector/index.js +302 -126
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/inspector/tests/viewer/co-plain-text-view.test.d.ts +2 -0
- package/dist/inspector/tests/viewer/co-plain-text-view.test.d.ts.map +1 -0
- package/dist/inspector/utils/history.d.ts +5 -1
- package/dist/inspector/utils/history.d.ts.map +1 -1
- package/dist/inspector/utils/permissions.d.ts +3 -0
- package/dist/inspector/utils/permissions.d.ts.map +1 -0
- package/dist/inspector/viewer/co-map-view.d.ts.map +1 -1
- package/dist/inspector/viewer/co-plain-text-view.d.ts +4 -2
- package/dist/inspector/viewer/co-plain-text-view.d.ts.map +1 -1
- package/dist/inspector/viewer/grid-view.d.ts.map +1 -1
- package/dist/inspector/viewer/page.d.ts.map +1 -1
- package/dist/inspector/viewer/use-resolve-covalue.d.ts +0 -1
- package/dist/inspector/viewer/use-resolve-covalue.d.ts.map +1 -1
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +4 -17
- package/dist/react-core/index.js.map +1 -1
- package/dist/svelte/jazz.class.svelte.d.ts +2 -2
- package/dist/svelte/jazz.class.svelte.d.ts.map +1 -1
- package/dist/svelte/jazz.class.svelte.js +15 -17
- package/dist/testing.js +1 -1
- package/dist/tools/coValues/coFeed.d.ts.map +1 -1
- package/dist/tools/coValues/group.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +7 -6
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/coValues/promise.d.ts +9 -0
- package/dist/tools/coValues/promise.d.ts.map +1 -0
- package/dist/tools/coValues/request.d.ts.map +1 -1
- package/dist/tools/exports.d.ts +1 -1
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/implementation/refs.d.ts +1 -1
- package/dist/tools/implementation/refs.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts +3 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/unionUtils.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts +5 -2
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/index.d.ts +1 -1
- package/dist/tools/subscribe/index.d.ts.map +1 -1
- package/dist/tools/subscribe/types.d.ts +2 -1
- package/dist/tools/subscribe/types.d.ts.map +1 -1
- package/dist/tools/tests/SubscriptionScope.test.d.ts +2 -0
- package/dist/tools/tests/SubscriptionScope.test.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/inspector/tests/utils/history.test.ts +233 -2
- package/src/inspector/tests/viewer/co-plain-text-view.test.tsx +125 -0
- package/src/inspector/tests/viewer/comap-view.test.tsx +309 -1
- package/src/inspector/tests/viewer/history-view.test.tsx +134 -2
- package/src/inspector/utils/history.ts +168 -1
- package/src/inspector/utils/permissions.ts +10 -0
- package/src/inspector/viewer/co-map-view.tsx +27 -15
- package/src/inspector/viewer/co-plain-text-view.tsx +102 -3
- package/src/inspector/viewer/grid-view.tsx +2 -1
- package/src/inspector/viewer/history-view.tsx +5 -23
- package/src/inspector/viewer/page.tsx +8 -1
- package/src/inspector/viewer/use-resolve-covalue.ts +2 -6
- package/src/react-core/hooks.ts +5 -29
- package/src/svelte/jazz.class.svelte.ts +16 -34
- package/src/tools/coValues/coFeed.ts +10 -7
- package/src/tools/coValues/coMap.ts +10 -7
- package/src/tools/coValues/group.ts +6 -2
- package/src/tools/coValues/interfaces.ts +48 -28
- package/src/tools/coValues/promise.ts +34 -0
- package/src/tools/coValues/request.ts +12 -8
- package/src/tools/exports.ts +1 -0
- package/src/tools/implementation/refs.ts +9 -17
- package/src/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.ts +62 -30
- package/src/tools/implementation/zodSchema/unionUtils.ts +3 -4
- package/src/tools/subscribe/SubscriptionScope.ts +45 -2
- package/src/tools/subscribe/index.ts +28 -13
- package/src/tools/subscribe/types.ts +5 -2
- package/src/tools/tests/SubscriptionScope.test.ts +397 -0
- package/src/tools/tests/deepLoading.test.ts +22 -0
- package/src/tools/tests/subscribe.test.ts +69 -0
- package/dist/chunk-NCNM6UDZ.js.map +0 -1
- package/dist/inspector/custom-element-ABVPHX53.js.map +0 -1
|
@@ -107,6 +107,23 @@ export function isCoValueClass<V extends CoValue>(
|
|
|
107
107
|
*/
|
|
108
108
|
export type ID<T> = string;
|
|
109
109
|
|
|
110
|
+
const unloadedCoValueStates = new Map<
|
|
111
|
+
NotLoadedCoValueState,
|
|
112
|
+
NotLoaded<CoValue>
|
|
113
|
+
>();
|
|
114
|
+
|
|
115
|
+
export function getUnloadedCoValueWithoutId<T extends CoValue>(
|
|
116
|
+
loadingState: NotLoadedCoValueState,
|
|
117
|
+
): NotLoaded<T> {
|
|
118
|
+
const value = unloadedCoValueStates.get(loadingState);
|
|
119
|
+
if (value) {
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
const newValue = createUnloadedCoValue("", loadingState);
|
|
123
|
+
unloadedCoValueStates.set(loadingState, newValue);
|
|
124
|
+
return newValue;
|
|
125
|
+
}
|
|
126
|
+
|
|
110
127
|
export function createUnloadedCoValue<T extends CoValue>(
|
|
111
128
|
id: ID<T>,
|
|
112
129
|
loadingState: NotLoadedCoValueState,
|
|
@@ -159,12 +176,8 @@ export function loadCoValue<
|
|
|
159
176
|
loadAs: options.loadAs,
|
|
160
177
|
syncResolution: true,
|
|
161
178
|
skipRetry: options.skipRetry,
|
|
162
|
-
onUnavailable:
|
|
163
|
-
|
|
164
|
-
},
|
|
165
|
-
onUnauthorized: () => {
|
|
166
|
-
resolve(createUnloadedCoValue(id, CoValueLoadingState.UNAUTHORIZED));
|
|
167
|
-
},
|
|
179
|
+
onUnavailable: resolve,
|
|
180
|
+
onUnauthorized: resolve,
|
|
168
181
|
unstable_branch: options.unstable_branch,
|
|
169
182
|
},
|
|
170
183
|
(value, unsubscribe) => {
|
|
@@ -215,8 +228,8 @@ export type SubscribeListenerOptions<
|
|
|
215
228
|
> = {
|
|
216
229
|
resolve?: RefsToResolveStrict<V, R>;
|
|
217
230
|
loadAs?: Account | AnonymousJazzAgent;
|
|
218
|
-
onUnauthorized?: () => void;
|
|
219
|
-
onUnavailable?: () => void;
|
|
231
|
+
onUnauthorized?: (value: NotLoaded<V>) => void;
|
|
232
|
+
onUnavailable?: (value: NotLoaded<V>) => void;
|
|
220
233
|
unstable_branch?: BranchDefinition;
|
|
221
234
|
};
|
|
222
235
|
|
|
@@ -290,8 +303,8 @@ export function subscribeToCoValue<
|
|
|
290
303
|
options: {
|
|
291
304
|
resolve?: RefsToResolveStrict<V, R>;
|
|
292
305
|
loadAs: Account | AnonymousJazzAgent;
|
|
293
|
-
onUnavailable?: () => void;
|
|
294
|
-
onUnauthorized?: () => void;
|
|
306
|
+
onUnavailable?: (value: NotLoaded<V>) => void;
|
|
307
|
+
onUnauthorized?: (value: NotLoaded<V>) => void;
|
|
295
308
|
syncResolution?: boolean;
|
|
296
309
|
skipRetry?: boolean;
|
|
297
310
|
unstable_branch?: BranchDefinition;
|
|
@@ -318,35 +331,42 @@ export function subscribeToCoValue<
|
|
|
318
331
|
options.unstable_branch,
|
|
319
332
|
);
|
|
320
333
|
|
|
321
|
-
const handleUpdate = (
|
|
334
|
+
const handleUpdate = () => {
|
|
322
335
|
if (unsubscribed) return;
|
|
323
336
|
|
|
324
|
-
|
|
325
|
-
options.onUnavailable?.();
|
|
337
|
+
const value = rootNode.getCurrentValue();
|
|
326
338
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
} else if (value.type === CoValueLoadingState.UNAUTHORIZED) {
|
|
332
|
-
options.onUnauthorized?.();
|
|
339
|
+
if (value.$isLoaded) {
|
|
340
|
+
listener(value as Resolved<V, R>, unsubscribe);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
333
343
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
344
|
+
switch (value.$jazz.loadingState) {
|
|
345
|
+
case CoValueLoadingState.UNAVAILABLE:
|
|
346
|
+
options.onUnavailable?.(value);
|
|
347
|
+
|
|
348
|
+
// Don't log unavailable errors when `loadUnique` or `upsertUnique` are used
|
|
349
|
+
if (!options.skipRetry) {
|
|
350
|
+
console.error(value.toString());
|
|
351
|
+
}
|
|
352
|
+
break;
|
|
353
|
+
case CoValueLoadingState.UNAUTHORIZED:
|
|
354
|
+
options.onUnauthorized?.(value);
|
|
355
|
+
console.error(value.toString());
|
|
356
|
+
break;
|
|
337
357
|
}
|
|
338
358
|
};
|
|
339
359
|
|
|
340
360
|
let shouldDefer = !options.syncResolution;
|
|
341
361
|
|
|
342
|
-
rootNode.setListener((
|
|
362
|
+
rootNode.setListener(() => {
|
|
343
363
|
if (shouldDefer) {
|
|
344
364
|
shouldDefer = false;
|
|
345
365
|
Promise.resolve().then(() => {
|
|
346
|
-
handleUpdate(
|
|
366
|
+
handleUpdate();
|
|
347
367
|
});
|
|
348
368
|
} else {
|
|
349
|
-
handleUpdate(
|
|
369
|
+
handleUpdate();
|
|
350
370
|
}
|
|
351
371
|
});
|
|
352
372
|
|
|
@@ -366,8 +386,8 @@ export function subscribeToExistingCoValue<
|
|
|
366
386
|
options:
|
|
367
387
|
| {
|
|
368
388
|
resolve?: RefsToResolveStrict<V, R>;
|
|
369
|
-
onUnavailable?: () => void;
|
|
370
|
-
onUnauthorized?: () => void;
|
|
389
|
+
onUnavailable?: (value: NotLoaded<V>) => void;
|
|
390
|
+
onUnauthorized?: (value: NotLoaded<V>) => void;
|
|
371
391
|
unstable_branch?: BranchDefinition;
|
|
372
392
|
}
|
|
373
393
|
| undefined,
|
|
@@ -703,7 +723,7 @@ function loadContentPiecesFromSubscription(
|
|
|
703
723
|
|
|
704
724
|
const currentValue = subscription.getCurrentValue();
|
|
705
725
|
|
|
706
|
-
if (
|
|
726
|
+
if (currentValue.$isLoaded) {
|
|
707
727
|
const core = currentValue.$jazz.raw.core as AvailableCoValueCore;
|
|
708
728
|
loadContentPiecesFromCoValue(core, valuesExported, contentPieces);
|
|
709
729
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class CoValuePromise<T> extends Promise<T> {
|
|
2
|
+
status: "pending" | "fulfilled" | "rejected" = "pending";
|
|
3
|
+
value: T | undefined;
|
|
4
|
+
reason: unknown | undefined;
|
|
5
|
+
|
|
6
|
+
static getRejected<T = never>(reason?: unknown): CoValuePromise<T> {
|
|
7
|
+
return new CoValuePromise<T>((resolve, reject) => {
|
|
8
|
+
reject(reason);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static getFulfilled<T>(value: T): CoValuePromise<T> {
|
|
13
|
+
return new CoValuePromise<T>((resolve) => {
|
|
14
|
+
resolve(value);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
executor: (
|
|
20
|
+
resolve: (value: T) => void,
|
|
21
|
+
reject: (reason?: unknown) => void,
|
|
22
|
+
) => void,
|
|
23
|
+
) {
|
|
24
|
+
super((resolve, reject) => {
|
|
25
|
+
const _resolve = (value: T) => {
|
|
26
|
+
resolve(value);
|
|
27
|
+
};
|
|
28
|
+
const _reject = (reason?: unknown) => {
|
|
29
|
+
reject(reason);
|
|
30
|
+
};
|
|
31
|
+
executor(_resolve, _reject);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -14,8 +14,6 @@ import {
|
|
|
14
14
|
CoMapSchemaInit,
|
|
15
15
|
CoValueClass,
|
|
16
16
|
CoreCoMapSchema,
|
|
17
|
-
CoValueLoadingState,
|
|
18
|
-
createUnloadedCoValue,
|
|
19
17
|
Group,
|
|
20
18
|
Loaded,
|
|
21
19
|
ResolveQuery,
|
|
@@ -377,9 +375,6 @@ export class HttpRoute<
|
|
|
377
375
|
const as = options?.owner ?? Account.getMe();
|
|
378
376
|
|
|
379
377
|
const target = await loadWorkerAccountOrGroup(this.workerId, as);
|
|
380
|
-
if (!target.$isLoaded) {
|
|
381
|
-
throw new JazzRequestError("Worker account not found", 400);
|
|
382
|
-
}
|
|
383
378
|
|
|
384
379
|
const response = await fetch(this.url, {
|
|
385
380
|
method: "POST",
|
|
@@ -621,20 +616,29 @@ async function loadWorkerAccountOrGroup(id: string, loadAs: Account) {
|
|
|
621
616
|
const coValue = await node.loadCoValueCore(id as `co_z${string}`);
|
|
622
617
|
|
|
623
618
|
if (!coValue.isAvailable()) {
|
|
624
|
-
|
|
619
|
+
throw new JazzRequestError("Worker account not found", 400);
|
|
625
620
|
}
|
|
626
621
|
|
|
627
622
|
const content = coValue.getCurrentContent();
|
|
628
623
|
|
|
629
624
|
if (content instanceof RawAccount) {
|
|
630
|
-
|
|
625
|
+
const account = await Account.load(content.id, {
|
|
631
626
|
loadAs,
|
|
632
627
|
});
|
|
628
|
+
if (!account.$isLoaded) {
|
|
629
|
+
throw new JazzRequestError("Worker account not found", 400);
|
|
630
|
+
}
|
|
631
|
+
return account;
|
|
633
632
|
}
|
|
634
633
|
|
|
635
|
-
|
|
634
|
+
const group = await Group.load(content.id, {
|
|
636
635
|
loadAs,
|
|
637
636
|
});
|
|
637
|
+
|
|
638
|
+
if (!group.$isLoaded) {
|
|
639
|
+
throw new JazzRequestError("Worker group not found", 400);
|
|
640
|
+
}
|
|
641
|
+
return group;
|
|
638
642
|
}
|
|
639
643
|
|
|
640
644
|
function defaultGetToken(request: Request) {
|
package/src/tools/exports.ts
CHANGED
|
@@ -53,29 +53,21 @@ export class Ref<out V extends CoValue> {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
if (!node) {
|
|
56
|
-
return createUnloadedCoValue(this.id, CoValueLoadingState.
|
|
56
|
+
return createUnloadedCoValue(this.id, CoValueLoadingState.UNAVAILABLE);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
const value = node.
|
|
59
|
+
const value = node.getCurrentValue();
|
|
60
60
|
|
|
61
|
-
if (value
|
|
62
|
-
return value
|
|
61
|
+
if (value.$isLoaded) {
|
|
62
|
+
return value as V;
|
|
63
63
|
} else {
|
|
64
64
|
return new Promise((resolve) => {
|
|
65
65
|
const unsubscribe = node.subscribe((value) => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
} else if (value?.type === CoValueLoadingState.UNAVAILABLE) {
|
|
70
|
-
unsubscribe();
|
|
71
|
-
resolve(
|
|
72
|
-
createUnloadedCoValue(this.id, CoValueLoadingState.UNAVAILABLE),
|
|
73
|
-
);
|
|
74
|
-
} else if (value?.type === CoValueLoadingState.UNAUTHORIZED) {
|
|
66
|
+
const currentValue = node.getCurrentValue();
|
|
67
|
+
|
|
68
|
+
if (currentValue.$jazz.loadingState !== CoValueLoadingState.LOADING) {
|
|
75
69
|
unsubscribe();
|
|
76
|
-
resolve(
|
|
77
|
-
createUnloadedCoValue(this.id, CoValueLoadingState.UNAUTHORIZED),
|
|
78
|
-
);
|
|
70
|
+
resolve(currentValue as V);
|
|
79
71
|
}
|
|
80
72
|
|
|
81
73
|
if (subscriptionScope.closed) {
|
|
@@ -86,7 +78,7 @@ export class Ref<out V extends CoValue> {
|
|
|
86
78
|
}
|
|
87
79
|
}
|
|
88
80
|
|
|
89
|
-
get value(): V
|
|
81
|
+
get value(): MaybeLoaded<V> {
|
|
90
82
|
return accessChildById(this.parent, this.id, this.schema);
|
|
91
83
|
}
|
|
92
84
|
}
|
|
@@ -60,16 +60,33 @@ function makeCodecCoField(
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
// CoFieldDefs are inherently type-unsafe. This type exists only for documentation purposes.
|
|
64
|
+
type CoFieldDef = any;
|
|
65
|
+
const schemaFieldCache = new WeakMap<SchemaField, CoFieldDef>();
|
|
66
|
+
|
|
67
|
+
function cacheSchemaField(schema: SchemaField, value: CoFieldDef): CoFieldDef {
|
|
68
|
+
schemaFieldCache.set(schema, value);
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function schemaFieldToCoFieldDef(schema: SchemaField): CoFieldDef {
|
|
73
|
+
const cachedCoFieldDef = schemaFieldCache.get(schema);
|
|
74
|
+
if (cachedCoFieldDef !== undefined) {
|
|
75
|
+
return cachedCoFieldDef;
|
|
76
|
+
}
|
|
77
|
+
|
|
64
78
|
if (isCoValueClass(schema)) {
|
|
65
|
-
return coField.ref(schema);
|
|
79
|
+
return cacheSchemaField(schema, coField.ref(schema));
|
|
66
80
|
} else if (isCoValueSchema(schema)) {
|
|
67
81
|
if (schema.builtin === "CoOptional") {
|
|
68
|
-
return
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
return cacheSchemaField(
|
|
83
|
+
schema,
|
|
84
|
+
coField.ref(schema.getCoValueClass(), {
|
|
85
|
+
optional: true,
|
|
86
|
+
}),
|
|
87
|
+
);
|
|
71
88
|
}
|
|
72
|
-
return coField.ref(schema.getCoValueClass());
|
|
89
|
+
return cacheSchemaField(schema, coField.ref(schema.getCoValueClass()));
|
|
73
90
|
} else {
|
|
74
91
|
if ("_zod" in schema) {
|
|
75
92
|
const zodSchemaDef = schema._zod.def;
|
|
@@ -90,29 +107,35 @@ export function schemaFieldToCoFieldDef(schema: SchemaField) {
|
|
|
90
107
|
// Primitive coField types support null and undefined as values,
|
|
91
108
|
// so we can just return the inner type here and rely on support
|
|
92
109
|
// for null/undefined at the type level
|
|
93
|
-
return coFieldDef;
|
|
110
|
+
return cacheSchemaField(schema, coFieldDef);
|
|
94
111
|
} else if (zodSchemaDef.type === "string") {
|
|
95
|
-
return coField.string;
|
|
112
|
+
return cacheSchemaField(schema, coField.string);
|
|
96
113
|
} else if (zodSchemaDef.type === "number") {
|
|
97
|
-
return coField.number;
|
|
114
|
+
return cacheSchemaField(schema, coField.number);
|
|
98
115
|
} else if (zodSchemaDef.type === "boolean") {
|
|
99
|
-
return coField.boolean;
|
|
116
|
+
return cacheSchemaField(schema, coField.boolean);
|
|
100
117
|
} else if (zodSchemaDef.type === "null") {
|
|
101
|
-
return coField.null;
|
|
118
|
+
return cacheSchemaField(schema, coField.null);
|
|
102
119
|
} else if (zodSchemaDef.type === "enum") {
|
|
103
|
-
return coField.string;
|
|
120
|
+
return cacheSchemaField(schema, coField.string);
|
|
104
121
|
} else if (zodSchemaDef.type === "readonly") {
|
|
105
|
-
return
|
|
106
|
-
|
|
122
|
+
return cacheSchemaField(
|
|
123
|
+
schema,
|
|
124
|
+
schemaFieldToCoFieldDef(
|
|
125
|
+
(schema as unknown as ZodReadonly).def.innerType as SchemaField,
|
|
126
|
+
),
|
|
107
127
|
);
|
|
108
128
|
} else if (zodSchemaDef.type === "date") {
|
|
109
|
-
return coField.optional.Date;
|
|
129
|
+
return cacheSchemaField(schema, coField.optional.Date);
|
|
110
130
|
} else if (zodSchemaDef.type === "template_literal") {
|
|
111
|
-
return coField.string;
|
|
131
|
+
return cacheSchemaField(schema, coField.string);
|
|
112
132
|
} else if (zodSchemaDef.type === "lazy") {
|
|
113
133
|
// Mostly to support z.json()
|
|
114
|
-
return
|
|
115
|
-
|
|
134
|
+
return cacheSchemaField(
|
|
135
|
+
schema,
|
|
136
|
+
schemaFieldToCoFieldDef(
|
|
137
|
+
(schema as unknown as ZodLazy).unwrap() as SchemaField,
|
|
138
|
+
),
|
|
116
139
|
);
|
|
117
140
|
} else if (
|
|
118
141
|
zodSchemaDef.type === "default" ||
|
|
@@ -122,9 +145,12 @@ export function schemaFieldToCoFieldDef(schema: SchemaField) {
|
|
|
122
145
|
"z.default()/z.catch() are not supported in collaborative schemas. They will be ignored.",
|
|
123
146
|
);
|
|
124
147
|
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
|
|
148
|
+
return cacheSchemaField(
|
|
149
|
+
schema,
|
|
150
|
+
schemaFieldToCoFieldDef(
|
|
151
|
+
(schema as unknown as ZodDefault | ZodCatch).def
|
|
152
|
+
.innerType as SchemaField,
|
|
153
|
+
),
|
|
128
154
|
);
|
|
129
155
|
} else if (zodSchemaDef.type === "literal") {
|
|
130
156
|
if (
|
|
@@ -140,11 +166,14 @@ export function schemaFieldToCoFieldDef(schema: SchemaField) {
|
|
|
140
166
|
) {
|
|
141
167
|
throw new Error("z.literal() with bigint is not supported");
|
|
142
168
|
}
|
|
143
|
-
return
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
169
|
+
return cacheSchemaField(
|
|
170
|
+
schema,
|
|
171
|
+
coField.literal(
|
|
172
|
+
...(zodSchemaDef.values as Exclude<
|
|
173
|
+
(typeof zodSchemaDef.values)[number],
|
|
174
|
+
undefined | null | bigint
|
|
175
|
+
>[]),
|
|
176
|
+
),
|
|
148
177
|
);
|
|
149
178
|
} else if (
|
|
150
179
|
zodSchemaDef.type === "object" ||
|
|
@@ -153,10 +182,10 @@ export function schemaFieldToCoFieldDef(schema: SchemaField) {
|
|
|
153
182
|
zodSchemaDef.type === "tuple" ||
|
|
154
183
|
zodSchemaDef.type === "intersection"
|
|
155
184
|
) {
|
|
156
|
-
return coField.json();
|
|
185
|
+
return cacheSchemaField(schema, coField.json());
|
|
157
186
|
} else if (zodSchemaDef.type === "union") {
|
|
158
187
|
if (isUnionOfPrimitivesDeeply(schema)) {
|
|
159
|
-
return coField.json();
|
|
188
|
+
return cacheSchemaField(schema, coField.json());
|
|
160
189
|
} else {
|
|
161
190
|
throw new Error(
|
|
162
191
|
"z.union()/z.discriminatedUnion() of collaborative types is not supported. Use co.discriminatedUnion() instead.",
|
|
@@ -183,8 +212,11 @@ export function schemaFieldToCoFieldDef(schema: SchemaField) {
|
|
|
183
212
|
throw error;
|
|
184
213
|
}
|
|
185
214
|
|
|
186
|
-
return
|
|
187
|
-
schema
|
|
215
|
+
return cacheSchemaField(
|
|
216
|
+
schema,
|
|
217
|
+
makeCodecCoField(
|
|
218
|
+
schema as z.core.$ZodCodec<z.core.$ZodType, z.core.$ZodType>,
|
|
219
|
+
),
|
|
188
220
|
);
|
|
189
221
|
} else {
|
|
190
222
|
throw new Error(
|
|
@@ -108,10 +108,9 @@ export function schemaUnionDiscriminatorFor(
|
|
|
108
108
|
const coValueSchema = hydrateCoreCoValueSchema(option as any);
|
|
109
109
|
const coValueClass = coValueSchema.getCoValueClass() as typeof CoMap;
|
|
110
110
|
|
|
111
|
-
const dummyFieldNames = allNestedRefKeys
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
.toArray();
|
|
111
|
+
const dummyFieldNames = Array.from(allNestedRefKeys).filter(
|
|
112
|
+
(key) => !optionDef.shape[key],
|
|
113
|
+
);
|
|
115
114
|
|
|
116
115
|
if (dummyFieldNames.length === 0) {
|
|
117
116
|
return coValueClass;
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type CoValue,
|
|
7
7
|
type ID,
|
|
8
8
|
MaybeLoaded,
|
|
9
|
+
NotLoaded,
|
|
9
10
|
type RefEncoded,
|
|
10
11
|
type RefsToResolve,
|
|
11
12
|
TypeSym,
|
|
@@ -283,7 +284,43 @@ export class SubscriptionScope<D extends CoValue> {
|
|
|
283
284
|
return this.pendingLoadedChildren.size === 0;
|
|
284
285
|
}
|
|
285
286
|
|
|
286
|
-
|
|
287
|
+
unloadedValue: NotLoaded<D> | undefined;
|
|
288
|
+
|
|
289
|
+
private getUnloadedValue(reason: NotLoadedCoValueState): NotLoaded<D> {
|
|
290
|
+
if (this.unloadedValue?.$jazz.loadingState === reason) {
|
|
291
|
+
return this.unloadedValue;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const unloadedValue: NotLoaded<D> = {
|
|
295
|
+
$jazz: {
|
|
296
|
+
id: this.id,
|
|
297
|
+
loadingState: reason,
|
|
298
|
+
// @ts-expect-error - This is a private property
|
|
299
|
+
_subscriptionScope: this,
|
|
300
|
+
},
|
|
301
|
+
$isLoaded: false,
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
this.unloadedValue = unloadedValue;
|
|
305
|
+
|
|
306
|
+
return unloadedValue;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
getCurrentValue(): MaybeLoaded<D> {
|
|
310
|
+
const rawValue = this.getCurrentRawValue();
|
|
311
|
+
|
|
312
|
+
if (
|
|
313
|
+
rawValue === CoValueLoadingState.UNAUTHORIZED ||
|
|
314
|
+
rawValue === CoValueLoadingState.UNAVAILABLE ||
|
|
315
|
+
rawValue === CoValueLoadingState.LOADING
|
|
316
|
+
) {
|
|
317
|
+
return this.getUnloadedValue(rawValue);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return rawValue;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
getCurrentRawValue(): D | NotLoadedCoValueState {
|
|
287
324
|
if (
|
|
288
325
|
this.value.type === CoValueLoadingState.UNAUTHORIZED ||
|
|
289
326
|
this.value.type === CoValueLoadingState.UNAVAILABLE
|
|
@@ -406,7 +443,7 @@ export class SubscriptionScope<D extends CoValue> {
|
|
|
406
443
|
this.subscription.pullValue();
|
|
407
444
|
|
|
408
445
|
// Check if the value is now available
|
|
409
|
-
const value = this.
|
|
446
|
+
const value = this.getCurrentRawValue();
|
|
410
447
|
|
|
411
448
|
// If the value is available, trigger the listener
|
|
412
449
|
if (typeof value !== "string") {
|
|
@@ -590,6 +627,12 @@ export class SubscriptionScope<D extends CoValue> {
|
|
|
590
627
|
return undefined;
|
|
591
628
|
}
|
|
592
629
|
|
|
630
|
+
// Check if $onError: "catch" is specified for this key
|
|
631
|
+
const skipInvalid = typeof depth === "object" && depth.$onError === "catch";
|
|
632
|
+
if (skipInvalid) {
|
|
633
|
+
this.skipInvalidKeys.add(key);
|
|
634
|
+
}
|
|
635
|
+
|
|
593
636
|
const id = map.$jazz.raw.get(key) as string | undefined;
|
|
594
637
|
const descriptor = map.$jazz.getDescriptor(key);
|
|
595
638
|
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
CoValue,
|
|
3
|
+
CoValueClass,
|
|
4
|
+
MaybeLoaded,
|
|
5
|
+
RefEncoded,
|
|
6
|
+
} from "../internal.js";
|
|
2
7
|
import { createUnloadedCoValue } from "../internal.js";
|
|
3
8
|
import { SubscriptionScope } from "./SubscriptionScope.js";
|
|
4
9
|
import { CoValueLoadingState } from "./types.js";
|
|
@@ -56,16 +61,22 @@ export function accessChildByKey<D extends CoValue>(
|
|
|
56
61
|
);
|
|
57
62
|
}
|
|
58
63
|
|
|
64
|
+
// TODO: this doesn't check the subscription tree loading state
|
|
65
|
+
// so if one of the children is loading, it will return the loading state
|
|
66
|
+
// instead of the latest loaded state
|
|
59
67
|
const value = subscriptionScope.childValues.get(childId);
|
|
60
68
|
|
|
61
69
|
if (value?.type === CoValueLoadingState.LOADED) {
|
|
62
70
|
return value.value;
|
|
63
|
-
} else {
|
|
64
|
-
return createUnloadedCoValue(
|
|
65
|
-
childId,
|
|
66
|
-
value?.type ?? CoValueLoadingState.LOADING,
|
|
67
|
-
);
|
|
68
71
|
}
|
|
72
|
+
|
|
73
|
+
const childNode = subscriptionScope.childNodes.get(childId);
|
|
74
|
+
|
|
75
|
+
if (!childNode) {
|
|
76
|
+
return createUnloadedCoValue(childId, CoValueLoadingState.UNAVAILABLE);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return childNode.getCurrentValue();
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
/**
|
|
@@ -77,9 +88,9 @@ export function accessChildByKey<D extends CoValue>(
|
|
|
77
88
|
* Used for refs that never change (e.g. CoFeed entries, CoMap edits)
|
|
78
89
|
*/
|
|
79
90
|
export function accessChildById<D extends CoValue>(
|
|
80
|
-
parent:
|
|
91
|
+
parent: CoValue,
|
|
81
92
|
childId: string,
|
|
82
|
-
schema: RefEncoded<
|
|
93
|
+
schema: RefEncoded<D>,
|
|
83
94
|
) {
|
|
84
95
|
const subscriptionScope = getSubscriptionScope(parent);
|
|
85
96
|
|
|
@@ -87,12 +98,16 @@ export function accessChildById<D extends CoValue>(
|
|
|
87
98
|
|
|
88
99
|
const value = subscriptionScope.childValues.get(childId);
|
|
89
100
|
|
|
101
|
+
// TODO: this doesn't check the subscription tree loading state
|
|
90
102
|
if (value?.type === CoValueLoadingState.LOADED) {
|
|
91
103
|
return value.value;
|
|
92
|
-
} else {
|
|
93
|
-
return createUnloadedCoValue(
|
|
94
|
-
childId,
|
|
95
|
-
value?.type ?? CoValueLoadingState.LOADING,
|
|
96
|
-
);
|
|
97
104
|
}
|
|
105
|
+
|
|
106
|
+
const childNode = subscriptionScope.childNodes.get(childId);
|
|
107
|
+
|
|
108
|
+
if (!childNode) {
|
|
109
|
+
return createUnloadedCoValue<D>(childId, CoValueLoadingState.UNAVAILABLE);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return childNode.getCurrentValue() as MaybeLoaded<D>;
|
|
98
113
|
}
|
|
@@ -29,10 +29,13 @@ export const CoValueLoadingState = {
|
|
|
29
29
|
export type CoValueLoadingState =
|
|
30
30
|
(typeof CoValueLoadingState)[keyof typeof CoValueLoadingState];
|
|
31
31
|
|
|
32
|
+
export type CoValueErrorState =
|
|
33
|
+
| typeof CoValueLoadingState.UNAVAILABLE
|
|
34
|
+
| typeof CoValueLoadingState.UNAUTHORIZED;
|
|
35
|
+
|
|
32
36
|
export type NotLoadedCoValueState =
|
|
33
37
|
| typeof CoValueLoadingState.LOADING
|
|
34
|
-
|
|
|
35
|
-
| typeof CoValueLoadingState.UNAVAILABLE;
|
|
38
|
+
| CoValueErrorState;
|
|
36
39
|
|
|
37
40
|
export type SubscriptionValue<D extends CoValue, R extends RefsToResolve<D>> =
|
|
38
41
|
| {
|