jazz-tools 0.17.0 → 0.17.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/.svelte-kit/__package__/media/image.svelte +1 -1
- package/.turbo/turbo-build.log +39 -39
- package/CHANGELOG.md +23 -0
- package/dist/index.js.map +1 -1
- package/dist/media/{chunk-BBSS3NEY.js → chunk-JBLT443O.js} +15 -15
- package/dist/media/{chunk-BBSS3NEY.js.map → chunk-JBLT443O.js.map} +1 -1
- package/dist/media/index.browser.js +1 -1
- package/dist/media/index.js +1 -1
- package/dist/media/index.native.d.ts.map +1 -1
- package/dist/media/index.native.js +13 -4
- package/dist/media/index.native.js.map +1 -1
- package/dist/media/utils.d.ts.map +1 -1
- package/dist/react/index.js +19 -13
- package/dist/react/index.js.map +1 -1
- package/dist/svelte/media/image.svelte +1 -1
- package/dist/tools/coValues/request.d.ts +1 -1
- 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/package.json +4 -4
- package/src/media/index.native.ts +17 -4
- package/src/media/utils.test.ts +57 -11
- package/src/media/utils.ts +18 -15
- package/src/react/media/image.tsx +18 -12
- package/src/svelte/media/image.svelte +1 -1
- package/src/tools/coValues/request.ts +1 -1
- package/src/tools/exports.ts +1 -0
package/src/media/utils.test.ts
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
import { Account, FileStream, ImageDefinition } from "jazz-tools";
|
2
|
-
import {
|
3
|
-
|
1
|
+
import { Account, FileStream, Group, ImageDefinition } from "jazz-tools";
|
2
|
+
import {
|
3
|
+
createJazzTestAccount,
|
4
|
+
setActiveAccount,
|
5
|
+
setupJazzTestSync,
|
6
|
+
} from "jazz-tools/testing";
|
4
7
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
8
|
+
import { highestResAvailable, loadImageBySize } from "./utils.js";
|
5
9
|
|
6
10
|
const createFileStream = (account: any, blobSize?: number) => {
|
7
11
|
return FileStream.createFromBlob(
|
@@ -209,23 +213,21 @@ describe("highestResAvailable", async () => {
|
|
209
213
|
describe("loadImageBySize", async () => {
|
210
214
|
let account: Account;
|
211
215
|
beforeEach(async () => {
|
212
|
-
account = await
|
213
|
-
|
214
|
-
});
|
215
|
-
vi.spyOn(Account, "getMe").mockReturnValue(account);
|
216
|
-
await setupJazzTestSync();
|
216
|
+
account = await setupJazzTestSync();
|
217
|
+
setActiveAccount(account);
|
217
218
|
});
|
218
219
|
|
219
220
|
const createImageDef = async (
|
220
221
|
sizes: Array<[number, number]>,
|
221
222
|
progressive = true,
|
223
|
+
owner: Account | Group = account,
|
222
224
|
) => {
|
223
225
|
if (sizes.length === 0) throw new Error("sizes array must not be empty");
|
224
226
|
|
225
227
|
const originalSize = sizes[sizes.length - 1]!;
|
226
228
|
sizes = sizes.slice(0, -1);
|
227
229
|
|
228
|
-
const original = await createFileStream(
|
230
|
+
const original = await createFileStream(owner, 1);
|
229
231
|
// Ensure sizes array is not empty
|
230
232
|
const imageDef = ImageDefinition.create(
|
231
233
|
{
|
@@ -233,14 +235,14 @@ describe("loadImageBySize", async () => {
|
|
233
235
|
progressive,
|
234
236
|
original,
|
235
237
|
},
|
236
|
-
{ owner
|
238
|
+
{ owner },
|
237
239
|
);
|
238
240
|
imageDef[`${originalSize[0]}x${originalSize[1]}`] = original;
|
239
241
|
|
240
242
|
for (const size of sizes) {
|
241
243
|
if (!size) continue;
|
242
244
|
const [w, h] = size;
|
243
|
-
imageDef[`${w}x${h}`] = await createFileStream(
|
245
|
+
imageDef[`${w}x${h}`] = await createFileStream(owner, 1);
|
244
246
|
}
|
245
247
|
return imageDef;
|
246
248
|
};
|
@@ -251,6 +253,24 @@ describe("loadImageBySize", async () => {
|
|
251
253
|
expect(result?.image.id).toBe(imageDef["1920x1080"]!.id);
|
252
254
|
});
|
253
255
|
|
256
|
+
it("returns the original image already loaded", async () => {
|
257
|
+
const account = await setupJazzTestSync({ asyncPeers: true });
|
258
|
+
const account2 = await createJazzTestAccount();
|
259
|
+
|
260
|
+
setActiveAccount(account);
|
261
|
+
|
262
|
+
const group = Group.create();
|
263
|
+
group.addMember("everyone", "reader");
|
264
|
+
|
265
|
+
const imageDef = await createImageDef([[1920, 1080]], false, group);
|
266
|
+
setActiveAccount(account2);
|
267
|
+
|
268
|
+
const result = await loadImageBySize(imageDef, 256, 256);
|
269
|
+
expect(result?.image.id).toBe(imageDef["1920x1080"]!.id);
|
270
|
+
expect(result?.image.isBinaryStreamEnded()).toBe(true);
|
271
|
+
expect(result?.image.asBase64()).toStrictEqual(expect.any(String));
|
272
|
+
});
|
273
|
+
|
254
274
|
it("returns null if no sizes are available", async () => {
|
255
275
|
const original = await createFileStream(account._owner, 1);
|
256
276
|
const imageDef = ImageDefinition.create(
|
@@ -324,4 +344,30 @@ describe("loadImageBySize", async () => {
|
|
324
344
|
expect(result?.width).toBe(1024);
|
325
345
|
expect(result?.height).toBe(1024);
|
326
346
|
});
|
347
|
+
|
348
|
+
it("returns the image already loaded", async () => {
|
349
|
+
const account = await setupJazzTestSync({ asyncPeers: true });
|
350
|
+
const account2 = await createJazzTestAccount();
|
351
|
+
|
352
|
+
setActiveAccount(account);
|
353
|
+
|
354
|
+
const group = Group.create();
|
355
|
+
group.addMember("everyone", "reader");
|
356
|
+
|
357
|
+
const imageDef = await createImageDef(
|
358
|
+
[
|
359
|
+
[512, 512],
|
360
|
+
[1024, 1024],
|
361
|
+
],
|
362
|
+
undefined,
|
363
|
+
group,
|
364
|
+
);
|
365
|
+
|
366
|
+
setActiveAccount(account2);
|
367
|
+
|
368
|
+
const result = await loadImageBySize(imageDef, 1024, 1024);
|
369
|
+
expect(result?.image.id).toBe(imageDef["1024x1024"]!.id);
|
370
|
+
expect(result?.image.isBinaryStreamEnded()).toBe(true);
|
371
|
+
expect(result?.image.asBase64()).toStrictEqual(expect.any(String));
|
372
|
+
});
|
327
373
|
});
|
package/src/media/utils.ts
CHANGED
@@ -126,21 +126,22 @@ export async function loadImage(
|
|
126
126
|
};
|
127
127
|
}
|
128
128
|
|
129
|
-
await imageOrId.ensureLoaded({
|
130
|
-
resolve: {
|
131
|
-
original: true,
|
132
|
-
},
|
133
|
-
});
|
134
|
-
|
135
129
|
if (!imageOrId.original) {
|
136
130
|
console.warn("Unable to find the original image");
|
137
131
|
return null;
|
138
132
|
}
|
139
133
|
|
134
|
+
const loadedOriginal = await FileStream.load(imageOrId.original.id);
|
135
|
+
|
136
|
+
if (!loadedOriginal) {
|
137
|
+
console.warn("Unable to find the original image");
|
138
|
+
return null;
|
139
|
+
}
|
140
|
+
|
140
141
|
return {
|
141
142
|
width: imageOrId.originalSize[0],
|
142
143
|
height: imageOrId.originalSize[1],
|
143
|
-
image:
|
144
|
+
image: loadedOriginal,
|
144
145
|
};
|
145
146
|
}
|
146
147
|
|
@@ -149,7 +150,7 @@ export async function loadImageBySize(
|
|
149
150
|
wantedWidth: number,
|
150
151
|
wantedHeight: number,
|
151
152
|
): Promise<{ width: number; height: number; image: FileStream } | null> {
|
152
|
-
const image =
|
153
|
+
const image: ImageDefinition | null =
|
153
154
|
typeof imageOrId === "string"
|
154
155
|
? await ImageDefinition.load(imageOrId)
|
155
156
|
: imageOrId;
|
@@ -184,19 +185,21 @@ export async function loadImageBySize(
|
|
184
185
|
const bestTarget =
|
185
186
|
sortedSizes.find((el) => el.match > 0.95) || sortedSizes.at(-1)!;
|
186
187
|
|
187
|
-
const
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
}
|
188
|
+
const file = image[bestTarget.size[2]];
|
189
|
+
|
190
|
+
if (!file) {
|
191
|
+
return null;
|
192
|
+
}
|
193
|
+
|
194
|
+
const loadedFile = await FileStream.load(file.id);
|
192
195
|
|
193
|
-
if (
|
196
|
+
if (!loadedFile) {
|
194
197
|
return null;
|
195
198
|
}
|
196
199
|
|
197
200
|
return {
|
198
201
|
width: bestTarget.size[0],
|
199
202
|
height: bestTarget.size[1],
|
200
|
-
image:
|
203
|
+
image: loadedFile,
|
201
204
|
};
|
202
205
|
}
|
@@ -92,7 +92,7 @@ export const Image = forwardRef<HTMLImageElement, ImageProps>(function Image(
|
|
92
92
|
);
|
93
93
|
const lazyPlaceholder = useMemo(
|
94
94
|
() =>
|
95
|
-
waitingLazyLoading ? URL.createObjectURL(
|
95
|
+
waitingLazyLoading ? URL.createObjectURL(getEmptyPixelBlob()) : undefined,
|
96
96
|
[waitingLazyLoading],
|
97
97
|
);
|
98
98
|
|
@@ -197,14 +197,20 @@ function revokeObjectURL(url: string | undefined) {
|
|
197
197
|
}
|
198
198
|
}
|
199
199
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
)
|
200
|
+
let emptyPixelBlob: Blob | undefined;
|
201
|
+
function getEmptyPixelBlob() {
|
202
|
+
if (!emptyPixelBlob) {
|
203
|
+
emptyPixelBlob = new Blob(
|
204
|
+
[
|
205
|
+
Uint8Array.from(
|
206
|
+
atob(
|
207
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==",
|
208
|
+
),
|
209
|
+
(c) => c.charCodeAt(0),
|
210
|
+
),
|
211
|
+
],
|
212
|
+
{ type: "image/png" },
|
213
|
+
);
|
214
|
+
}
|
215
|
+
return emptyPixelBlob;
|
216
|
+
}
|
@@ -13,7 +13,7 @@ interface ImageProps extends Omit<HTMLImgAttributes, "width" | "height"> {
|
|
13
13
|
|
14
14
|
const { imageId, width, height, ...rest }: ImageProps = $props();
|
15
15
|
|
16
|
-
const imageState = new CoState(ImageDefinition, imageId);
|
16
|
+
const imageState = new CoState(ImageDefinition, () => imageId);
|
17
17
|
let lastBestImage: [string, string] | null = null;
|
18
18
|
|
19
19
|
/**
|
@@ -330,7 +330,7 @@ function parseSchemaAndResolve<
|
|
330
330
|
};
|
331
331
|
}
|
332
332
|
|
333
|
-
class HttpRoute<
|
333
|
+
export class HttpRoute<
|
334
334
|
RequestShape extends MessageShape = z.core.$ZodLooseShape,
|
335
335
|
RequestResolve extends ResolveQuery<CoMapSchema<RequestShape>> = any,
|
336
336
|
ResponseShape extends MessageShape = z.core.$ZodLooseShape,
|