jazz-tools 0.19.1 → 0.19.2

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 (58) hide show
  1. package/.turbo/turbo-build.log +48 -48
  2. package/CHANGELOG.md +11 -0
  3. package/dist/inspector/{custom-element-QESCMFY7.js → custom-element-ABVPHX53.js} +1118 -465
  4. package/dist/inspector/custom-element-ABVPHX53.js.map +1 -0
  5. package/dist/inspector/index.js +1090 -437
  6. package/dist/inspector/index.js.map +1 -1
  7. package/dist/inspector/register-custom-element.js +1 -1
  8. package/dist/inspector/tests/utils/history.test.d.ts +2 -0
  9. package/dist/inspector/tests/utils/history.test.d.ts.map +1 -0
  10. package/dist/inspector/tests/viewer/co-value-editor.test.d.ts +2 -0
  11. package/dist/inspector/tests/viewer/co-value-editor.test.d.ts.map +1 -0
  12. package/dist/inspector/tests/viewer/comap-view.test.d.ts +2 -0
  13. package/dist/inspector/tests/viewer/comap-view.test.d.ts.map +1 -0
  14. package/dist/inspector/ui/icon.d.ts +6 -0
  15. package/dist/inspector/ui/icon.d.ts.map +1 -1
  16. package/dist/inspector/ui/icons/add-icon.d.ts +2 -0
  17. package/dist/inspector/ui/icons/add-icon.d.ts.map +1 -0
  18. package/dist/inspector/ui/icons/edit-icon.d.ts +2 -0
  19. package/dist/inspector/ui/icons/edit-icon.d.ts.map +1 -0
  20. package/dist/inspector/ui/icons/history.d.ts +2 -0
  21. package/dist/inspector/ui/icons/history.d.ts.map +1 -0
  22. package/dist/inspector/utils/history.d.ts +3 -0
  23. package/dist/inspector/utils/history.d.ts.map +1 -0
  24. package/dist/inspector/utils/transactions-changes.d.ts +38 -0
  25. package/dist/inspector/utils/transactions-changes.d.ts.map +1 -0
  26. package/dist/inspector/viewer/co-map-view.d.ts +9 -0
  27. package/dist/inspector/viewer/co-map-view.d.ts.map +1 -0
  28. package/dist/inspector/viewer/co-value-editor.d.ts +10 -0
  29. package/dist/inspector/viewer/co-value-editor.d.ts.map +1 -0
  30. package/dist/inspector/viewer/grid-view.d.ts +3 -2
  31. package/dist/inspector/viewer/grid-view.d.ts.map +1 -1
  32. package/dist/inspector/viewer/history-view.d.ts.map +1 -1
  33. package/dist/inspector/viewer/page.d.ts.map +1 -1
  34. package/dist/tools/coValues/CoFieldInit.d.ts +2 -1
  35. package/dist/tools/coValues/CoFieldInit.d.ts.map +1 -1
  36. package/dist/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.d.ts +3 -2
  37. package/dist/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.d.ts.map +1 -1
  38. package/package.json +4 -4
  39. package/src/inspector/tests/utils/history.test.ts +401 -0
  40. package/src/inspector/tests/viewer/co-value-editor.test.tsx +903 -0
  41. package/src/inspector/tests/viewer/comap-view.test.tsx +581 -0
  42. package/src/inspector/ui/icon.tsx +6 -0
  43. package/src/inspector/ui/icons/add-icon.tsx +21 -0
  44. package/src/inspector/ui/icons/edit-icon.tsx +17 -0
  45. package/src/inspector/ui/icons/history.tsx +28 -0
  46. package/src/inspector/ui/modal.tsx +3 -3
  47. package/src/inspector/utils/history.ts +49 -0
  48. package/src/inspector/utils/transactions-changes.ts +98 -0
  49. package/src/inspector/viewer/co-map-view.tsx +312 -0
  50. package/src/inspector/viewer/co-value-editor.tsx +164 -0
  51. package/src/inspector/viewer/grid-view.tsx +139 -10
  52. package/src/inspector/viewer/history-view.tsx +16 -118
  53. package/src/inspector/viewer/page.tsx +13 -0
  54. package/src/react-core/tests/usePassPhraseAuth.test.ts +1 -1
  55. package/src/tools/coValues/CoFieldInit.ts +6 -3
  56. package/src/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.ts +12 -7
  57. package/src/tools/tests/coVector.test.ts +43 -0
  58. package/dist/inspector/custom-element-QESCMFY7.js.map +0 -1
@@ -1,27 +1,93 @@
1
1
  import { CoID, LocalNode, RawCoValue } from "cojson";
2
2
  import { JsonObject, JsonValue } from "cojson";
3
+ import { useState } from "react";
4
+ import { styled } from "goober";
3
5
  import { ResolveIcon } from "./type-icon.js";
4
6
  import { PageInfo, isCoId } from "./types.js";
5
7
  import { CoMapPreview, ValueRenderer } from "./value-renderer.js";
8
+ import { CoValueEditor } from "./co-value-editor.js";
6
9
 
7
10
  import { Badge } from "../ui/badge.js";
8
11
  import { Card, CardBody, CardHeader } from "../ui/card.js";
9
12
  import { Grid } from "../ui/grid.js";
13
+ import { Icon } from "../ui/icon.js";
10
14
  import { Text } from "../ui/text.js";
11
15
 
12
16
  function GridItem({
13
17
  entry,
14
18
  onNavigate,
15
19
  node,
20
+ coValue,
16
21
  }: {
17
22
  entry: [string, JsonValue | undefined];
18
23
  onNavigate: (pages: PageInfo[]) => void;
19
24
  node: LocalNode;
25
+ coValue?: RawCoValue;
20
26
  }) {
21
27
  const [key, value] = entry;
22
28
  const isCoValue = isCoId(value);
29
+ const [isEditing, setIsEditing] = useState(false);
23
30
 
24
- const props = isCoValue
31
+ const handleEditClick = (e: React.MouseEvent) => {
32
+ e.stopPropagation();
33
+ setIsEditing(true);
34
+ };
35
+
36
+ const handleCancel = () => {
37
+ setIsEditing(false);
38
+ };
39
+
40
+ const handleDelete = (e: React.MouseEvent) => {
41
+ e.stopPropagation();
42
+ if (confirm(`Are you sure you want to delete the property "${key}"?`)) {
43
+ coValue?.core.makeTransaction(
44
+ [
45
+ {
46
+ op: "del",
47
+ key,
48
+ },
49
+ ],
50
+ "private",
51
+ );
52
+ }
53
+ };
54
+
55
+ if (isEditing) {
56
+ return (
57
+ <Card
58
+ style={{
59
+ backgroundColor: "var(--j-foreground)",
60
+ borderColor: "var(--j-foreground)",
61
+ }}
62
+ >
63
+ <CardHeader>
64
+ <div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
65
+ {isCoValue ? (
66
+ <>
67
+ <Text strong>{key}</Text>
68
+ <Badge>
69
+ <ResolveIcon coId={value as CoID<RawCoValue>} node={node} />
70
+ </Badge>
71
+ </>
72
+ ) : (
73
+ <Text strong>{key}</Text>
74
+ )}
75
+ </div>
76
+ </CardHeader>
77
+ <CardBody style={{ wordBreak: "break-word" }}>
78
+ <CoValueEditor
79
+ node={node}
80
+ property={key}
81
+ value={value}
82
+ coValue={coValue!}
83
+ onCancel={handleCancel}
84
+ />
85
+ </CardBody>
86
+ </Card>
87
+ );
88
+ }
89
+
90
+ const cardProps = isCoValue
25
91
  ? {
26
92
  onClick: () =>
27
93
  onNavigate([{ coId: value as CoID<RawCoValue>, name: key }]),
@@ -35,17 +101,37 @@ function GridItem({
35
101
  };
36
102
 
37
103
  return (
38
- <Card {...props}>
104
+ <Card {...cardProps}>
39
105
  <CardHeader>
40
- {isCoValue ? (
41
- <>
106
+ <div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
107
+ {isCoValue ? (
108
+ <>
109
+ <Text strong>{key}</Text>
110
+ <Badge>
111
+ <ResolveIcon coId={value as CoID<RawCoValue>} node={node} />
112
+ </Badge>
113
+ </>
114
+ ) : (
42
115
  <Text strong>{key}</Text>
43
- <Badge>
44
- <ResolveIcon coId={value as CoID<RawCoValue>} node={node} />
45
- </Badge>
46
- </>
47
- ) : (
48
- <Text strong>{key}</Text>
116
+ )}
117
+ </div>
118
+ {coValue && (
119
+ <ActionButtons>
120
+ <EditButton
121
+ onClick={handleEditClick}
122
+ type="button"
123
+ aria-label="Edit"
124
+ >
125
+ <Icon name="edit" size="sm" />
126
+ </EditButton>
127
+ <DeleteButton
128
+ onClick={handleDelete}
129
+ type="button"
130
+ aria-label="Delete"
131
+ >
132
+ <Icon name="delete" size="sm" />
133
+ </DeleteButton>
134
+ </ActionButtons>
49
135
  )}
50
136
  </CardHeader>
51
137
  <CardBody style={{ wordBreak: "break-word" }}>
@@ -68,10 +154,12 @@ export function GridView({
68
154
  data,
69
155
  onNavigate,
70
156
  node,
157
+ coValue,
71
158
  }: {
72
159
  data: JsonObject;
73
160
  onNavigate: (pages: PageInfo[]) => void;
74
161
  node: LocalNode;
162
+ coValue?: RawCoValue;
75
163
  }) {
76
164
  const entries = Object.entries(data);
77
165
 
@@ -82,9 +170,50 @@ export function GridView({
82
170
  entry={entry}
83
171
  onNavigate={onNavigate}
84
172
  node={node}
173
+ coValue={coValue}
85
174
  key={childIndex}
86
175
  />
87
176
  ))}
88
177
  </Grid>
89
178
  );
90
179
  }
180
+
181
+ const EditButton = styled("button")`
182
+ display: inline-flex;
183
+ align-items: center;
184
+ justify-content: center;
185
+ padding: 0.25rem;
186
+ border: none;
187
+ background: transparent;
188
+ cursor: pointer;
189
+ color: var(--j-text-color);
190
+ border-radius: var(--j-radius-sm);
191
+ transition: background-color 0.2s;
192
+
193
+ &:hover {
194
+ background-color: var(--j-foreground);
195
+ }
196
+ `;
197
+
198
+ const DeleteButton = styled("button")`
199
+ display: inline-flex;
200
+ align-items: center;
201
+ justify-content: center;
202
+ padding: 0.25rem;
203
+ border: none;
204
+ background: transparent;
205
+ cursor: pointer;
206
+ color: var(--j-text-color);
207
+ border-radius: var(--j-radius-sm);
208
+ transition: background-color 0.2s;
209
+
210
+ &:hover {
211
+ background-color: var(--j-foreground);
212
+ }
213
+ `;
214
+
215
+ const ActionButtons = styled("div")`
216
+ display: flex;
217
+ align-items: center;
218
+ gap: 0.25rem;
219
+ `;
@@ -1,29 +1,11 @@
1
- import {
2
- AccountRole,
3
- BinaryStreamStart,
4
- CoID,
5
- JsonValue,
6
- LocalNode,
7
- OpID,
8
- RawCoValue,
9
- Role,
10
- } from "cojson";
1
+ import { CoID, JsonValue, LocalNode, OpID, RawCoValue } from "cojson";
11
2
  import { useMemo } from "react";
12
3
  import { styled } from "goober";
13
- import { isCoId } from "./types";
14
4
  import { AccountOrGroupText } from "./account-or-group-text";
15
5
  import { DataTable, ColumnDef } from "../ui/data-table";
16
- import { MapOpPayload } from "cojson/dist/coValues/coMap.js";
17
- import {
18
- DeletionOpPayload,
19
- InsertionOpPayload,
20
- } from "cojson/dist/coValues/coList.js";
21
- import {
22
- BinaryStreamChunk,
23
- BinaryStreamEnd,
24
- } from "cojson/dist/coValues/coStream.js";
25
- import { VerifiedTransaction } from "cojson/dist/coValueCore/coValueCore.js";
6
+ import type { VerifiedTransaction } from "cojson/dist/coValueCore/coValueCore.js";
26
7
  import { Icon, Accordion } from "../ui";
8
+ import * as TransactionChanges from "../utils/transactions-changes";
27
9
 
28
10
  type HistoryEntry = {
29
11
  id: string;
@@ -168,7 +150,7 @@ function mapTransactionToAction(
168
150
  coValue: RawCoValue,
169
151
  ): string {
170
152
  // Group changes
171
- if (isUserPromotion(change)) {
153
+ if (TransactionChanges.isUserPromotion(change)) {
172
154
  if (change.value === "revoked") {
173
155
  return `${change.key} has been revoked`;
174
156
  }
@@ -176,28 +158,28 @@ function mapTransactionToAction(
176
158
  return `${change.key} has been promoted to ${change.value}`;
177
159
  }
178
160
 
179
- if (isGroupExtension(change)) {
161
+ if (TransactionChanges.isGroupExtension(change)) {
180
162
  const child = change.key.slice(6);
181
163
  return `Group became a member of ${child}`;
182
164
  }
183
165
 
184
- if (isGroupExtendRevocation(change)) {
166
+ if (TransactionChanges.isGroupExtendRevocation(change)) {
185
167
  const child = change.key.slice(6);
186
168
  return `Group's membership of ${child} has been revoked.`;
187
169
  }
188
170
 
189
- if (isGroupPromotion(change)) {
171
+ if (TransactionChanges.isGroupPromotion(change)) {
190
172
  const parent = change.key.slice(7);
191
173
  return `Group ${parent} has been promoted to ${change.value}`;
192
174
  }
193
175
 
194
- if (isKeyRevelation(change)) {
176
+ if (TransactionChanges.isKeyRevelation(change)) {
195
177
  const [key, target] = change.key.split("_for_");
196
178
  return `Key "${key}" has been revealed to "${target}"`;
197
179
  }
198
180
 
199
181
  // coList changes
200
- if (isItemAppend(change)) {
182
+ if (TransactionChanges.isItemAppend(change)) {
201
183
  if (change.after === "start") {
202
184
  return `"${change.value}" has been appended`;
203
185
  }
@@ -211,7 +193,7 @@ function mapTransactionToAction(
211
193
  return `"${change.value}" has been inserted after "${(after as any).value}"`;
212
194
  }
213
195
 
214
- if (isItemPrepend(change)) {
196
+ if (TransactionChanges.isItemPrepend(change)) {
215
197
  if (change.before === "end") {
216
198
  return `"${change.value}" has been prepended`;
217
199
  }
@@ -225,7 +207,7 @@ function mapTransactionToAction(
225
207
  return `"${change.value}" has been inserted before "${(before as any).value}"`;
226
208
  }
227
209
 
228
- if (isItemDeletion(change)) {
210
+ if (TransactionChanges.isItemDeletion(change)) {
229
211
  const insertion = findListChange(change.insertion, coValue);
230
212
  if (insertion === undefined) {
231
213
  return `An undefined item has been deleted`;
@@ -235,24 +217,24 @@ function mapTransactionToAction(
235
217
  }
236
218
 
237
219
  // coStream changes
238
- if (isStreamStart(change)) {
220
+ if (TransactionChanges.isStreamStart(change)) {
239
221
  return `Stream started with mime type "${change.mimeType}" and file name "${change.fileName}"`;
240
222
  }
241
223
 
242
- if (isStreamChunk(change)) {
224
+ if (TransactionChanges.isStreamChunk(change)) {
243
225
  return `Stream chunk added`;
244
226
  }
245
227
 
246
- if (isStreamEnd(change)) {
228
+ if (TransactionChanges.isStreamEnd(change)) {
247
229
  return `Stream ended`;
248
230
  }
249
231
 
250
232
  // coMap changes
251
- if (isPropertySet(change)) {
233
+ if (TransactionChanges.isPropertySet(change)) {
252
234
  return `Property "${change.key}" has been set to ${JSON.stringify(change.value)}`;
253
235
  }
254
236
 
255
- if (isPropertyDeletion(change)) {
237
+ if (TransactionChanges.isPropertyDeletion(change)) {
256
238
  return `Property "${change.key}" has been deleted`;
257
239
  }
258
240
 
@@ -269,90 +251,6 @@ const findListChange = (
269
251
  )?.changes?.[opId.changeIdx];
270
252
  };
271
253
 
272
- const isGroupExtension = (
273
- change: any,
274
- ): change is Extract<
275
- MapOpPayload<`child_${string}`, "extend">,
276
- { op: "set" }
277
- > => {
278
- return change?.op === "set" && change?.value === "extend";
279
- };
280
-
281
- const isGroupExtendRevocation = (
282
- change: any,
283
- ): change is Extract<
284
- MapOpPayload<`child_${string}`, "revoked">,
285
- { op: "set" }
286
- > => {
287
- return change?.op === "set" && change?.value === "revoked";
288
- };
289
-
290
- const isGroupPromotion = (
291
- change: any,
292
- ): change is Extract<
293
- MapOpPayload<`parent_co_${string}`, AccountRole>,
294
- { op: "set" }
295
- > => {
296
- return change?.op === "set" && change?.key.startsWith("parent_co_");
297
- };
298
-
299
- const isUserPromotion = (
300
- change: any,
301
- ): change is Extract<MapOpPayload<CoID<RawCoValue>, Role>, { op: "set" }> => {
302
- return (
303
- change?.op === "set" && (isCoId(change?.key) || change?.key === "everyone")
304
- );
305
- };
306
-
307
- const isKeyRevelation = (
308
- change: any,
309
- ): change is Extract<
310
- MapOpPayload<`${string}_for_${string}`, string>,
311
- { op: "set" }
312
- > => {
313
- return change?.op === "set" && change?.key.includes("_for_");
314
- };
315
-
316
- const isPropertySet = (
317
- change: any,
318
- ): change is Extract<MapOpPayload<string, any>, { op: "set" }> => {
319
- return change?.op === "set" && "key" in change && "value" in change;
320
- };
321
- const isPropertyDeletion = (
322
- change: any,
323
- ): change is Extract<MapOpPayload<string, any>, { op: "del" }> => {
324
- return change?.op === "del" && "key" in change;
325
- };
326
-
327
- const isItemAppend = (
328
- change: any,
329
- ): change is Extract<InsertionOpPayload<any>, { op: "app" }> => {
330
- return change?.op === "app" && "after" in change && "value" in change;
331
- };
332
- const isItemPrepend = (
333
- change: any,
334
- ): change is Extract<InsertionOpPayload<any>, { op: "pre" }> => {
335
- return change?.op === "pre" && "before" in change && "value" in change;
336
- };
337
-
338
- const isItemDeletion = (
339
- change: any,
340
- ): change is Extract<DeletionOpPayload, { op: "del" }> => {
341
- return change?.op === "del" && "insertion" in change;
342
- };
343
-
344
- const isStreamStart = (change: any): change is BinaryStreamStart => {
345
- return change?.type === "start" && "mimeType" in change;
346
- };
347
-
348
- const isStreamChunk = (change: any): change is BinaryStreamChunk => {
349
- return change?.type === "chunk" && "chunk" in change;
350
- };
351
-
352
- const isStreamEnd = (change: any): change is BinaryStreamEnd => {
353
- return change?.type === "end";
354
- };
355
-
356
254
  const RedTooltip = styled("span")`
357
255
  position:relative; /* making the .tooltip span a container for the tooltip text */
358
256
  border-bottom:1px dashed #000; /* little indicater to indicate it's hoverable */
@@ -2,6 +2,7 @@ import {
2
2
  CoID,
3
3
  LocalNode,
4
4
  RawCoList,
5
+ RawCoMap,
5
6
  RawCoStream,
6
7
  RawCoValue,
7
8
  RawGroup,
@@ -23,6 +24,7 @@ import { TypeIcon } from "./type-icon.js";
23
24
  import { PageInfo } from "./types.js";
24
25
  import { resolveCoValue, useResolvedCoValue } from "./use-resolve-covalue.js";
25
26
  import { HistoryView } from "./history-view.js";
27
+ import { CoMapView } from "./co-map-view.js";
26
28
 
27
29
  interface PageContainerProps extends React.HTMLAttributes<HTMLDivElement> {
28
30
  isTopLevel?: boolean;
@@ -165,6 +167,17 @@ function View(
165
167
  return <TableView data={snapshot} node={node} onNavigate={onNavigate} />;
166
168
  }
167
169
 
170
+ if (type === "comap") {
171
+ return (
172
+ <CoMapView
173
+ coValue={value as RawCoMap}
174
+ data={snapshot}
175
+ node={node}
176
+ onNavigate={onNavigate}
177
+ />
178
+ );
179
+ }
180
+
168
181
  return <GridView data={snapshot} onNavigate={onNavigate} node={node} />;
169
182
  }
170
183
 
@@ -119,7 +119,7 @@ describe("usePassphraseAuth", () => {
119
119
  const me = useAccount();
120
120
  const logOut = useLogOut();
121
121
 
122
- if (me) {
122
+ if (me.$isLoaded) {
123
123
  if (!accounts.includes(me.$jazz.id)) {
124
124
  accounts.push(me.$jazz.id);
125
125
  }
@@ -3,6 +3,7 @@ import { CoList } from "./coList.js";
3
3
  import { CoMap, CoMapInit } from "./coMap.js";
4
4
  import { CoPlainText } from "./coPlainText.js";
5
5
  import { CoRichText } from "./coRichText.js";
6
+ import { CoVector } from "./coVector.js";
6
7
 
7
8
  /**
8
9
  * Returns the type of values that can be used to initialize a field of the provided type.
@@ -15,6 +16,8 @@ export type CoFieldInit<V> = V extends CoMap
15
16
  ? V | CoMapInit<V>
16
17
  : V extends CoList<infer T> | CoFeed<infer T>
17
18
  ? V | ReadonlyArray<CoFieldInit<T>>
18
- : V extends CoPlainText | CoRichText
19
- ? V | string
20
- : V;
19
+ : V extends CoVector | Readonly<CoVector>
20
+ ? V | ReadonlyArray<number> | Float32Array
21
+ : V extends CoPlainText | CoRichText
22
+ ? V | string
23
+ : V;
@@ -5,6 +5,7 @@ import {
5
5
  CoreCoListSchema,
6
6
  CoreCoMapSchema,
7
7
  CoreCoRecordSchema,
8
+ CoreCoVectorSchema,
8
9
  CorePlainTextSchema,
9
10
  Simplify,
10
11
  } from "../../../internal.js";
@@ -33,13 +34,15 @@ export type CoFieldSchemaInit<S extends CoValueClass | AnyZodOrCoValueSchema> =
33
34
  ? CoListSchemaInit<T>
34
35
  : S extends CoreCoFeedSchema<infer T>
35
36
  ? CoFeedSchemaInit<T>
36
- : S extends CorePlainTextSchema | CoreRichTextSchema
37
- ? string
38
- : S extends CoreCoOptionalSchema<infer T>
39
- ? CoFieldSchemaInit<T> | undefined
40
- : S extends CoDiscriminatedUnionSchema<infer Members>
41
- ? CoFieldSchemaInit<Members[number]>
42
- : never)
37
+ : S extends CoreCoVectorSchema
38
+ ? CoVectorSchemaInit
39
+ : S extends CorePlainTextSchema | CoreRichTextSchema
40
+ ? string
41
+ : S extends CoreCoOptionalSchema<infer T>
42
+ ? CoFieldSchemaInit<T> | undefined
43
+ : S extends CoDiscriminatedUnionSchema<infer Members>
44
+ ? CoFieldSchemaInit<Members[number]>
45
+ : never)
43
46
  : S extends z.core.$ZodType
44
47
  ? TypeOfZodSchema<S>
45
48
  : S extends CoValueClass
@@ -76,6 +79,8 @@ export type CoFeedSchemaInit<T extends AnyZodOrCoValueSchema> = Simplify<
76
79
  ReadonlyArray<CoFieldSchemaInit<T>>
77
80
  >;
78
81
 
82
+ export type CoVectorSchemaInit = ReadonlyArray<number> | Float32Array;
83
+
79
84
  /**
80
85
  * The convenience type for extracting the init type of a CoValue schema.
81
86
  */
@@ -112,6 +112,49 @@ describe("Creating a CoVector", async () => {
112
112
 
113
113
  expect(embedding.$jazz.owner).toEqual(group);
114
114
  });
115
+
116
+ describe("nested inside a container CoValue", async () => {
117
+ test("from an array of numbers", () => {
118
+ const VectorMap = co.map({
119
+ embedding: EmbeddingSchema,
120
+ });
121
+
122
+ const container = VectorMap.create({
123
+ embedding: [1, 2, 3],
124
+ });
125
+
126
+ expect(container.embedding).toBeInstanceOf(CoVector);
127
+ expect(Array.from(container.embedding)).toEqual([1, 2, 3]);
128
+ const vectorOwner = container.embedding.$jazz.owner;
129
+ expect(
130
+ vectorOwner.getParentGroups().map((group) => group.$jazz.id),
131
+ ).toContain(container.$jazz.owner.$jazz.id);
132
+
133
+ container.$jazz.set("embedding", [4, 5, 6]);
134
+ expect(Array.from(container.embedding)).toEqual([4, 5, 6]);
135
+ });
136
+
137
+ test("from a Float32Array", () => {
138
+ const VectorList = co.list(EmbeddingSchema);
139
+
140
+ const list = VectorList.create([new Float32Array([1, 2, 3])]);
141
+
142
+ const vector = list[0];
143
+ assert(vector);
144
+ expect(vector).toBeInstanceOf(CoVector);
145
+ expect(Array.from(vector)).toEqual([1, 2, 3]);
146
+ const vectorOwner = vector.$jazz.owner;
147
+ expect(
148
+ vectorOwner.getParentGroups().map((group) => group.$jazz.id),
149
+ ).toContain(list.$jazz.owner.$jazz.id);
150
+
151
+ list.$jazz.push(new Float32Array([4, 5, 6]));
152
+
153
+ const vector2 = list[1];
154
+ assert(vector2);
155
+ expect(Array.from(vector2)).toEqual([4, 5, 6]);
156
+ });
157
+ });
115
158
  });
116
159
 
117
160
  describe("CoVector structure", async () => {