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.
- package/.turbo/turbo-build.log +48 -48
- package/CHANGELOG.md +11 -0
- package/dist/inspector/{custom-element-QESCMFY7.js → custom-element-ABVPHX53.js} +1118 -465
- package/dist/inspector/custom-element-ABVPHX53.js.map +1 -0
- package/dist/inspector/index.js +1090 -437
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/inspector/tests/utils/history.test.d.ts +2 -0
- package/dist/inspector/tests/utils/history.test.d.ts.map +1 -0
- package/dist/inspector/tests/viewer/co-value-editor.test.d.ts +2 -0
- package/dist/inspector/tests/viewer/co-value-editor.test.d.ts.map +1 -0
- package/dist/inspector/tests/viewer/comap-view.test.d.ts +2 -0
- package/dist/inspector/tests/viewer/comap-view.test.d.ts.map +1 -0
- package/dist/inspector/ui/icon.d.ts +6 -0
- package/dist/inspector/ui/icon.d.ts.map +1 -1
- package/dist/inspector/ui/icons/add-icon.d.ts +2 -0
- package/dist/inspector/ui/icons/add-icon.d.ts.map +1 -0
- package/dist/inspector/ui/icons/edit-icon.d.ts +2 -0
- package/dist/inspector/ui/icons/edit-icon.d.ts.map +1 -0
- package/dist/inspector/ui/icons/history.d.ts +2 -0
- package/dist/inspector/ui/icons/history.d.ts.map +1 -0
- package/dist/inspector/utils/history.d.ts +3 -0
- package/dist/inspector/utils/history.d.ts.map +1 -0
- package/dist/inspector/utils/transactions-changes.d.ts +38 -0
- package/dist/inspector/utils/transactions-changes.d.ts.map +1 -0
- package/dist/inspector/viewer/co-map-view.d.ts +9 -0
- package/dist/inspector/viewer/co-map-view.d.ts.map +1 -0
- package/dist/inspector/viewer/co-value-editor.d.ts +10 -0
- package/dist/inspector/viewer/co-value-editor.d.ts.map +1 -0
- package/dist/inspector/viewer/grid-view.d.ts +3 -2
- package/dist/inspector/viewer/grid-view.d.ts.map +1 -1
- package/dist/inspector/viewer/history-view.d.ts.map +1 -1
- package/dist/inspector/viewer/page.d.ts.map +1 -1
- package/dist/tools/coValues/CoFieldInit.d.ts +2 -1
- package/dist/tools/coValues/CoFieldInit.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/inspector/tests/utils/history.test.ts +401 -0
- package/src/inspector/tests/viewer/co-value-editor.test.tsx +903 -0
- package/src/inspector/tests/viewer/comap-view.test.tsx +581 -0
- package/src/inspector/ui/icon.tsx +6 -0
- package/src/inspector/ui/icons/add-icon.tsx +21 -0
- package/src/inspector/ui/icons/edit-icon.tsx +17 -0
- package/src/inspector/ui/icons/history.tsx +28 -0
- package/src/inspector/ui/modal.tsx +3 -3
- package/src/inspector/utils/history.ts +49 -0
- package/src/inspector/utils/transactions-changes.ts +98 -0
- package/src/inspector/viewer/co-map-view.tsx +312 -0
- package/src/inspector/viewer/co-value-editor.tsx +164 -0
- package/src/inspector/viewer/grid-view.tsx +139 -10
- package/src/inspector/viewer/history-view.tsx +16 -118
- package/src/inspector/viewer/page.tsx +13 -0
- package/src/react-core/tests/usePassPhraseAuth.test.ts +1 -1
- package/src/tools/coValues/CoFieldInit.ts +6 -3
- package/src/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.ts +12 -7
- package/src/tools/tests/coVector.test.ts +43 -0
- 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
|
|
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 {...
|
|
104
|
+
<Card {...cardProps}>
|
|
39
105
|
<CardHeader>
|
|
40
|
-
{
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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 {
|
|
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
|
|
|
@@ -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
|
|
19
|
-
? V |
|
|
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
|
|
37
|
-
?
|
|
38
|
-
: S extends
|
|
39
|
-
?
|
|
40
|
-
: S extends
|
|
41
|
-
? CoFieldSchemaInit<
|
|
42
|
-
:
|
|
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 () => {
|