jazz-tools 0.18.31 → 0.18.33
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__/media/image.svelte +1 -1
- package/.svelte-kit/__package__/tests/media/image.svelte.test.js +1 -1
- package/.turbo/turbo-build.log +58 -58
- package/CHANGELOG.md +23 -0
- package/dist/{chunk-6BIYT3KH.js → chunk-OSQ7S47Q.js} +3 -3
- package/dist/chunk-OSQ7S47Q.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/inspector/{custom-element-RQTLPAPJ.js → custom-element-RBBL46TI.js} +636 -193
- package/dist/inspector/custom-element-RBBL46TI.js.map +1 -0
- package/dist/inspector/index.js +626 -183
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/inspector/tests/ui/data-table.test.d.ts +2 -0
- package/dist/inspector/tests/ui/data-table.test.d.ts.map +1 -0
- package/dist/inspector/tests/viewer/history-view.test.d.ts +2 -0
- package/dist/inspector/tests/viewer/history-view.test.d.ts.map +1 -0
- package/dist/inspector/ui/data-table.d.ts +23 -0
- package/dist/inspector/ui/data-table.d.ts.map +1 -0
- package/dist/inspector/ui/index.d.ts +1 -0
- package/dist/inspector/ui/index.d.ts.map +1 -1
- package/dist/inspector/viewer/history-view.d.ts +6 -0
- package/dist/inspector/viewer/history-view.d.ts.map +1 -0
- package/dist/inspector/viewer/page.d.ts.map +1 -1
- package/dist/svelte/media/image.svelte +1 -1
- package/dist/svelte/tests/media/image.svelte.test.js +1 -1
- package/dist/testing.js +1 -1
- package/dist/tools/coValues/coFeed.d.ts +1 -1
- package/dist/tools/coValues/coFeed.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
- package/dist/worker/index.d.ts +2 -1
- package/dist/worker/index.d.ts.map +1 -1
- package/dist/worker/index.js +2 -1
- package/dist/worker/index.js.map +1 -1
- package/package.json +4 -4
- package/src/inspector/tests/ui/data-table.test.tsx +296 -0
- package/src/inspector/tests/viewer/history-view.test.tsx +246 -0
- package/src/inspector/ui/data-table.tsx +265 -0
- package/src/inspector/ui/index.ts +1 -0
- package/src/inspector/viewer/history-view.tsx +379 -0
- package/src/inspector/viewer/page.tsx +2 -0
- package/src/media/create-image-factory.test.ts +2 -2
- package/src/svelte/media/image.svelte +1 -1
- package/src/svelte/tests/media/image.svelte.test.ts +1 -1
- package/src/tools/coValues/coFeed.ts +2 -2
- package/src/tools/coValues/interfaces.ts +1 -1
- package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +1 -1
- package/src/tools/tests/CoValueCoreSubscription.test.ts +1 -1
- package/src/tools/tests/coFeed.test.ts +1 -1
- package/src/tools/tests/load.test.ts +1 -1
- package/src/worker/index.ts +9 -1
- package/dist/chunk-6BIYT3KH.js.map +0 -1
- package/dist/inspector/custom-element-RQTLPAPJ.js.map +0 -1
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountRole,
|
|
3
|
+
BinaryStreamStart,
|
|
4
|
+
CoID,
|
|
5
|
+
JsonValue,
|
|
6
|
+
LocalNode,
|
|
7
|
+
OpID,
|
|
8
|
+
RawCoValue,
|
|
9
|
+
Role,
|
|
10
|
+
} from "cojson";
|
|
11
|
+
import { useMemo } from "react";
|
|
12
|
+
import { styled } from "goober";
|
|
13
|
+
import { isCoId } from "./types";
|
|
14
|
+
import { AccountOrGroupText } from "./account-or-group-text";
|
|
15
|
+
import { DataTable, ColumnDef } from "../ui/data-table";
|
|
16
|
+
import { Heading } from "../ui/heading";
|
|
17
|
+
import { MapOpPayload } from "cojson/dist/coValues/coMap.js";
|
|
18
|
+
import {
|
|
19
|
+
DeletionOpPayload,
|
|
20
|
+
InsertionOpPayload,
|
|
21
|
+
} from "cojson/dist/coValues/coList.js";
|
|
22
|
+
import {
|
|
23
|
+
BinaryStreamChunk,
|
|
24
|
+
BinaryStreamEnd,
|
|
25
|
+
} from "cojson/dist/coValues/coStream.js";
|
|
26
|
+
import { VerifiedTransaction } from "cojson/dist/coValueCore/coValueCore.js";
|
|
27
|
+
import { Icon } from "../ui";
|
|
28
|
+
|
|
29
|
+
type HistoryEntry = {
|
|
30
|
+
id: string;
|
|
31
|
+
author: string;
|
|
32
|
+
action: string;
|
|
33
|
+
timestamp: Date;
|
|
34
|
+
isValid: boolean;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export function HistoryView({
|
|
38
|
+
coValue,
|
|
39
|
+
node,
|
|
40
|
+
}: {
|
|
41
|
+
coValue: RawCoValue;
|
|
42
|
+
node: LocalNode;
|
|
43
|
+
}) {
|
|
44
|
+
const transactions = useMemo(
|
|
45
|
+
() => getHistory(coValue),
|
|
46
|
+
[coValue.core.verifiedTransactions.length],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const columns: ColumnDef<HistoryEntry>[] = [
|
|
50
|
+
{
|
|
51
|
+
id: "author",
|
|
52
|
+
header: "Author",
|
|
53
|
+
accessor: (row) => (
|
|
54
|
+
<>
|
|
55
|
+
{row.isValid || (
|
|
56
|
+
<RedTooltip data-text="This transaction is invalid and is not used">
|
|
57
|
+
<Icon
|
|
58
|
+
name="caution"
|
|
59
|
+
size="xs"
|
|
60
|
+
color="red"
|
|
61
|
+
style={{
|
|
62
|
+
display: "inline-block",
|
|
63
|
+
verticalAlign: "middle",
|
|
64
|
+
marginRight: "0.25rem",
|
|
65
|
+
}}
|
|
66
|
+
/>
|
|
67
|
+
</RedTooltip>
|
|
68
|
+
)}
|
|
69
|
+
{row.author.startsWith("co_") ? (
|
|
70
|
+
<AccountOrGroupText
|
|
71
|
+
coId={row.author as CoID<RawCoValue>}
|
|
72
|
+
node={node}
|
|
73
|
+
showId
|
|
74
|
+
/>
|
|
75
|
+
) : (
|
|
76
|
+
row.author
|
|
77
|
+
)}
|
|
78
|
+
</>
|
|
79
|
+
),
|
|
80
|
+
sortable: false,
|
|
81
|
+
filterable: true,
|
|
82
|
+
sortFn: (a, b) => a.author.localeCompare(b.author),
|
|
83
|
+
filterFn: (row, filterValue) =>
|
|
84
|
+
row.author.toLowerCase().includes(filterValue.toLowerCase()),
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "action",
|
|
88
|
+
header: "Action",
|
|
89
|
+
accessor: (row) => row.action,
|
|
90
|
+
sortable: false,
|
|
91
|
+
filterable: true,
|
|
92
|
+
sortFn: (a, b) => a.action.localeCompare(b.action),
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "timestamp",
|
|
96
|
+
header: "Timestamp",
|
|
97
|
+
accessor: (row) => row.timestamp.toISOString(),
|
|
98
|
+
sortable: true,
|
|
99
|
+
filterable: true,
|
|
100
|
+
sortFn: (a, b) => a.timestamp.getTime() - b.timestamp.getTime(),
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<section style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
106
|
+
<Heading>CoValue history</Heading>
|
|
107
|
+
<DataTable
|
|
108
|
+
columns={columns}
|
|
109
|
+
data={transactions}
|
|
110
|
+
pageSize={10}
|
|
111
|
+
initialSort={{ columnId: "timestamp", direction: "desc" }}
|
|
112
|
+
getRowKey={(row) => row.id}
|
|
113
|
+
emptyMessage="No history available"
|
|
114
|
+
/>
|
|
115
|
+
</section>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getTransactionChanges(
|
|
120
|
+
tx: VerifiedTransaction,
|
|
121
|
+
coValue: RawCoValue,
|
|
122
|
+
): JsonValue[] {
|
|
123
|
+
if (tx.isValid === false && tx.tx.privacy === "private") {
|
|
124
|
+
const readKey = coValue.core.getReadKey(tx.tx.keyUsed);
|
|
125
|
+
if (!readKey) {
|
|
126
|
+
throw new Error("Read key not found");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
coValue.core.verified.decryptTransaction(
|
|
131
|
+
tx.txID.sessionID,
|
|
132
|
+
tx.txID.txIndex,
|
|
133
|
+
readKey,
|
|
134
|
+
) ?? []
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
// const decryptedString = coValue.core.verified.sessions.get(tx.txID.sessionID)?.impl.decryptNextTransactionChangesJson(tx.txID.txIndex, readKey);
|
|
138
|
+
|
|
139
|
+
// return decryptedString ? [decryptedString] : [];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return tx.changes ?? (tx.tx as any).changes ?? [];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function getHistory(coValue: RawCoValue): HistoryEntry[] {
|
|
146
|
+
return coValue.core.verifiedTransactions.flatMap((tx, index) => {
|
|
147
|
+
const changes = getTransactionChanges(tx, coValue);
|
|
148
|
+
|
|
149
|
+
return changes.map((change, changeIndex) => ({
|
|
150
|
+
id: `${tx.txID.sessionID.toString()}-${tx.txID.txIndex}-${index}-${changeIndex}`,
|
|
151
|
+
author: tx.author,
|
|
152
|
+
action: mapTransactionToAction(change, coValue),
|
|
153
|
+
timestamp: new Date(tx.currentMadeAt),
|
|
154
|
+
isValid: tx.isValid,
|
|
155
|
+
}));
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function mapTransactionToAction(
|
|
160
|
+
change: JsonValue,
|
|
161
|
+
coValue: RawCoValue,
|
|
162
|
+
): string {
|
|
163
|
+
// Group changes
|
|
164
|
+
if (isUserPromotion(change)) {
|
|
165
|
+
if (change.value === "revoked") {
|
|
166
|
+
return `${change.key} has been revoked`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return `${change.key} has been promoted to ${change.value}`;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (isGroupExtension(change)) {
|
|
173
|
+
const child = change.key.slice(6);
|
|
174
|
+
return `Group became a member of ${child}`;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (isGroupExtendRevocation(change)) {
|
|
178
|
+
const child = change.key.slice(6);
|
|
179
|
+
return `Group's membership of ${child} has been revoked.`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (isGroupPromotion(change)) {
|
|
183
|
+
const parent = change.key.slice(7);
|
|
184
|
+
return `Group ${parent} has been promoted to ${change.value}`;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (isKeyRevelation(change)) {
|
|
188
|
+
const [key, target] = change.key.split("_for_");
|
|
189
|
+
return `Key "${key}" has been revealed to "${target}"`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// coList changes
|
|
193
|
+
if (isItemAppend(change)) {
|
|
194
|
+
if (change.after === "start") {
|
|
195
|
+
return `"${change.value}" has been appended`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const after = findListChange(change.after, coValue);
|
|
199
|
+
|
|
200
|
+
if (after === undefined) {
|
|
201
|
+
return `"${change.value}" has been inserted after undefined item`;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return `"${change.value}" has been inserted after "${(after as any).value}"`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (isItemPrepend(change)) {
|
|
208
|
+
if (change.before === "end") {
|
|
209
|
+
return `"${change.value}" has been prepended`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const before = findListChange(change.before, coValue);
|
|
213
|
+
|
|
214
|
+
if (before === undefined) {
|
|
215
|
+
return `"${change.value}" has been inserted before undefined item`;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return `"${change.value}" has been inserted before "${(before as any).value}"`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (isItemDeletion(change)) {
|
|
222
|
+
const insertion = findListChange(change.insertion, coValue);
|
|
223
|
+
if (insertion === undefined) {
|
|
224
|
+
return `An undefined item has been deleted`;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return `"${(insertion as any).value}" has been deleted`;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// coStream changes
|
|
231
|
+
if (isStreamStart(change)) {
|
|
232
|
+
return `Stream started with mime type "${change.mimeType}" and file name "${change.fileName}"`;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (isStreamChunk(change)) {
|
|
236
|
+
return `Stream chunk added`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (isStreamEnd(change)) {
|
|
240
|
+
return `Stream ended`;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// coMap changes
|
|
244
|
+
if (isPropertySet(change)) {
|
|
245
|
+
return `Property "${change.key}" has been set to "${change.value}"`;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (isPropertyDeletion(change)) {
|
|
249
|
+
return `Property "${change.key}" has been deleted`;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return "Unknown action: " + JSON.stringify(change);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const findListChange = (
|
|
256
|
+
opId: OpID,
|
|
257
|
+
coValue: RawCoValue,
|
|
258
|
+
): JsonValue | undefined => {
|
|
259
|
+
return coValue.core.verifiedTransactions.find(
|
|
260
|
+
(tx) =>
|
|
261
|
+
tx.txID.sessionID === opId.sessionID && tx.txID.txIndex === opId.txIndex,
|
|
262
|
+
)?.changes?.[opId.changeIdx];
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const isGroupExtension = (
|
|
266
|
+
change: any,
|
|
267
|
+
): change is Extract<
|
|
268
|
+
MapOpPayload<`child_${string}`, "extend">,
|
|
269
|
+
{ op: "set" }
|
|
270
|
+
> => {
|
|
271
|
+
return change?.op === "set" && change?.value === "extend";
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const isGroupExtendRevocation = (
|
|
275
|
+
change: any,
|
|
276
|
+
): change is Extract<
|
|
277
|
+
MapOpPayload<`child_${string}`, "revoked">,
|
|
278
|
+
{ op: "set" }
|
|
279
|
+
> => {
|
|
280
|
+
return change?.op === "set" && change?.value === "revoked";
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const isGroupPromotion = (
|
|
284
|
+
change: any,
|
|
285
|
+
): change is Extract<
|
|
286
|
+
MapOpPayload<`parent_co_${string}`, AccountRole>,
|
|
287
|
+
{ op: "set" }
|
|
288
|
+
> => {
|
|
289
|
+
return change?.op === "set" && change?.key.startsWith("parent_co_");
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const isUserPromotion = (
|
|
293
|
+
change: any,
|
|
294
|
+
): change is Extract<MapOpPayload<CoID<RawCoValue>, Role>, { op: "set" }> => {
|
|
295
|
+
return (
|
|
296
|
+
change?.op === "set" && (isCoId(change?.key) || change?.key === "everyone")
|
|
297
|
+
);
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const isKeyRevelation = (
|
|
301
|
+
change: any,
|
|
302
|
+
): change is Extract<
|
|
303
|
+
MapOpPayload<`${string}_for_${string}`, string>,
|
|
304
|
+
{ op: "set" }
|
|
305
|
+
> => {
|
|
306
|
+
return change?.op === "set" && change?.key.includes("_for_");
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const isPropertySet = (
|
|
310
|
+
change: any,
|
|
311
|
+
): change is Extract<MapOpPayload<string, any>, { op: "set" }> => {
|
|
312
|
+
return change?.op === "set" && "key" in change && "value" in change;
|
|
313
|
+
};
|
|
314
|
+
const isPropertyDeletion = (
|
|
315
|
+
change: any,
|
|
316
|
+
): change is Extract<MapOpPayload<string, any>, { op: "del" }> => {
|
|
317
|
+
return change?.op === "del" && "key" in change;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const isItemAppend = (
|
|
321
|
+
change: any,
|
|
322
|
+
): change is Extract<InsertionOpPayload<any>, { op: "app" }> => {
|
|
323
|
+
return change?.op === "app" && "after" in change && "value" in change;
|
|
324
|
+
};
|
|
325
|
+
const isItemPrepend = (
|
|
326
|
+
change: any,
|
|
327
|
+
): change is Extract<InsertionOpPayload<any>, { op: "pre" }> => {
|
|
328
|
+
return change?.op === "pre" && "before" in change && "value" in change;
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const isItemDeletion = (
|
|
332
|
+
change: any,
|
|
333
|
+
): change is Extract<DeletionOpPayload, { op: "del" }> => {
|
|
334
|
+
return change?.op === "del" && "insertion" in change;
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
const isStreamStart = (change: any): change is BinaryStreamStart => {
|
|
338
|
+
return change?.type === "start" && "mimeType" in change;
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const isStreamChunk = (change: any): change is BinaryStreamChunk => {
|
|
342
|
+
return change?.type === "chunk" && "chunk" in change;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const isStreamEnd = (change: any): change is BinaryStreamEnd => {
|
|
346
|
+
return change?.type === "end";
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const RedTooltip = styled("span")`
|
|
350
|
+
position:relative; /* making the .tooltip span a container for the tooltip text */
|
|
351
|
+
border-bottom:1px dashed #000; /* little indicater to indicate it's hoverable */
|
|
352
|
+
|
|
353
|
+
&:before {
|
|
354
|
+
content: attr(data-text);
|
|
355
|
+
background-color: red;
|
|
356
|
+
position:absolute;
|
|
357
|
+
|
|
358
|
+
/* vertically center */
|
|
359
|
+
top:50%;
|
|
360
|
+
transform:translateY(-50%);
|
|
361
|
+
|
|
362
|
+
/* move to right */
|
|
363
|
+
left:100%;
|
|
364
|
+
margin-left:15px; /* and add a small left margin */
|
|
365
|
+
|
|
366
|
+
/* basic styles */
|
|
367
|
+
width:200px;
|
|
368
|
+
padding:10px;
|
|
369
|
+
border-radius:10px;
|
|
370
|
+
color: #fff;
|
|
371
|
+
text-align:center;
|
|
372
|
+
|
|
373
|
+
display:none; /* hide by default */
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
&:hover:before {
|
|
377
|
+
display:block;
|
|
378
|
+
}
|
|
379
|
+
`;
|
|
@@ -22,6 +22,7 @@ import { TableView } from "./table-viewer.js";
|
|
|
22
22
|
import { TypeIcon } from "./type-icon.js";
|
|
23
23
|
import { PageInfo } from "./types.js";
|
|
24
24
|
import { resolveCoValue, useResolvedCoValue } from "./use-resolve-covalue.js";
|
|
25
|
+
import { HistoryView } from "./history-view.js";
|
|
25
26
|
|
|
26
27
|
interface PageContainerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
27
28
|
isTopLevel?: boolean;
|
|
@@ -240,6 +241,7 @@ export function Page(props: PageProps) {
|
|
|
240
241
|
</Text>
|
|
241
242
|
</>
|
|
242
243
|
)}
|
|
244
|
+
{value && <HistoryView coValue={value} node={node} />}
|
|
243
245
|
</ContentContainer>
|
|
244
246
|
</PageContainer>
|
|
245
247
|
);
|
|
@@ -74,7 +74,7 @@ describe("createImage", async () => {
|
|
|
74
74
|
|
|
75
75
|
getImageSize.mockResolvedValue({ width: 1, height: 1 });
|
|
76
76
|
getPlaceholderBase64.mockResolvedValue(
|
|
77
|
-
"data:image/png;base64,
|
|
77
|
+
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
|
|
78
78
|
);
|
|
79
79
|
|
|
80
80
|
const image = await createImage(imageBlob, {
|
|
@@ -204,7 +204,7 @@ describe("createImage", async () => {
|
|
|
204
204
|
|
|
205
205
|
// 1x1 png
|
|
206
206
|
const OnePixel = atob(
|
|
207
|
-
"
|
|
207
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
|
|
208
208
|
);
|
|
209
209
|
|
|
210
210
|
// Image 1920x400
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
[
|
|
114
114
|
Uint8Array.from(
|
|
115
115
|
atob(
|
|
116
|
-
"
|
|
116
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
|
|
117
117
|
),
|
|
118
118
|
(c) => c.charCodeAt(0),
|
|
119
119
|
),
|
|
@@ -626,7 +626,7 @@ describe("Image", async () => {
|
|
|
626
626
|
|
|
627
627
|
const img = container.querySelector("img");
|
|
628
628
|
expect(img).toBeDefined();
|
|
629
|
-
expect(img!.src).toBe("blob:test-
|
|
629
|
+
expect(img!.src).toBe("blob:test-68");
|
|
630
630
|
});
|
|
631
631
|
|
|
632
632
|
it("should load the image when threshold is reached", async () => {
|
|
@@ -286,12 +286,12 @@ export class CoFeed<out Item = any> extends CoValueBase implements CoValue {
|
|
|
286
286
|
static load<F extends CoFeed, const R extends RefsToResolve<F> = true>(
|
|
287
287
|
this: CoValueClass<F>,
|
|
288
288
|
id: ID<F>,
|
|
289
|
-
options
|
|
289
|
+
options?: {
|
|
290
290
|
resolve?: RefsToResolveStrict<F, R>;
|
|
291
291
|
loadAs?: Account | AnonymousJazzAgent;
|
|
292
292
|
},
|
|
293
293
|
): Promise<Resolved<F, R> | null> {
|
|
294
|
-
return loadCoValueWithoutMe(this, id, options);
|
|
294
|
+
return loadCoValueWithoutMe(this, id, options ?? {});
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
/**
|
|
@@ -78,7 +78,7 @@ export class FileStreamSchema implements CoreFileStreamSchema {
|
|
|
78
78
|
|
|
79
79
|
load(
|
|
80
80
|
id: string,
|
|
81
|
-
options
|
|
81
|
+
options?: { loadAs?: Account | AnonymousJazzAgent },
|
|
82
82
|
): Promise<FileStream | null> {
|
|
83
83
|
return this.coValueClass.load(id, options);
|
|
84
84
|
}
|
|
@@ -1251,7 +1251,7 @@ describe("CoValueCoreSubscription", async () => {
|
|
|
1251
1251
|
subscription.unsubscribe();
|
|
1252
1252
|
});
|
|
1253
1253
|
|
|
1254
|
-
test
|
|
1254
|
+
test("should wait for the full streaming of the parent group", async () => {
|
|
1255
1255
|
disableJazzTestSync();
|
|
1256
1256
|
|
|
1257
1257
|
const alice = await createJazzTestAccount({
|
|
@@ -773,7 +773,7 @@ describe("FileStream large file loading", async () => {
|
|
|
773
773
|
|
|
774
774
|
const loadedChunks = loadedStream.getChunks({ allowUnfinished: true });
|
|
775
775
|
expect(loadedChunks).not.toBeNull();
|
|
776
|
-
expect(loadedChunks?.finished).
|
|
776
|
+
expect(loadedChunks?.finished).toBeFalsy();
|
|
777
777
|
|
|
778
778
|
expect(loadedStream.$jazz.raw.core.knownState()).not.toEqual(
|
|
779
779
|
largeStream.$jazz.raw.core.knownState(),
|
|
@@ -337,7 +337,7 @@ test("should wait for the full streaming of the group", async () => {
|
|
|
337
337
|
);
|
|
338
338
|
});
|
|
339
339
|
|
|
340
|
-
test
|
|
340
|
+
test("should wait for the full streaming of the parent groups", async () => {
|
|
341
341
|
disableJazzTestSync();
|
|
342
342
|
|
|
343
343
|
const alice = await createJazzTestAccount({
|
package/src/worker/index.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AgentSecret,
|
|
3
|
+
CryptoProvider,
|
|
4
|
+
LocalNode,
|
|
5
|
+
Peer,
|
|
6
|
+
StorageAPI,
|
|
7
|
+
} from "cojson";
|
|
2
8
|
import {
|
|
3
9
|
type AnyWebSocketConstructor,
|
|
4
10
|
WebSocketPeerWithReconnection,
|
|
@@ -35,6 +41,7 @@ type WorkerOptions<
|
|
|
35
41
|
* If false, the worker will not set in the global account context
|
|
36
42
|
*/
|
|
37
43
|
asActiveAccount?: boolean;
|
|
44
|
+
storage?: StorageAPI;
|
|
38
45
|
};
|
|
39
46
|
|
|
40
47
|
/** @category Context Creation */
|
|
@@ -95,6 +102,7 @@ export async function startWorker<
|
|
|
95
102
|
peers,
|
|
96
103
|
crypto: options.crypto ?? (await WasmCrypto.create()),
|
|
97
104
|
asActiveAccount,
|
|
105
|
+
storage: options.storage,
|
|
98
106
|
});
|
|
99
107
|
|
|
100
108
|
const account = context.account as InstanceOfSchema<S>;
|