jazz-tools 0.18.16 → 0.18.17
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 +104 -98
- package/.svelte-kit/__package__/media/image.svelte.d.ts.map +1 -1
- package/.svelte-kit/__package__/tests/media/image.svelte.test.js +16 -2
- package/.turbo/turbo-build.log +42 -42
- package/CHANGELOG.md +11 -0
- package/dist/{chunk-GRN6OAUX.js → chunk-OTWWOZMB.js} +73 -4
- package/dist/chunk-OTWWOZMB.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/media/image.d.ts.map +1 -1
- package/dist/react-native-core/index.js +3 -1
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/media/image.d.ts.map +1 -1
- package/dist/svelte/media/image.svelte +104 -98
- package/dist/svelte/media/image.svelte.d.ts.map +1 -1
- package/dist/svelte/tests/media/image.svelte.test.js +16 -2
- package/dist/testing.js +1 -1
- package/dist/tools/implementation/refs.d.ts +1 -1
- package/dist/tools/implementation/refs.d.ts.map +1 -1
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts +4 -0
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts +7 -0
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/react/media/image.tsx +2 -0
- package/src/react/tests/media/image.test.tsx +20 -2
- package/src/react-native-core/media/image.tsx +4 -1
- package/src/svelte/media/image.svelte +104 -98
- package/src/svelte/tests/media/image.svelte.test.ts +18 -2
- package/src/tools/implementation/refs.ts +27 -3
- package/src/tools/subscribe/CoValueCoreSubscription.ts +14 -0
- package/src/tools/subscribe/SubscriptionScope.ts +62 -1
- package/src/tools/subscribe/index.ts +8 -0
- package/dist/chunk-GRN6OAUX.js.map +0 -1
@@ -1,118 +1,122 @@
|
|
1
1
|
<script lang="ts">
|
2
|
-
import { ImageDefinition } from "jazz-tools";
|
3
|
-
import { highestResAvailable } from "jazz-tools/media";
|
4
|
-
import { onDestroy } from "svelte";
|
5
|
-
import { CoState } from "../jazz.class.svelte";
|
6
|
-
import type { ImageProps } from "./image.types.js";
|
7
|
-
|
8
|
-
const { imageId, width, height, ...rest }: ImageProps = $props();
|
9
|
-
|
10
|
-
const imageState = new CoState(ImageDefinition, () => imageId);
|
11
|
-
let lastBestImage: [string, string] | null = null;
|
12
|
-
|
13
|
-
/**
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
let waitingLazyLoading = $state(rest.loading === "lazy");
|
20
|
-
const lazyPlaceholder = $derived.by(() =>
|
21
|
-
|
22
|
-
);
|
23
|
-
|
24
|
-
const dimensions = $derived.by<{
|
25
|
-
|
26
|
-
|
27
|
-
}>(() => {
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
// Both width and height are "original"
|
32
|
-
if (width === "original" && height === "original") {
|
33
|
-
return { width: originalWidth, height: originalHeight };
|
34
|
-
}
|
2
|
+
import { ImageDefinition } from "jazz-tools";
|
3
|
+
import { highestResAvailable } from "jazz-tools/media";
|
4
|
+
import { onDestroy } from "svelte";
|
5
|
+
import { CoState } from "../jazz.class.svelte";
|
6
|
+
import type { ImageProps } from "./image.types.js";
|
7
|
+
|
8
|
+
const { imageId, width, height, ...rest }: ImageProps = $props();
|
9
|
+
|
10
|
+
const imageState = new CoState(ImageDefinition, () => imageId);
|
11
|
+
let lastBestImage: [string, string] | null = null;
|
12
|
+
|
13
|
+
/**
|
14
|
+
* For lazy loading, we use the browser's strategy for images with loading="lazy".
|
15
|
+
* We use an empty image, and when the browser triggers the load event, we load the best available image.
|
16
|
+
* On page loading, if the image url is already in browser's cache, the load event is triggered immediately.
|
17
|
+
* This is why we need to use a different blob url for every image.
|
18
|
+
*/
|
19
|
+
let waitingLazyLoading = $state(rest.loading === "lazy");
|
20
|
+
const lazyPlaceholder = $derived.by(() =>
|
21
|
+
waitingLazyLoading ? URL.createObjectURL(emptyPixelBlob) : undefined,
|
22
|
+
);
|
23
|
+
|
24
|
+
const dimensions = $derived.by<{
|
25
|
+
width: number | undefined;
|
26
|
+
height: number | undefined;
|
27
|
+
}>(() => {
|
28
|
+
const originalWidth = imageState.current?.originalSize?.[0];
|
29
|
+
const originalHeight = imageState.current?.originalSize?.[1];
|
35
30
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
return {
|
40
|
-
width: Math.round((height * originalWidth) / originalHeight),
|
41
|
-
height,
|
42
|
-
};
|
31
|
+
// Both width and height are "original"
|
32
|
+
if (width === "original" && height === "original") {
|
33
|
+
return { width: originalWidth, height: originalHeight };
|
43
34
|
}
|
44
|
-
return { width: undefined, height };
|
45
|
-
}
|
46
35
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
36
|
+
// Width is "original", height is a number
|
37
|
+
if (width === "original" && typeof height === "number") {
|
38
|
+
if (originalWidth && originalHeight) {
|
39
|
+
return {
|
40
|
+
width: Math.round((height * originalWidth) / originalHeight),
|
41
|
+
height,
|
42
|
+
};
|
43
|
+
}
|
44
|
+
return { width: undefined, height };
|
54
45
|
}
|
55
|
-
return { width, height: undefined };
|
56
|
-
}
|
57
46
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
47
|
+
// Height is "original", width is a number
|
48
|
+
if (height === "original" && typeof width === "number") {
|
49
|
+
if (originalWidth && originalHeight) {
|
50
|
+
return {
|
51
|
+
width,
|
52
|
+
height: Math.round((width * originalHeight) / originalWidth),
|
53
|
+
};
|
54
|
+
}
|
55
|
+
return { width, height: undefined };
|
56
|
+
}
|
64
57
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
58
|
+
// In all other cases, use the property value:
|
59
|
+
return {
|
60
|
+
width: width === "original" ? originalWidth : width,
|
61
|
+
height: height === "original" ? originalHeight : height,
|
62
|
+
};
|
63
|
+
});
|
69
64
|
|
70
|
-
const
|
71
|
-
|
65
|
+
const src = $derived.by(() => {
|
66
|
+
if (waitingLazyLoading) {
|
67
|
+
return lazyPlaceholder;
|
68
|
+
}
|
72
69
|
|
73
|
-
|
74
|
-
image
|
75
|
-
|
76
|
-
dimensions.height || dimensions.width || 9999,
|
77
|
-
);
|
70
|
+
const image = imageState.current;
|
71
|
+
if (image === undefined)
|
72
|
+
return "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
|
78
73
|
|
79
|
-
|
80
|
-
if (lastBestImage?.[0] === bestImage.image.$jazz.id) return lastBestImage?.[1];
|
74
|
+
if (!image) return undefined;
|
81
75
|
|
82
|
-
|
76
|
+
const bestImage = highestResAvailable(
|
77
|
+
image,
|
78
|
+
dimensions.width || dimensions.height || 9999,
|
79
|
+
dimensions.height || dimensions.width || 9999,
|
80
|
+
);
|
83
81
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
82
|
+
if (!bestImage) return image.placeholderDataURL;
|
83
|
+
if (lastBestImage?.[0] === bestImage.image.$jazz.id)
|
84
|
+
return lastBestImage?.[1];
|
85
|
+
|
86
|
+
const blob = bestImage.image.toBlob();
|
87
|
+
|
88
|
+
if (blob) {
|
89
|
+
const url = URL.createObjectURL(blob);
|
90
|
+
revokeObjectURL(lastBestImage?.[1]);
|
91
|
+
lastBestImage = [bestImage.image.$jazz.id, url];
|
92
|
+
return url;
|
93
|
+
}
|
90
94
|
|
91
|
-
|
92
|
-
});
|
95
|
+
return image.placeholderDataURL;
|
96
|
+
});
|
93
97
|
|
94
|
-
// Cleanup object URL on component destroy
|
95
|
-
onDestroy(() => {
|
96
|
-
|
97
|
-
});
|
98
|
+
// Cleanup object URL on component destroy
|
99
|
+
onDestroy(() => {
|
100
|
+
revokeObjectURL(lastBestImage?.[1]);
|
101
|
+
});
|
98
102
|
|
99
|
-
function revokeObjectURL(url: string | undefined) {
|
100
|
-
|
101
|
-
|
103
|
+
function revokeObjectURL(url: string | undefined) {
|
104
|
+
if (url && url.startsWith("blob:")) {
|
105
|
+
URL.revokeObjectURL(url);
|
106
|
+
}
|
102
107
|
}
|
103
|
-
}
|
104
108
|
|
105
|
-
const emptyPixelBlob = new Blob(
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
109
|
+
const emptyPixelBlob = new Blob(
|
110
|
+
[
|
111
|
+
Uint8Array.from(
|
112
|
+
atob(
|
113
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==",
|
114
|
+
),
|
115
|
+
(c) => c.charCodeAt(0),
|
110
116
|
),
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
{ type: "image/png" },
|
115
|
-
);
|
117
|
+
],
|
118
|
+
{ type: "image/png" },
|
119
|
+
);
|
116
120
|
</script>
|
117
121
|
|
118
122
|
<img
|
@@ -120,6 +124,8 @@ const emptyPixelBlob = new Blob(
|
|
120
124
|
width={dimensions.width}
|
121
125
|
height={dimensions.height}
|
122
126
|
alt={rest.alt}
|
123
|
-
onload={() => {
|
127
|
+
onload={() => {
|
128
|
+
waitingLazyLoading = false;
|
129
|
+
}}
|
124
130
|
{...rest}
|
125
131
|
/>
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"image.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/media/image.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
1
|
+
{"version":3,"file":"image.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/media/image.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAiInD,QAAA,MAAM,KAAK,gDAAsC,CAAC;AAClD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
|
@@ -10,7 +10,7 @@ describe("Image", async () => {
|
|
10
10
|
});
|
11
11
|
const renderWithAccount = (props) => render(Image, props, { account });
|
12
12
|
describe("initial rendering", () => {
|
13
|
-
it("should render
|
13
|
+
it("should render a blank placeholder while waiting for the coValue to load", async () => {
|
14
14
|
const { container } = renderWithAccount({
|
15
15
|
imageId: "co_zMTubMby3QiKDYnW9e2BEXW7Xaq",
|
16
16
|
alt: "test",
|
@@ -20,7 +20,21 @@ describe("Image", async () => {
|
|
20
20
|
expect(img.getAttribute("width")).toBe(null);
|
21
21
|
expect(img.getAttribute("height")).toBe(null);
|
22
22
|
expect(img.alt).toBe("test");
|
23
|
-
expect(img.src).toBe("");
|
23
|
+
expect(img.src).toBe("data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==");
|
24
|
+
});
|
25
|
+
it("should render nothing if coValue is not found", async () => {
|
26
|
+
const { container } = renderWithAccount({
|
27
|
+
imageId: "co_zMTubMby3QiKDYnW9e2BEXW7Xaq",
|
28
|
+
alt: "test",
|
29
|
+
});
|
30
|
+
await waitFor(() => {
|
31
|
+
const img = container.querySelector("img");
|
32
|
+
expect(img).toBeDefined();
|
33
|
+
expect(img.getAttribute("width")).toBe(null);
|
34
|
+
expect(img.getAttribute("height")).toBe(null);
|
35
|
+
expect(img.alt).toBe("test");
|
36
|
+
expect(img.src).toBe("");
|
37
|
+
});
|
24
38
|
});
|
25
39
|
it("should render an empty image if the image is not loaded yet", async () => {
|
26
40
|
const original = FileStream.create({ owner: account.$jazz.owner });
|
package/dist/testing.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { type Account } from "../coValues/account.js";
|
2
|
-
import
|
2
|
+
import { AnonymousJazzAgent, CoValue, ID, RefEncoded } from "../internal.js";
|
3
3
|
export declare class Ref<out V extends CoValue> {
|
4
4
|
readonly id: ID<V>;
|
5
5
|
readonly controlledAccount: Account | AnonymousJazzAgent;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../../../src/tools/implementation/refs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,
|
1
|
+
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../../../src/tools/implementation/refs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,OAAO,EACP,EAAE,EACF,UAAU,EAEX,MAAM,gBAAgB,CAAC;AAOxB,qBAAa,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,OAAO;IAElC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAClB,QAAQ,CAAC,iBAAiB,EAAE,OAAO,GAAG,kBAAkB;IACxD,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO;gBAHf,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EACT,iBAAiB,EAAE,OAAO,GAAG,kBAAkB,EAC/C,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EACrB,MAAM,EAAE,OAAO;IAOpB,IAAI,IAAI,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAwD/B,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAEhC;CACF;AAED,wBAAgB,QAAQ,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,EACnD,MAAM,EAAE,OAAO,EACf,WAAW,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,SAAS,EACnD,cAAc,EAAE,MAAM,IAAI,EAAE,EAC5B,iBAAiB,EAAE,OAAO,GAAG,kBAAkB,EAC/C,eAAe,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,UAAU,CAAC,OAAO,CAAC,GAClD;KAAG,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC;CAAE,GAAG;IACjC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,MAAM,EAAE,MAAM,CAAC;CAChB,CAgDA;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,SAAS,OAAO,GACxD,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GACnB,KAAK,CAAC"}
|
@@ -16,6 +16,10 @@ export declare class CoValueCoreSubscription {
|
|
16
16
|
private listener;
|
17
17
|
private skipRetry?;
|
18
18
|
constructor(localNode: LocalNode, id: string, listener: (value: RawCoValue | "unavailable") => void, skipRetry?: boolean, branch?: BranchDefinition);
|
19
|
+
/**
|
20
|
+
* Rehydrates the subscription by resetting the unsubscribed flag and initializing the subscription again
|
21
|
+
*/
|
22
|
+
pullValue(): void;
|
19
23
|
/**
|
20
24
|
* Main entry point for subscription initialization.
|
21
25
|
* Determines the subscription strategy based on current availability and branch requirements.
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"CoValueCoreSubscription.d.ts","sourceRoot":"","sources":["../../../src/tools/subscribe/CoValueCoreSubscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,SAAS,EAET,UAAU,EACX,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;GAKG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,aAAa,CAAC,CAAU;IAChC,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,SAAS,CAAC,CAAU;gBAG1B,SAAS,EAAE,SAAS,EACpB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,KAAK,IAAI,EACrD,SAAS,CAAC,EAAE,OAAO,EACnB,MAAM,CAAC,EAAE,gBAAgB;IAY3B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAmB9B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAY/B;;;OAGG;IACH,OAAO,CAAC,WAAW;IAsBnB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IA6BpC;;;OAGG;IACH,OAAO,CAAC,SAAS;IASjB,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,GAAG,IAAI;IAM7C;;;OAGG;IACH,WAAW,IAAI,IAAI;CAKpB"}
|
1
|
+
{"version":3,"file":"CoValueCoreSubscription.d.ts","sourceRoot":"","sources":["../../../src/tools/subscribe/CoValueCoreSubscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,SAAS,EAET,UAAU,EACX,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;GAKG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,aAAa,CAAC,CAAU;IAChC,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,SAAS,CAAC,CAAU;gBAG1B,SAAS,EAAE,SAAS,EACpB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,KAAK,IAAI,EACrD,SAAS,CAAC,EAAE,OAAO,EACnB,MAAM,CAAC,EAAE,gBAAgB;IAY3B;;OAEG;IACH,SAAS;IAWT;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAmB9B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAY/B;;;OAGG;IACH,OAAO,CAAC,WAAW;IAsBnB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IA6BpC;;;OAGG;IACH,OAAO,CAAC,SAAS;IASjB,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,GAAG,IAAI;IAM7C;;;OAGG;IACH,WAAW,IAAI,IAAI;CAKpB"}
|
@@ -34,6 +34,7 @@ export declare class SubscriptionScope<D extends CoValue> {
|
|
34
34
|
totalValidTransactions: number;
|
35
35
|
migrated: boolean;
|
36
36
|
migrating: boolean;
|
37
|
+
closed: boolean;
|
37
38
|
silenceUpdates: boolean;
|
38
39
|
constructor(node: LocalNode, resolve: RefsToResolve<D>, id: ID<D>, schema: RefEncoded<D>, skipRetry?: boolean, bestEffortResolution?: boolean, unstable_branch?: BranchDefinition | undefined);
|
39
40
|
updateValue(value: SubscriptionValue<D, any>): void;
|
@@ -50,6 +51,12 @@ export declare class SubscriptionScope<D extends CoValue> {
|
|
50
51
|
setListener(listener: (value: SubscriptionValue<D, any>) => void): void;
|
51
52
|
subscribeToKey(key: string): void;
|
52
53
|
isSubscribedToId(id: string): boolean;
|
54
|
+
/**
|
55
|
+
* Checks if the currently unloaded value has got some updates
|
56
|
+
*
|
57
|
+
* Used to make the autoload work on closed subscription scopes
|
58
|
+
*/
|
59
|
+
pullValue(listener: (value: SubscriptionValue<D, any>) => void): void;
|
53
60
|
subscribeToId(id: string, descriptor: RefEncoded<any>): void;
|
54
61
|
loadChildren(): boolean;
|
55
62
|
loadCoMapKey(map: CoMap, key: string, depth: Record<string, any> | true): string | undefined;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SubscriptionScope.d.ts","sourceRoot":"","sources":["../../../src/tools/subscribe/SubscriptionScope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAEL,MAAM,EACN,KAAK,EACL,KAAK,OAAO,EACZ,KAAK,EAAE,EACP,KAAK,UAAU,EACf,KAAK,aAAa,EAInB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,SAAS,EAAuB,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGhF,qBAAa,iBAAiB,CAAC,CAAC,SAAS,OAAO;
|
1
|
+
{"version":3,"file":"SubscriptionScope.d.ts","sourceRoot":"","sources":["../../../src/tools/subscribe/SubscriptionScope.ts"],"names":[],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/subscribe/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,CAAC,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/subscribe/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,CAAC,qDA0B/D;AAED,yBAAyB;AAEzB;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,OAAO,EAChD,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,OAqBZ;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAC/C,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,OAa5B"}
|
package/package.json
CHANGED
@@ -177,7 +177,7 @@
|
|
177
177
|
},
|
178
178
|
"type": "module",
|
179
179
|
"license": "MIT",
|
180
|
-
"version": "0.18.
|
180
|
+
"version": "0.18.17",
|
181
181
|
"dependencies": {
|
182
182
|
"@manuscripts/prosemirror-recreate-steps": "^0.1.4",
|
183
183
|
"@scure/base": "1.2.1",
|
@@ -194,9 +194,9 @@
|
|
194
194
|
"prosemirror-transform": "^1.9.0",
|
195
195
|
"use-sync-external-store": "^1.5.0",
|
196
196
|
"zod": "3.25.76",
|
197
|
-
"cojson": "0.18.
|
198
|
-
"cojson-storage-indexeddb": "0.18.
|
199
|
-
"cojson-transport-ws": "0.18.
|
197
|
+
"cojson": "0.18.17",
|
198
|
+
"cojson-storage-indexeddb": "0.18.17",
|
199
|
+
"cojson-transport-ws": "0.18.17"
|
200
200
|
},
|
201
201
|
"devDependencies": {
|
202
202
|
"@scure/bip39": "^1.3.0",
|
@@ -140,6 +140,8 @@ export const Image = forwardRef<HTMLImageElement, ImageProps>(function Image(
|
|
140
140
|
return lazyPlaceholder;
|
141
141
|
}
|
142
142
|
|
143
|
+
if (image === undefined)
|
144
|
+
return "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
|
143
145
|
if (!image) return undefined;
|
144
146
|
|
145
147
|
const bestImage = highestResAvailable(
|
@@ -13,17 +13,35 @@ describe("Image", async () => {
|
|
13
13
|
vi.spyOn(Account, "getMe").mockReturnValue(account);
|
14
14
|
|
15
15
|
describe("initial rendering", () => {
|
16
|
-
it("should render
|
16
|
+
it("should render a blank placeholder while waiting for the coValue to load", async () => {
|
17
17
|
const { container } = render(
|
18
18
|
<Image imageId="co_zMTubMby3QiKDYnW9e2BEXW7Xaq" alt="test" />,
|
19
19
|
{ account },
|
20
20
|
);
|
21
|
+
|
21
22
|
const img = container.querySelector("img");
|
22
23
|
expect(img).toBeDefined();
|
23
24
|
expect(img!.getAttribute("width")).toBe(null);
|
24
25
|
expect(img!.getAttribute("height")).toBe(null);
|
25
26
|
expect(img!.alt).toBe("test");
|
26
|
-
expect(img!.src).toBe(
|
27
|
+
expect(img!.src).toBe(
|
28
|
+
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==",
|
29
|
+
);
|
30
|
+
});
|
31
|
+
|
32
|
+
it("should render nothing if coValue is not found", async () => {
|
33
|
+
const { container } = render(
|
34
|
+
<Image imageId="co_zMTubMby3QiKDYnW9e2BEXW7Xaq" alt="test" />,
|
35
|
+
{ account },
|
36
|
+
);
|
37
|
+
await waitFor(() => {
|
38
|
+
const img = container.querySelector("img");
|
39
|
+
expect(img).toBeDefined();
|
40
|
+
expect(img!.getAttribute("width")).toBe(null);
|
41
|
+
expect(img!.getAttribute("height")).toBe(null);
|
42
|
+
expect(img!.alt).toBe("test");
|
43
|
+
expect(img!.src).toBe("");
|
44
|
+
});
|
27
45
|
});
|
28
46
|
|
29
47
|
it("should render an empty image if the image is not loaded yet", async () => {
|
@@ -69,7 +69,10 @@ export const Image = forwardRef<RNImage, ImageProps>(function Image(
|
|
69
69
|
ref,
|
70
70
|
) {
|
71
71
|
const image = useCoState(ImageDefinition, imageId);
|
72
|
-
const [src, setSrc] = useState<string | undefined>(
|
72
|
+
const [src, setSrc] = useState<string | undefined>(
|
73
|
+
image?.placeholderDataURL ??
|
74
|
+
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==",
|
75
|
+
);
|
73
76
|
|
74
77
|
const dimensions: { width: number | undefined; height: number | undefined } =
|
75
78
|
useMemo(() => {
|