jazz-tools 0.19.0 → 0.19.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.
Files changed (29) hide show
  1. package/.turbo/turbo-build.log +51 -51
  2. package/CHANGELOG.md +10 -0
  3. package/dist/{chunk-P3YLNFN4.js → chunk-NCNM6UDZ.js} +61 -22
  4. package/dist/chunk-NCNM6UDZ.js.map +1 -0
  5. package/dist/index.js +1 -1
  6. package/dist/testing.js +1 -1
  7. package/dist/tools/coValues/deepLoading.d.ts +8 -7
  8. package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
  9. package/dist/tools/coValues/interfaces.d.ts +3 -3
  10. package/dist/tools/coValues/interfaces.d.ts.map +1 -1
  11. package/dist/tools/coValues/schemaUnion.d.ts +6 -9
  12. package/dist/tools/coValues/schemaUnion.d.ts.map +1 -1
  13. package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts +18 -7
  14. package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
  15. package/dist/tools/implementation/zodSchema/unionUtils.d.ts.map +1 -1
  16. package/dist/tools/subscribe/SubscriptionScope.d.ts +1 -0
  17. package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
  18. package/package.json +4 -4
  19. package/src/tools/coValues/coList.ts +1 -1
  20. package/src/tools/coValues/deepLoading.ts +85 -71
  21. package/src/tools/coValues/interfaces.ts +3 -3
  22. package/src/tools/coValues/schemaUnion.ts +19 -14
  23. package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +69 -9
  24. package/src/tools/implementation/zodSchema/unionUtils.ts +35 -4
  25. package/src/tools/subscribe/SubscriptionScope.ts +3 -14
  26. package/src/tools/tests/coDiscriminatedUnion.test.ts +347 -5
  27. package/src/tools/tests/deepLoading.test.ts +55 -59
  28. package/src/tools/tests/schema.resolved.test.ts +70 -1
  29. package/dist/chunk-P3YLNFN4.js.map +0 -1
@@ -11,6 +11,8 @@ import {
11
11
  Group,
12
12
  ID,
13
13
  MaybeLoaded,
14
+ RefsToResolve,
15
+ RefsToResolveStrict,
14
16
  Resolved,
15
17
  Simplify,
16
18
  SubscribeListenerOptions,
@@ -150,18 +152,17 @@ export abstract class SchemaUnion extends CoValueBase implements CoValue {
150
152
  /**
151
153
  * Load a `SchemaUnion` with a given ID, as a given account.
152
154
  *
153
- * Note: The `resolve` option is not supported for `SchemaUnion`s due to https://github.com/garden-co/jazz/issues/2639
154
- *
155
155
  * @category Subscription & Loading
156
156
  */
157
- static load<M extends SchemaUnion>(
157
+ static load<M extends SchemaUnion, const R extends RefsToResolve<M> = true>(
158
158
  this: CoValueClass<M>,
159
159
  id: ID<M>,
160
160
  options?: {
161
+ resolve?: RefsToResolveStrict<M, R>;
161
162
  loadAs?: Account | AnonymousJazzAgent;
162
163
  skipRetry?: boolean;
163
164
  },
164
- ): Promise<MaybeLoaded<Resolved<M, true>>> {
165
+ ): Promise<MaybeLoaded<Resolved<M, R>>> {
165
166
  return loadCoValueWithoutMe(this, id, options);
166
167
  }
167
168
 
@@ -174,27 +175,31 @@ export abstract class SchemaUnion extends CoValueBase implements CoValue {
174
175
  *
175
176
  * Also see the `useCoState` hook to reactively subscribe to a CoValue in a React component.
176
177
  *
177
- * Note: The `resolve` option is not supported for `SchemaUnion`s due to https://github.com/garden-co/jazz/issues/2639
178
- *
179
178
  * @category Subscription & Loading
180
179
  */
181
- static subscribe<M extends SchemaUnion>(
180
+ static subscribe<
181
+ M extends SchemaUnion,
182
+ const R extends RefsToResolve<M> = true,
183
+ >(
182
184
  this: CoValueClass<M>,
183
185
  id: ID<M>,
184
- listener: (value: Resolved<M, true>, unsubscribe: () => void) => void,
186
+ listener: (value: Resolved<M, R>, unsubscribe: () => void) => void,
185
187
  ): () => void;
186
- static subscribe<M extends SchemaUnion>(
188
+ static subscribe<
189
+ M extends SchemaUnion,
190
+ const R extends RefsToResolve<M> = true,
191
+ >(
187
192
  this: CoValueClass<M>,
188
193
  id: ID<M>,
189
- options: SubscribeListenerOptions<M, true>,
190
- listener: (value: Resolved<M, true>, unsubscribe: () => void) => void,
194
+ options: SubscribeListenerOptions<M, R>,
195
+ listener: (value: Resolved<M, R>, unsubscribe: () => void) => void,
191
196
  ): () => void;
192
- static subscribe<M extends SchemaUnion>(
197
+ static subscribe<M extends SchemaUnion, const R extends RefsToResolve<M>>(
193
198
  this: CoValueClass<M>,
194
199
  id: ID<M>,
195
- ...args: SubscribeRestArgs<M, true>
200
+ ...args: SubscribeRestArgs<M, R>
196
201
  ): () => void {
197
202
  const { options, listener } = parseSubscribeRestArgs(args);
198
- return subscribeToCoValueWithoutMe<M, true>(this, id, options, listener);
203
+ return subscribeToCoValueWithoutMe<M, R>(this, id, options, listener);
199
204
  }
200
205
  }
@@ -6,6 +6,8 @@ import {
6
6
  InstanceOfSchema,
7
7
  InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded,
8
8
  MaybeLoaded,
9
+ RefsToResolve,
10
+ RefsToResolveStrict,
9
11
  Resolved,
10
12
  SchemaUnion,
11
13
  SchemaUnionConcreteSubclass,
@@ -14,7 +16,8 @@ import {
14
16
  } from "../../../internal.js";
15
17
  import { z } from "../zodReExport.js";
16
18
  import { CoOptionalSchema } from "./CoOptionalSchema.js";
17
- import { CoreCoValueSchema } from "./CoValueSchema.js";
19
+ import { CoreCoValueSchema, CoreResolveQuery } from "./CoValueSchema.js";
20
+ import { withSchemaResolveQuery } from "../../schemaUtils.js";
18
21
 
19
22
  export interface DiscriminableCoValueSchemaDefinition {
20
23
  discriminatorMap: z.core.$ZodDiscriminatedUnionInternals["propValues"];
@@ -44,12 +47,19 @@ export interface CoreCoDiscriminatedUnionSchema<
44
47
  }
45
48
  export class CoDiscriminatedUnionSchema<
46
49
  Options extends DiscriminableCoValueSchemas,
50
+ DefaultResolveQuery extends CoreResolveQuery = true,
47
51
  > implements CoreCoDiscriminatedUnionSchema<Options>
48
52
  {
49
53
  readonly collaborative = true as const;
50
54
  readonly builtin = "CoDiscriminatedUnion" as const;
51
55
  readonly getDefinition: () => CoDiscriminatedUnionSchemaDefinition<Options>;
52
- readonly resolveQuery = true as const;
56
+
57
+ /**
58
+ * Default resolve query to be used when loading instances of this schema.
59
+ * This resolve query will be used when no resolve query is provided to the load method.
60
+ * @default true
61
+ */
62
+ resolveQuery: DefaultResolveQuery = true as DefaultResolveQuery;
53
63
 
54
64
  constructor(
55
65
  coreSchema: CoreCoDiscriminatedUnionSchema<Options>,
@@ -60,9 +70,18 @@ export class CoDiscriminatedUnionSchema<
60
70
  this.getDefinition = coreSchema.getDefinition;
61
71
  }
62
72
 
63
- load(
73
+ load<
74
+ const R extends RefsToResolve<
75
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
76
+ // @ts-expect-error
77
+ > = DefaultResolveQuery,
78
+ >(
64
79
  id: string,
65
80
  options?: {
81
+ resolve?: RefsToResolveStrict<
82
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
83
+ R
84
+ >;
66
85
  loadAs?: Account | AnonymousJazzAgent;
67
86
  skipRetry?: boolean;
68
87
  unstable_branch?: BranchDefinition;
@@ -71,29 +90,42 @@ export class CoDiscriminatedUnionSchema<
71
90
  MaybeLoaded<
72
91
  Resolved<
73
92
  CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
74
- true
93
+ R
75
94
  >
76
95
  >
77
96
  > {
78
- return this.coValueClass.load(id, options) as any;
97
+ return this.coValueClass.load(
98
+ id,
99
+ // @ts-expect-error
100
+ withSchemaResolveQuery(options, this.resolveQuery),
101
+ ) as any;
79
102
  }
80
103
 
81
- subscribe(
104
+ subscribe<
105
+ const R extends RefsToResolve<
106
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
107
+ // @ts-expect-error
108
+ > = DefaultResolveQuery,
109
+ >(
82
110
  id: string,
83
111
  options: SubscribeListenerOptions<
84
112
  CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
85
- true
113
+ R
86
114
  >,
87
115
  listener: (
88
116
  value: Resolved<
89
117
  CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
90
- true
118
+ R
91
119
  >,
92
120
  unsubscribe: () => void,
93
121
  ) => void,
94
122
  ): () => void {
95
123
  // @ts-expect-error
96
- return this.coValueClass.subscribe(id, options, listener);
124
+ return this.coValueClass.subscribe(
125
+ id,
126
+ withSchemaResolveQuery(options, this.resolveQuery),
127
+ listener,
128
+ );
97
129
  }
98
130
 
99
131
  getCoValueClass(): SchemaUnionConcreteSubclass<
@@ -105,6 +137,34 @@ export class CoDiscriminatedUnionSchema<
105
137
  optional(): CoOptionalSchema<this> {
106
138
  return coOptionalDefiner(this);
107
139
  }
140
+
141
+ /**
142
+ * Adds a default resolve query to be used when loading instances of this schema.
143
+ * This resolve query will be used when no resolve query is provided to the load method.
144
+ */
145
+ resolved<
146
+ const R extends RefsToResolve<
147
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
148
+ > = true,
149
+ >(
150
+ resolveQuery: RefsToResolveStrict<
151
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
152
+ R
153
+ >,
154
+ ): CoDiscriminatedUnionSchema<Options, R> {
155
+ const definition = this.getDefinition();
156
+ const coreSchema: CoreCoDiscriminatedUnionSchema<Options> =
157
+ createCoreCoDiscriminatedUnionSchema(
158
+ definition.discriminator,
159
+ definition.options,
160
+ );
161
+ const copy = new CoDiscriminatedUnionSchema<Options, R>(
162
+ coreSchema,
163
+ this.coValueClass,
164
+ );
165
+ copy.resolveQuery = resolveQuery as R;
166
+ return copy;
167
+ }
108
168
  }
109
169
 
110
170
  export function createCoreCoDiscriminatedUnionSchema<
@@ -7,6 +7,7 @@ import {
7
7
  DiscriminableCoValueSchemas,
8
8
  DiscriminableCoreCoValueSchema,
9
9
  SchemaUnionDiscriminator,
10
+ coField,
10
11
  } from "../../internal.js";
11
12
  import {
12
13
  hydrateCoreCoValueSchema,
@@ -59,13 +60,23 @@ export function schemaUnionDiscriminatorFor(
59
60
  const determineSchema: SchemaUnionDiscriminator<CoMap> = (
60
61
  discriminable,
61
62
  ) => {
63
+ // collect all keys of nested CoValues
64
+ const allNestedRefKeys = new Set<string>();
65
+ for (const option of availableOptions) {
66
+ const coMapShape = (option as CoreCoMapSchema).getDefinition().shape;
67
+ for (const [key, value] of Object.entries(coMapShape)) {
68
+ if (isAnyCoValueSchema(value)) {
69
+ allNestedRefKeys.add(key);
70
+ }
71
+ }
72
+ }
73
+
62
74
  for (const option of availableOptions) {
63
75
  let match = true;
76
+ const optionDef = (option as CoreCoMapSchema).getDefinition();
64
77
 
65
78
  for (const key of Object.keys(discriminatorMap)) {
66
- const discriminatorDef = (option as CoreCoMapSchema).getDefinition()
67
- .shape[key];
68
-
79
+ const discriminatorDef = optionDef.shape[key];
69
80
  const discriminatorValue = discriminable.get(key);
70
81
 
71
82
  if (discriminatorValue && typeof discriminatorValue === "object") {
@@ -95,7 +106,27 @@ export function schemaUnionDiscriminatorFor(
95
106
 
96
107
  if (match) {
97
108
  const coValueSchema = hydrateCoreCoValueSchema(option as any);
98
- return coValueSchema.getCoValueClass() as typeof CoMap;
109
+ const coValueClass = coValueSchema.getCoValueClass() as typeof CoMap;
110
+
111
+ const dummyFieldNames = allNestedRefKeys
112
+ .keys()
113
+ .filter((key) => !optionDef.shape[key])
114
+ .toArray();
115
+
116
+ if (dummyFieldNames.length === 0) {
117
+ return coValueClass;
118
+ }
119
+
120
+ // inject dummy fields
121
+ return class extends coValueClass {
122
+ constructor(...args: ConstructorParameters<typeof coValueClass>) {
123
+ super(...args);
124
+
125
+ for (const key of dummyFieldNames) {
126
+ (this as any)[key] = coField.null;
127
+ }
128
+ }
129
+ };
99
130
  }
100
131
  }
101
132
 
@@ -49,6 +49,7 @@ export class SubscriptionScope<D extends CoValue> {
49
49
  autoloadedKeys = new Set<string>();
50
50
  skipInvalidKeys = new Set<string>();
51
51
  totalValidTransactions = 0;
52
+ version = 0;
52
53
  migrated = false;
53
54
  migrating = false;
54
55
  closed = false;
@@ -172,9 +173,7 @@ export class SubscriptionScope<D extends CoValue> {
172
173
  } else {
173
174
  const hasChanged =
174
175
  update.totalValidTransactions !== this.totalValidTransactions ||
175
- // Checking the identity of the raw value makes us cover the cases where the group
176
- // has been updated and the coValues that don't update the totalValidTransactions value (e.g. FileStream)
177
- this.value.value.$jazz.raw !== update;
176
+ update.version !== this.version;
178
177
 
179
178
  if (this.loadChildren()) {
180
179
  this.updateValue(createCoValue(this.schema, update, this));
@@ -184,6 +183,7 @@ export class SubscriptionScope<D extends CoValue> {
184
183
  }
185
184
 
186
185
  this.totalValidTransactions = update.totalValidTransactions;
186
+ this.version = update.version;
187
187
 
188
188
  this.silenceUpdates = false;
189
189
  this.triggerUpdate();
@@ -594,17 +594,6 @@ export class SubscriptionScope<D extends CoValue> {
594
594
  const descriptor = map.$jazz.getDescriptor(key);
595
595
 
596
596
  if (!descriptor) {
597
- this.childErrors.set(
598
- key,
599
- new JazzError(undefined, CoValueLoadingState.UNAVAILABLE, [
600
- {
601
- code: "validationError",
602
- message: `The ref ${key} requested on ${map.constructor.name} is not defined in the schema`,
603
- params: {},
604
- path: [key],
605
- },
606
- ]),
607
- );
608
597
  return undefined;
609
598
  }
610
599