jazz-tools 0.18.2 → 0.18.3

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 (52) hide show
  1. package/.turbo/turbo-build.log +46 -44
  2. package/CHANGELOG.md +10 -0
  3. package/dist/media/{chunk-KR2V6X2N.js → chunk-W3S526L3.js} +96 -93
  4. package/dist/media/chunk-W3S526L3.js.map +1 -0
  5. package/dist/media/create-image/browser.d.ts +43 -0
  6. package/dist/media/create-image/browser.d.ts.map +1 -0
  7. package/dist/media/create-image/react-native.d.ts +37 -0
  8. package/dist/media/create-image/react-native.d.ts.map +1 -0
  9. package/dist/media/create-image/server.d.ts +34 -0
  10. package/dist/media/create-image/server.d.ts.map +1 -0
  11. package/dist/media/create-image/server.test.d.ts +2 -0
  12. package/dist/media/create-image/server.test.d.ts.map +1 -0
  13. package/dist/media/{create-image.d.ts → create-image-factory.d.ts} +8 -7
  14. package/dist/media/create-image-factory.d.ts.map +1 -0
  15. package/dist/media/create-image-factory.test.d.ts +2 -0
  16. package/dist/media/create-image-factory.test.d.ts.map +1 -0
  17. package/dist/media/exports.d.ts +3 -0
  18. package/dist/media/exports.d.ts.map +1 -0
  19. package/dist/media/index.browser.d.ts +2 -14
  20. package/dist/media/index.browser.d.ts.map +1 -1
  21. package/dist/media/index.browser.js +11 -20
  22. package/dist/media/index.browser.js.map +1 -1
  23. package/dist/media/index.d.ts +12 -4
  24. package/dist/media/index.d.ts.map +1 -1
  25. package/dist/media/index.js +1 -1
  26. package/dist/media/index.native.d.ts +2 -16
  27. package/dist/media/index.native.d.ts.map +1 -1
  28. package/dist/media/index.native.js +23 -42
  29. package/dist/media/index.native.js.map +1 -1
  30. package/dist/media/index.server.d.ts +3 -0
  31. package/dist/media/index.server.d.ts.map +1 -0
  32. package/dist/media/index.server.js +103 -0
  33. package/dist/media/index.server.js.map +1 -0
  34. package/dist/react/index.js +7 -7
  35. package/dist/react/index.js.map +1 -1
  36. package/package.json +27 -11
  37. package/src/media/create-image/browser.ts +161 -0
  38. package/src/media/create-image/react-native.ts +158 -0
  39. package/src/media/create-image/server.test.ts +74 -0
  40. package/src/media/create-image/server.ts +181 -0
  41. package/src/media/{create-image.test.ts → create-image-factory.test.ts} +1 -1
  42. package/src/media/{create-image.ts → create-image-factory.ts} +22 -12
  43. package/src/media/exports.ts +2 -0
  44. package/src/media/index.browser.ts +2 -150
  45. package/src/media/index.native.ts +2 -166
  46. package/src/media/index.server.ts +2 -0
  47. package/src/media/index.ts +16 -8
  48. package/tsup.config.ts +1 -0
  49. package/dist/media/chunk-KR2V6X2N.js.map +0 -1
  50. package/dist/media/create-image.d.ts.map +0 -1
  51. package/dist/media/create-image.test.d.ts +0 -2
  52. package/dist/media/create-image.test.d.ts.map +0 -1
@@ -1,12 +1,12 @@
1
1
 
2
- > jazz-tools@0.18.2 build /home/runner/_work/jazz/jazz/packages/jazz-tools
2
+ > jazz-tools@0.18.3 build /home/runner/_work/jazz/jazz/packages/jazz-tools
3
3
  > tsup && pnpm types && pnpm build:svelte
4
4
 
5
5
  CLI Building entry: {"index":"src/index.ts","testing":"src/testing.ts"}
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI Building entry: {"index":"src/browser/index.ts"}
8
8
  CLI Using tsconfig: tsconfig.json
9
- CLI Building entry: {"index":"src/media/index.ts","index.browser":"src/media/index.browser.ts","index.native":"src/media/index.native.ts"}
9
+ CLI Building entry: {"index":"src/media/index.ts","index.browser":"src/media/index.browser.ts","index.native":"src/media/index.native.ts","index.server":"src/media/index.server.ts"}
10
10
  CLI Using tsconfig: tsconfig.json
11
11
  CLI Building entry: {"index":"src/expo/index.ts","testing":"src/expo/testing.ts","crypto":"src/expo/crypto.ts"}
12
12
  CLI Using tsconfig: tsconfig.json
@@ -107,91 +107,93 @@
107
107
  ESM Build start
108
108
  CLI Cleaning output folder
109
109
  ESM Build start
110
+ ESM dist/worker/index.js 2.33 KB
111
+ ESM dist/worker/index.js.map 4.79 KB
112
+ ESM ⚡️ Build success in 17ms
110
113
  ESM dist/tiptap/index.js 564.00 B
111
114
  ESM dist/tiptap/index.js.map 1.21 KB
112
- ESM ⚡️ Build success in 10ms
115
+ ESM ⚡️ Build success in 19ms
113
116
  ESM dist/react/ssr.js 688.00 B
114
117
  ESM dist/react/ssr.js.map 1.12 KB
115
- ESM ⚡️ Build success in 17ms
116
- ESM dist/worker/index.js 2.33 KB
117
- ESM dist/worker/index.js.map 4.79 KB
118
- ESM ⚡️ Build success in 15ms
119
- ESM dist/media/index.js 236.00 B
120
- ESM dist/media/index.browser.js 3.21 KB
121
- ESM dist/media/index.native.js 3.53 KB
122
- ESM dist/media/chunk-KR2V6X2N.js 6.42 KB
123
- ESM dist/media/index.js.map 71.00 B
124
- ESM dist/media/index.browser.js.map 6.02 KB
125
- ESM dist/media/index.native.js.map 6.52 KB
126
- ESM dist/media/chunk-KR2V6X2N.js.map 16.19 KB
127
118
  ESM ⚡️ Build success in 21ms
128
119
  ESM dist/better-auth/auth/client.js 4.36 KB
129
- ESM dist/better-auth/auth/react.js 1.19 KB
130
120
  ESM dist/better-auth/auth/server.js 5.94 KB
121
+ ESM dist/better-auth/auth/react.js 1.19 KB
131
122
  ESM dist/better-auth/auth/client.js.map 8.12 KB
132
- ESM dist/better-auth/auth/react.js.map 3.37 KB
133
123
  ESM dist/better-auth/auth/server.js.map 10.66 KB
134
- ESM ⚡️ Build success in 16ms
135
- ESM dist/expo/index.js 4.68 KB
136
- ESM dist/expo/testing.js 112.00 B
137
- ESM dist/expo/crypto.js 153.00 B
138
- ESM dist/expo/index.js.map 10.23 KB
139
- ESM dist/expo/testing.js.map 168.00 B
140
- ESM dist/expo/crypto.js.map 189.00 B
141
- ESM ⚡️ Build success in 24ms
124
+ ESM dist/better-auth/auth/react.js.map 3.37 KB
125
+ ESM ⚡️ Build success in 19ms
126
+ ESM dist/media/index.js 236.00 B
127
+ ESM dist/media/index.browser.js 2.79 KB
128
+ ESM dist/media/index.native.js 2.90 KB
129
+ ESM dist/media/index.server.js 2.95 KB
130
+ ESM dist/media/chunk-W3S526L3.js 6.47 KB
131
+ ESM dist/media/index.js.map 71.00 B
132
+ ESM dist/media/index.browser.js.map 6.15 KB
133
+ ESM dist/media/index.native.js.map 6.09 KB
134
+ ESM dist/media/index.server.js.map 6.37 KB
135
+ ESM dist/media/chunk-W3S526L3.js.map 16.57 KB
136
+ ESM ⚡️ Build success in 28ms
142
137
  ESM dist/react-native/index.js 2.53 KB
143
138
  ESM dist/react-native/testing.js 120.00 B
144
139
  ESM dist/react-native/crypto.js 161.00 B
145
140
  ESM dist/react-native/index.js.map 5.68 KB
146
141
  ESM dist/react-native/testing.js.map 176.00 B
147
142
  ESM dist/react-native/crypto.js.map 197.00 B
148
- ESM ⚡️ Build success in 22ms
143
+ ESM ⚡️ Build success in 29ms
149
144
  ESM dist/browser/index.js 13.44 KB
150
145
  ESM dist/browser/index.js.map 28.70 KB
151
- ESM ⚡️ Build success in 31ms
146
+ ESM ⚡️ Build success in 36ms
147
+ ESM dist/expo/index.js 4.68 KB
148
+ ESM dist/expo/testing.js 112.00 B
149
+ ESM dist/expo/crypto.js 153.00 B
150
+ ESM dist/expo/index.js.map 10.23 KB
151
+ ESM dist/expo/testing.js.map 168.00 B
152
+ ESM dist/expo/crypto.js.map 189.00 B
153
+ ESM ⚡️ Build success in 36ms
152
154
  ESM dist/react-native-core/index.js 17.90 KB
153
155
  ESM dist/react-native-core/testing.js 119.00 B
154
156
  ESM dist/react-native-core/crypto.js 2.10 KB
155
157
  ESM dist/react-native-core/index.js.map 36.66 KB
156
- ESM dist/react-native-core/testing.js.map 175.00 B
157
158
  ESM dist/react-native-core/crypto.js.map 4.25 KB
158
- ESM ⚡️ Build success in 30ms
159
- ESM dist/react/index.js 24.66 KB
159
+ ESM dist/react-native-core/testing.js.map 175.00 B
160
+ ESM ⚡️ Build success in 37ms
160
161
  ESM dist/react/testing.js 122.00 B
161
- ESM dist/react/index.js.map 53.09 KB
162
+ ESM dist/react/index.js 24.66 KB
162
163
  ESM dist/react/testing.js.map 165.00 B
163
- ESM ⚡️ Build success in 39ms
164
+ ESM dist/react/index.js.map 53.43 KB
165
+ ESM ⚡️ Build success in 42ms
164
166
  ESM dist/prosemirror/index.js 77.63 KB
165
167
  ESM dist/prosemirror/index.js.map 306.98 KB
166
- ESM ⚡️ Build success in 40ms
168
+ ESM ⚡️ Build success in 47ms
167
169
  ESM dist/inspector/index.js 61.52 KB
168
170
  ESM dist/inspector/index.js.map 109.98 KB
169
- ESM ⚡️ Build success in 58ms
170
- ESM dist/index.js 26.13 KB
171
+ ESM ⚡️ Build success in 57ms
171
172
  ESM dist/testing.js 7.17 KB
173
+ ESM dist/index.js 26.13 KB
172
174
  ESM dist/chunk-IERUTUXB.js 163.90 KB
173
- ESM dist/index.js.map 52.92 KB
174
175
  ESM dist/testing.js.map 14.10 KB
176
+ ESM dist/index.js.map 52.92 KB
175
177
  ESM dist/chunk-IERUTUXB.js.map 389.03 KB
176
- ESM ⚡️ Build success in 78ms
177
- ESM dist/react-core/chunk-7DYMJ74I.js 279.00 B
178
- ESM dist/react-core/testing.js 1.17 KB
178
+ ESM ⚡️ Build success in 79ms
179
179
  ESM dist/react-core/index.js 141.07 KB
180
- ESM dist/react-core/chunk-7DYMJ74I.js.map 533.00 B
180
+ ESM dist/react-core/testing.js 1.17 KB
181
+ ESM dist/react-core/chunk-7DYMJ74I.js 279.00 B
181
182
  ESM dist/react-core/testing.js.map 1.82 KB
183
+ ESM dist/react-core/chunk-7DYMJ74I.js.map 533.00 B
182
184
  ESM dist/react-core/index.js.map 383.45 KB
183
- ESM ⚡️ Build success in 75ms
185
+ ESM ⚡️ Build success in 78ms
184
186
  ESM dist/inspector/register-custom-element.js 218.00 B
185
187
  ESM dist/inspector/register-custom-element.js.map 314.00 B
186
188
  ESM dist/inspector/custom-element-WCY6D3QJ.js 1.53 MB
187
189
  ESM dist/inspector/custom-element-WCY6D3QJ.js.map 2.35 MB
188
- ESM ⚡️ Build success in 106ms
190
+ ESM ⚡️ Build success in 112ms
189
191
 
190
- > jazz-tools@0.18.2 types /home/runner/_work/jazz/jazz/packages/jazz-tools
192
+ > jazz-tools@0.18.3 types /home/runner/_work/jazz/jazz/packages/jazz-tools
191
193
  > tsc --outDir dist
192
194
 
193
195
 
194
- > jazz-tools@0.18.2 build:svelte /home/runner/_work/jazz/jazz/packages/jazz-tools
196
+ > jazz-tools@0.18.3 build:svelte /home/runner/_work/jazz/jazz/packages/jazz-tools
195
197
  > rm -rf dist/svelte && svelte-package -i src/svelte -o dist/svelte --tsconfig tsconfig.svelte.json
196
198
 
197
199
  src/svelte -> dist/svelte
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # jazz-tools
2
2
 
3
+ ## 0.18.3
4
+
5
+ ### Patch Changes
6
+
7
+ - b526ab6: Set 18.x as latest
8
+ - d69aa68: Added a server implementation of `createImage()` to create images in server environments using the "sharp" library
9
+ - cojson@0.18.3
10
+ - cojson-storage-indexeddb@0.18.3
11
+ - cojson-transport-ws@0.18.3
12
+
3
13
  ## 0.18.2
4
14
 
5
15
  ### Patch Changes
@@ -1,89 +1,5 @@
1
- // src/media/create-image.ts
2
- import {
3
- ImageDefinition
4
- } from "jazz-tools";
5
- function createImageFactory(impl) {
6
- return (source, options) => createImage(source, options, impl);
7
- }
8
- async function createImage(imageBlobOrFile, options, impl) {
9
- const { width: originalWidth, height: originalHeight } = await impl.getImageSize(imageBlobOrFile);
10
- const def = {
11
- originalSize: [originalWidth, originalHeight],
12
- progressive: false,
13
- placeholderDataURL: void 0,
14
- files: {}
15
- };
16
- if (options?.placeholder === "blur") {
17
- def.placeholderDataURL = await impl.getPlaceholderBase64(imageBlobOrFile);
18
- }
19
- if (options?.maxSize === void 0) {
20
- def.original = await impl.createFileStreamFromSource(
21
- imageBlobOrFile,
22
- options?.owner
23
- );
24
- def.files[`${originalWidth}x${originalHeight}`] = def.original;
25
- } else if (options?.maxSize >= originalWidth && options?.maxSize >= originalHeight) {
26
- def.original = await impl.createFileStreamFromSource(
27
- imageBlobOrFile,
28
- options?.owner
29
- );
30
- def.files[`${originalWidth}x${originalHeight}`] = def.original;
31
- } else {
32
- const { width, height } = getNewDimensions(
33
- originalWidth,
34
- originalHeight,
35
- options.maxSize
36
- );
37
- const blob = await impl.resize(imageBlobOrFile, width, height);
38
- def.originalSize = [width, height];
39
- def.original = await impl.createFileStreamFromSource(blob, options?.owner);
40
- def.files[`${width}x${height}`] = def.original;
41
- }
42
- const imageCoValue = ImageDefinition.create(
43
- {
44
- originalSize: def.originalSize,
45
- progressive: def.progressive,
46
- placeholderDataURL: def.placeholderDataURL,
47
- original: def.original,
48
- ...def.files
49
- },
50
- options?.owner
51
- );
52
- if (options?.progressive) {
53
- imageCoValue.$jazz.set("progressive", true);
54
- const resizes = [256, 1024, 2048].filter(
55
- (s) => s < Math.max(imageCoValue.originalSize[0], imageCoValue.originalSize[1])
56
- );
57
- for (const size of resizes) {
58
- const { width, height } = getNewDimensions(
59
- originalWidth,
60
- originalHeight,
61
- size
62
- );
63
- const blob = await impl.resize(imageBlobOrFile, width, height);
64
- imageCoValue.$jazz.set(
65
- `${width}x${height}`,
66
- await impl.createFileStreamFromSource(blob, options?.owner)
67
- );
68
- }
69
- }
70
- return imageCoValue;
71
- }
72
- var getNewDimensions = (originalWidth, originalHeight, maxSize) => {
73
- if (originalWidth > originalHeight) {
74
- return {
75
- width: maxSize,
76
- height: Math.round(maxSize * (originalHeight / originalWidth))
77
- };
78
- }
79
- return {
80
- width: Math.round(maxSize * (originalWidth / originalHeight)),
81
- height: maxSize
82
- };
83
- };
84
-
85
1
  // src/media/utils.ts
86
- import { Account as Account2, FileStream as FileStream2, ImageDefinition as ImageDefinition2 } from "jazz-tools";
2
+ import { Account, FileStream, ImageDefinition } from "jazz-tools";
87
3
  function highestResAvailable(image, wantedWidth, wantedHeight) {
88
4
  const availableSizes = image.$jazz.raw.keys().filter((key) => /^\d+x\d+$/.test(key)).map((key) => {
89
5
  const [w, h] = key.split("x").map(Number);
@@ -139,11 +55,11 @@ function isLoaded(id) {
139
55
  if (!id) {
140
56
  return false;
141
57
  }
142
- return !!Account2.getMe().$jazz.localNode.getLoaded(id);
58
+ return !!Account.getMe().$jazz.localNode.getLoaded(id);
143
59
  }
144
60
  async function loadImage(imageOrId) {
145
61
  if (typeof imageOrId === "string") {
146
- const image = await ImageDefinition2.load(imageOrId, {
62
+ const image = await ImageDefinition.load(imageOrId, {
147
63
  resolve: {
148
64
  original: true
149
65
  }
@@ -161,7 +77,7 @@ async function loadImage(imageOrId) {
161
77
  console.warn("Unable to find the original image");
162
78
  return null;
163
79
  }
164
- const loadedOriginal = await FileStream2.load(imageOrId.original.$jazz.id);
80
+ const loadedOriginal = await FileStream.load(imageOrId.original.$jazz.id);
165
81
  if (!loadedOriginal) {
166
82
  console.warn("Unable to find the original image");
167
83
  return null;
@@ -173,7 +89,7 @@ async function loadImage(imageOrId) {
173
89
  };
174
90
  }
175
91
  async function loadImageBySize(imageOrId, wantedWidth, wantedHeight) {
176
- const image = typeof imageOrId === "string" ? await ImageDefinition2.load(imageOrId) : imageOrId;
92
+ const image = typeof imageOrId === "string" ? await ImageDefinition.load(imageOrId) : imageOrId;
177
93
  if (image === null) {
178
94
  return null;
179
95
  }
@@ -196,7 +112,7 @@ async function loadImageBySize(imageOrId, wantedWidth, wantedHeight) {
196
112
  if (!file) {
197
113
  return null;
198
114
  }
199
- const loadedFile = await FileStream2.load(file.id);
115
+ const loadedFile = await FileStream.load(file.id);
200
116
  if (!loadedFile) {
201
117
  return null;
202
118
  }
@@ -207,10 +123,97 @@ async function loadImageBySize(imageOrId, wantedWidth, wantedHeight) {
207
123
  };
208
124
  }
209
125
 
126
+ // src/media/create-image-factory.ts
127
+ import {
128
+ ImageDefinition as ImageDefinition2
129
+ } from "jazz-tools";
130
+ function createImageFactory(impl, imageTypeGuard) {
131
+ return (source, options) => {
132
+ imageTypeGuard?.(source);
133
+ return createImage(source, options ?? {}, impl);
134
+ };
135
+ }
136
+ async function createImage(imageBlobOrFile, options, impl) {
137
+ const { width: originalWidth, height: originalHeight } = await impl.getImageSize(imageBlobOrFile);
138
+ const def = {
139
+ originalSize: [originalWidth, originalHeight],
140
+ progressive: false,
141
+ placeholderDataURL: void 0,
142
+ files: {}
143
+ };
144
+ if (options?.placeholder === "blur") {
145
+ def.placeholderDataURL = await impl.getPlaceholderBase64(imageBlobOrFile);
146
+ }
147
+ if (options?.maxSize === void 0) {
148
+ def.original = await impl.createFileStreamFromSource(
149
+ imageBlobOrFile,
150
+ options?.owner
151
+ );
152
+ def.files[`${originalWidth}x${originalHeight}`] = def.original;
153
+ } else if (options?.maxSize >= originalWidth && options?.maxSize >= originalHeight) {
154
+ def.original = await impl.createFileStreamFromSource(
155
+ imageBlobOrFile,
156
+ options?.owner
157
+ );
158
+ def.files[`${originalWidth}x${originalHeight}`] = def.original;
159
+ } else {
160
+ const { width, height } = getNewDimensions(
161
+ originalWidth,
162
+ originalHeight,
163
+ options.maxSize
164
+ );
165
+ const blob = await impl.resize(imageBlobOrFile, width, height);
166
+ def.originalSize = [width, height];
167
+ def.original = await impl.createFileStreamFromSource(blob, options?.owner);
168
+ def.files[`${width}x${height}`] = def.original;
169
+ }
170
+ const imageCoValue = ImageDefinition2.create(
171
+ {
172
+ originalSize: def.originalSize,
173
+ progressive: def.progressive,
174
+ placeholderDataURL: def.placeholderDataURL,
175
+ original: def.original,
176
+ ...def.files
177
+ },
178
+ options?.owner
179
+ );
180
+ if (options?.progressive) {
181
+ imageCoValue.$jazz.set("progressive", true);
182
+ const resizes = [256, 1024, 2048].filter(
183
+ (s) => s < Math.max(imageCoValue.originalSize[0], imageCoValue.originalSize[1])
184
+ );
185
+ for (const size of resizes) {
186
+ const { width, height } = getNewDimensions(
187
+ originalWidth,
188
+ originalHeight,
189
+ size
190
+ );
191
+ const blob = await impl.resize(imageBlobOrFile, width, height);
192
+ imageCoValue.$jazz.set(
193
+ `${width}x${height}`,
194
+ await impl.createFileStreamFromSource(blob, options?.owner)
195
+ );
196
+ }
197
+ }
198
+ return imageCoValue;
199
+ }
200
+ var getNewDimensions = (originalWidth, originalHeight, maxSize) => {
201
+ if (originalWidth > originalHeight) {
202
+ return {
203
+ width: maxSize,
204
+ height: Math.round(maxSize * (originalHeight / originalWidth))
205
+ };
206
+ }
207
+ return {
208
+ width: Math.round(maxSize * (originalWidth / originalHeight)),
209
+ height: maxSize
210
+ };
211
+ };
212
+
210
213
  export {
211
- createImageFactory,
212
214
  highestResAvailable,
213
215
  loadImage,
214
- loadImageBySize
216
+ loadImageBySize,
217
+ createImageFactory
215
218
  };
216
- //# sourceMappingURL=chunk-KR2V6X2N.js.map
219
+ //# sourceMappingURL=chunk-W3S526L3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/media/utils.ts","../../src/media/create-image-factory.ts"],"sourcesContent":["import type { CoID } from \"cojson\";\nimport { Account, FileStream, ImageDefinition } from \"jazz-tools\";\n\nexport function highestResAvailable(\n image: ImageDefinition,\n wantedWidth: number,\n wantedHeight: number,\n): { width: number; height: number; image: FileStream } | null {\n const availableSizes: [number, number, string][] = image.$jazz.raw\n .keys()\n .filter((key) => /^\\d+x\\d+$/.test(key))\n .map((key) => {\n const [w, h] = key.split(\"x\").map(Number) as [number, number];\n return [w, h, key];\n });\n\n if (availableSizes.length === 0) {\n return image.original\n ? {\n width: image.originalSize[0],\n height: image.originalSize[1],\n image: image.original,\n }\n : null;\n }\n\n const sortedSizes = availableSizes\n .map((size) => {\n return {\n size,\n match: sizesMatchWanted(size[0], size[1], wantedWidth, wantedHeight),\n isLoaded: isLoaded(\n image.$jazz.raw.get(size[2]) as CoID<any> | undefined,\n ),\n };\n })\n .sort((a, b) => a.match - b.match);\n\n // We try to find the better already loaded image\n // note: `toReversed` is not available in react-native.\n const bestLoaded = [...sortedSizes]\n .reverse()\n .find((el) => el.isLoaded && image[el.size[2]]?.getChunks());\n\n // if I can't find a good match, let's use the highest resolution\n const bestTarget =\n sortedSizes.find((el) => el.match > 0.95) || sortedSizes.at(-1);\n\n // if the best target is already loaded, we are done\n if (image[bestTarget!.size[2]]?.getChunks()) {\n return image[bestTarget!.size[2]]\n ? {\n width: bestTarget!.size[0],\n height: bestTarget!.size[1],\n image: image[bestTarget!.size[2]]!,\n }\n : null;\n }\n\n // if the best already loaded is not the best target\n // let's trigger the load of the best target\n if (bestLoaded) {\n image[bestTarget!.size[2]]?.getChunks();\n return image[bestLoaded.size[2]]\n ? {\n width: bestLoaded.size[0],\n height: bestLoaded.size[1],\n image: image[bestLoaded.size[2]]!,\n }\n : null;\n }\n\n // if nothing is loaded, then start fetching all the images till the best\n for (let size of sortedSizes) {\n if (size.match <= bestTarget!.match) {\n image[size.size[2]]?.getChunks();\n }\n }\n\n return null;\n}\n\nfunction sizesMatchWanted(\n w: number,\n h: number,\n wantedW: number,\n wantedH: number,\n): number {\n const area1 = w * h;\n const area2 = wantedW * wantedH;\n\n const areaRatio = area1 / area2;\n\n // // Below 0.95 means the image is too small, we don't want to upscale it\n // if (areaRatio < 0.95) {\n // return 9999;\n // }\n\n return areaRatio;\n}\n\nfunction isLoaded(id: CoID<any> | null | undefined): boolean {\n if (!id) {\n return false;\n }\n\n return !!Account.getMe().$jazz.localNode.getLoaded(id);\n}\n\nexport async function loadImage(\n imageOrId: ImageDefinition | string,\n): Promise<{ width: number; height: number; image: FileStream } | null> {\n if (typeof imageOrId === \"string\") {\n const image = await ImageDefinition.load(imageOrId, {\n resolve: {\n original: true,\n },\n });\n\n if (image === null || image.original === null) {\n return null;\n }\n\n return {\n width: image.originalSize[0],\n height: image.originalSize[1],\n image: image.original,\n };\n }\n\n if (!imageOrId.original) {\n console.warn(\"Unable to find the original image\");\n return null;\n }\n\n const loadedOriginal = await FileStream.load(imageOrId.original.$jazz.id);\n\n if (!loadedOriginal) {\n console.warn(\"Unable to find the original image\");\n return null;\n }\n\n return {\n width: imageOrId.originalSize[0],\n height: imageOrId.originalSize[1],\n image: loadedOriginal,\n };\n}\n\nexport async function loadImageBySize(\n imageOrId: ImageDefinition | string,\n wantedWidth: number,\n wantedHeight: number,\n): Promise<{ width: number; height: number; image: FileStream } | null> {\n // @ts-expect-error The resolved type for CoMap does not include catchall properties\n const image: ImageDefinition | null =\n typeof imageOrId === \"string\"\n ? await ImageDefinition.load(imageOrId)\n : imageOrId;\n\n if (image === null) {\n return null;\n }\n\n if (image.progressive === false) {\n return loadImage(imageOrId);\n }\n\n const availableSizes: [number, number, string][] = image.$jazz.raw\n .keys()\n .filter((key) => /^\\d+x\\d+$/.test(key))\n .map((key) => {\n const [w, h] = key.split(\"x\").map(Number) as [number, number];\n return [w, h, key];\n });\n\n if (availableSizes.length === 0) {\n return null;\n }\n\n const sortedSizes = availableSizes\n .map((size) => ({\n size,\n match: sizesMatchWanted(size[0], size[1], wantedWidth, wantedHeight),\n }))\n .sort((a, b) => a.match - b.match);\n\n const bestTarget =\n sortedSizes.find((el) => el.match > 0.95) || sortedSizes.at(-1)!;\n\n // The image's `wxh` keys reference FileStream.\n // image[bestTarget.size[2]] returns undefined if FileStream hasn't loaded yet.\n // Since we only need the file's ID to fetch it later, we check the raw _refs\n // which contain only the linked covalue's ID.\n const file = image.$jazz.refs[bestTarget.size[2]];\n\n if (!file) {\n return null;\n }\n\n const loadedFile = await FileStream.load(file.id);\n\n if (!loadedFile) {\n return null;\n }\n\n return {\n width: bestTarget.size[0],\n height: bestTarget.size[1],\n image: loadedFile,\n };\n}\n","import {\n Account,\n FileStream,\n Group,\n ImageDefinition,\n type Loaded,\n} from \"jazz-tools\";\n\nexport type SourceType = Blob | File | string;\n\nexport type ResizeOutput = Blob | string;\n\nexport type CreateImageOptions = {\n /** The owner of the image. Can be either a Group or Account. If not specified, the current user will be the owner. */\n owner?: Group | Account;\n /**\n * Controls placeholder generation for the image.\n * - `\"blur\"`: Generates a blurred placeholder image (default)\n * - `false`: No placeholder is generated\n * @default \"blur\"\n */\n placeholder?: \"blur\" | false;\n /**\n * Maximum size constraint for the image. The image will be resized to fit within this size while maintaining aspect ratio.\n * If the image is smaller than maxSize in both dimensions, no resizing occurs.\n * @example 1024 // Resizes image to fit within 1024px in the largest dimension\n */\n maxSize?: number; // | [number, number];\n /**\n * The progressive loading pattern is a technique that allows images to load incrementally, starting with a small version and gradually replacing it with a larger version as it becomes available.\n * This is useful for improving the user experience by showing a placeholder while the image is loading.\n *\n * Passing progressive: true to createImage() will create internal smaller versions of the image for future uses.\n *\n * @default false\n */\n progressive?: boolean;\n};\n\nexport type CreateImageImpl<\n TSourceType = SourceType,\n TResizeOutput = ResizeOutput,\n> = {\n createFileStreamFromSource: (\n imageBlobOrFile: TSourceType | TResizeOutput,\n owner?: Group | Account,\n ) => Promise<FileStream>;\n getImageSize: (\n imageBlobOrFile: TSourceType,\n ) => Promise<{ width: number; height: number }>;\n getPlaceholderBase64: (imageBlobOrFile: TSourceType) => Promise<string>;\n resize: (\n imageBlobOrFile: TSourceType,\n width: number,\n height: number,\n ) => Promise<TResizeOutput>;\n};\n\nexport function createImageFactory<TSourceType, TResizeOutput>(\n impl: CreateImageImpl<TSourceType, TResizeOutput>,\n imageTypeGuard?: (imageBlobOrFile: TSourceType) => void,\n) {\n return (source: TSourceType, options?: CreateImageOptions) => {\n imageTypeGuard?.(source);\n return createImage(source, options ?? {}, impl);\n };\n}\n\nasync function createImage<TSourceType, TResizeOutput>(\n imageBlobOrFile: TSourceType,\n options: CreateImageOptions,\n impl: CreateImageImpl<TSourceType, TResizeOutput>,\n): Promise<Loaded<typeof ImageDefinition, { $each: true }>> {\n // Get the original size of the image\n const { width: originalWidth, height: originalHeight } =\n await impl.getImageSize(imageBlobOrFile);\n\n const def: {\n originalSize: [number, number];\n progressive: boolean;\n placeholderDataURL: string | undefined;\n original?: FileStream;\n files: Record<string, FileStream>;\n } = {\n originalSize: [originalWidth, originalHeight],\n progressive: false,\n placeholderDataURL: undefined,\n files: {},\n };\n\n // Placeholder\n if (options?.placeholder === \"blur\") {\n def.placeholderDataURL = await impl.getPlaceholderBase64(imageBlobOrFile);\n }\n\n /**\n * Original\n *\n * Save the original image.\n * If the maxSize is set, resize the image to the maxSize if needed\n */\n if (options?.maxSize === undefined) {\n def.original = await impl.createFileStreamFromSource(\n imageBlobOrFile,\n options?.owner,\n );\n def.files[`${originalWidth}x${originalHeight}`] = def.original;\n } else if (\n options?.maxSize >= originalWidth &&\n options?.maxSize >= originalHeight\n ) {\n // no resizes required, just return the original image\n def.original = await impl.createFileStreamFromSource(\n imageBlobOrFile,\n options?.owner,\n );\n def.files[`${originalWidth}x${originalHeight}`] = def.original;\n } else {\n const { width, height } = getNewDimensions(\n originalWidth,\n originalHeight,\n options.maxSize,\n );\n\n const blob = await impl.resize(imageBlobOrFile, width, height);\n def.originalSize = [width, height];\n def.original = await impl.createFileStreamFromSource(blob, options?.owner);\n def.files[`${width}x${height}`] = def.original;\n }\n\n const imageCoValue = ImageDefinition.create(\n {\n originalSize: def.originalSize,\n progressive: def.progressive,\n placeholderDataURL: def.placeholderDataURL,\n original: def.original,\n ...def.files,\n },\n options?.owner,\n );\n\n /**\n * Progressive loading\n *\n * Save a set of resized images using three sizes: 256, 1024, 2048\n *\n * On the client side, the image will be loaded progressively, starting from the smallest size and increasing the size until the original size is reached.\n */\n if (options?.progressive) {\n imageCoValue.$jazz.set(\"progressive\", true);\n\n const resizes = ([256, 1024, 2048] as const).filter(\n (s) =>\n s <\n Math.max(imageCoValue.originalSize[0], imageCoValue.originalSize[1]),\n );\n\n for (const size of resizes) {\n const { width, height } = getNewDimensions(\n originalWidth,\n originalHeight,\n size,\n );\n\n const blob = await impl.resize(imageBlobOrFile, width, height);\n imageCoValue.$jazz.set(\n `${width}x${height}`,\n await impl.createFileStreamFromSource(blob, options?.owner),\n );\n }\n }\n\n return imageCoValue;\n}\n\nconst getNewDimensions = (\n originalWidth: number,\n originalHeight: number,\n maxSize: number,\n) => {\n if (originalWidth > originalHeight) {\n return {\n width: maxSize,\n height: Math.round(maxSize * (originalHeight / originalWidth)),\n };\n }\n\n return {\n width: Math.round(maxSize * (originalWidth / originalHeight)),\n height: maxSize,\n };\n};\n"],"mappings":"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","names":["ImageDefinition"]}
@@ -0,0 +1,43 @@
1
+ import { FileStream } from "jazz-tools";
2
+ /**
3
+ * Creates an ImageDefinition from an image File or Blob with built-in UX features.
4
+ *
5
+ * This function creates a specialized CoValue for managing images in Jazz applications.
6
+ * It supports blurry placeholders, built-in resizing, and progressive loading patterns.
7
+ *
8
+ * @returns Promise that resolves to an ImageDefinition
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { createImage } from "jazz-tools/media";
13
+ *
14
+ * // Create an image from a file input
15
+ * async function handleFileUpload(event: React.ChangeEvent<HTMLInputElement>) {
16
+ * const file = event.target.files?.[0];
17
+ * if (file) {
18
+ * // Creates ImageDefinition with a blurry placeholder, limited to 1024px
19
+ * // on the longest side, and multiple resolutions automatically
20
+ * const image = await createImage(file, {
21
+ * owner: me._owner,
22
+ * maxSize: 1024,
23
+ * placeholder: "blur",
24
+ * progressive: true,
25
+ * });
26
+ *
27
+ * // Store the image in your application data
28
+ * me.profile.image = image;
29
+ * }
30
+ * }
31
+ * ```
32
+ */
33
+ export declare const createImage: (source: Blob | File, options?: import("../create-image-factory").CreateImageOptions) => Promise<{
34
+ readonly [key: string]: FileStream;
35
+ } & {
36
+ readonly original: FileStream | null;
37
+ readonly originalSize: [number, number];
38
+ readonly placeholderDataURL: string | undefined;
39
+ readonly progressive: boolean;
40
+ } & {
41
+ readonly [key: string]: FileStream | null;
42
+ } & import("jazz-tools").CoMap>;
43
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/media/create-image/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,UAAU,EAAS,MAAM,YAAY,CAAC;AAGxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,WAAW;;;;;;;;;+BAYvB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { Account, Group } from "jazz-tools";
2
+ import { FileStream } from "jazz-tools";
3
+ /**
4
+ * Creates an ImageDefinition from an image file path with built-in UX features.
5
+ *
6
+ * This function creates a specialized CoValue for managing images in Jazz applications.
7
+ * It supports blurry placeholders, built-in resizing, and progressive loading patterns.
8
+ *
9
+ * @returns Promise that resolves to an ImageDefinition
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { createImage } from "jazz-tools/media";
14
+ *
15
+ * async function uploadImageFromCamera(imagePath: string) {
16
+ * const image = await createImage(imagePath, {
17
+ * maxSize: 800,
18
+ * placeholder: "blur",
19
+ * progressive: false,
20
+ * });
21
+ *
22
+ * return image;
23
+ * }
24
+ * ```
25
+ */
26
+ export declare const createImage: (source: string, options?: import("../create-image-factory").CreateImageOptions) => Promise<{
27
+ readonly [key: string]: FileStream;
28
+ } & {
29
+ readonly original: FileStream | null;
30
+ readonly originalSize: [number, number];
31
+ readonly placeholderDataURL: string | undefined;
32
+ readonly progressive: boolean;
33
+ } & {
34
+ readonly [key: string]: FileStream | null;
35
+ } & import("jazz-tools").CoMap>;
36
+ export declare function createFileStreamFromSource(filePath: string, owner?: Account | Group): Promise<FileStream>;
37
+ //# sourceMappingURL=react-native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-native.d.ts","sourceRoot":"","sources":["../../../src/media/create-image/react-native.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAMxC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,WAAW;;;;;;;;;+BAcvB,CAAC;AAwEF,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,GACtB,OAAO,CAAC,UAAU,CAAC,CAOrB"}
@@ -0,0 +1,34 @@
1
+ import { FileStream } from "jazz-tools";
2
+ export type SharpImageType = File | Blob | Buffer | ArrayBuffer | Uint8Array | Uint8ClampedArray | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array;
3
+ /**
4
+ * Creates an ImageDefinition from an image File, Blob or Buffer with built-in UX features.
5
+ *
6
+ * This function creates a specialized CoValue for managing images in Jazz applications.
7
+ * It supports blurry placeholders, built-in resizing, and progressive loading patterns.
8
+ *
9
+ * @returns Promise that resolves to an ImageDefinition
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import fs from "node:fs";
14
+ * import { createImage } from "jazz-tools/media";
15
+ *
16
+ * const imageBuffer = fs.readFileSync("path/to/image.jpg");
17
+ * const image = await createImage(imageBuffer, {
18
+ * maxSize: 800,
19
+ * placeholder: "blur",
20
+ * progressive: false,
21
+ * });
22
+ * ```
23
+ */
24
+ export declare const createImage: (source: SharpImageType, options?: import("../create-image-factory").CreateImageOptions) => Promise<{
25
+ readonly [key: string]: FileStream;
26
+ } & {
27
+ readonly original: FileStream | null;
28
+ readonly originalSize: [number, number];
29
+ readonly placeholderDataURL: string | undefined;
30
+ readonly progressive: boolean;
31
+ } & {
32
+ readonly [key: string]: FileStream | null;
33
+ } & import("jazz-tools").CoMap>;
34
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/media/create-image/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,UAAU,EAAS,MAAM,YAAY,CAAC;AAIxD,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,IAAI,GACJ,MAAM,GACN,WAAW,GACX,UAAU,GACV,iBAAiB,GACjB,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,YAAY,GACZ,YAAY,CAAC;AAYjB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,WAAW;;;;;;;;;+BAYvB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../../src/media/create-image/server.test.ts"],"names":[],"mappings":""}
@@ -1,5 +1,6 @@
1
1
  import { Account, FileStream, Group } from "jazz-tools";
2
2
  export type SourceType = Blob | File | string;
3
+ export type ResizeOutput = Blob | string;
3
4
  export type CreateImageOptions = {
4
5
  /** The owner of the image. Can be either a Group or Account. If not specified, the current user will be the owner. */
5
6
  owner?: Group | Account;
@@ -26,16 +27,16 @@ export type CreateImageOptions = {
26
27
  */
27
28
  progressive?: boolean;
28
29
  };
29
- export type CreateImageImpl = {
30
- createFileStreamFromSource: (imageBlobOrFile: SourceType, owner?: Group | Account) => Promise<FileStream>;
31
- getImageSize: (imageBlobOrFile: SourceType) => Promise<{
30
+ export type CreateImageImpl<TSourceType = SourceType, TResizeOutput = ResizeOutput> = {
31
+ createFileStreamFromSource: (imageBlobOrFile: TSourceType | TResizeOutput, owner?: Group | Account) => Promise<FileStream>;
32
+ getImageSize: (imageBlobOrFile: TSourceType) => Promise<{
32
33
  width: number;
33
34
  height: number;
34
35
  }>;
35
- getPlaceholderBase64: (imageBlobOrFile: SourceType) => Promise<string>;
36
- resize: (imageBlobOrFile: SourceType, width: number, height: number) => Promise<Blob | string>;
36
+ getPlaceholderBase64: (imageBlobOrFile: TSourceType) => Promise<string>;
37
+ resize: (imageBlobOrFile: TSourceType, width: number, height: number) => Promise<TResizeOutput>;
37
38
  };
38
- export declare function createImageFactory(impl: CreateImageImpl): (source: SourceType, options: CreateImageOptions) => Promise<{
39
+ export declare function createImageFactory<TSourceType, TResizeOutput>(impl: CreateImageImpl<TSourceType, TResizeOutput>, imageTypeGuard?: (imageBlobOrFile: TSourceType) => void): (source: TSourceType, options?: CreateImageOptions) => Promise<{
39
40
  readonly [key: string]: FileStream;
40
41
  } & {
41
42
  readonly original: FileStream | null;
@@ -45,4 +46,4 @@ export declare function createImageFactory(impl: CreateImageImpl): (source: Sour
45
46
  } & {
46
47
  readonly [key: string]: FileStream | null;
47
48
  } & import("jazz-tools").CoMap>;
48
- //# sourceMappingURL=create-image.d.ts.map
49
+ //# sourceMappingURL=create-image-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-image-factory.d.ts","sourceRoot":"","sources":["../../src/media/create-image-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,UAAU,EACV,KAAK,EAGN,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,MAAM,CAAC;AAEzC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,sHAAsH;IACtH,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC7B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,eAAe,CACzB,WAAW,GAAG,UAAU,EACxB,aAAa,GAAG,YAAY,IAC1B;IACF,0BAA0B,EAAE,CAC1B,eAAe,EAAE,WAAW,GAAG,aAAa,EAC5C,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,KACpB,OAAO,CAAC,UAAU,CAAC,CAAC;IACzB,YAAY,EAAE,CACZ,eAAe,EAAE,WAAW,KACzB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,oBAAoB,EAAE,CAAC,eAAe,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxE,MAAM,EAAE,CACN,eAAe,EAAE,WAAW,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,aAAa,CAAC,CAAC;CAC7B,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,aAAa,EAC3D,IAAI,EAAE,eAAe,CAAC,WAAW,EAAE,aAAa,CAAC,EACjD,cAAc,CAAC,EAAE,CAAC,eAAe,EAAE,WAAW,KAAK,IAAI,YAEvC,WAAW,YAAY,kBAAkB;;;;;;;;;gCAI1D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=create-image-factory.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-image-factory.test.d.ts","sourceRoot":"","sources":["../../src/media/create-image-factory.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export { highestResAvailable, loadImage, loadImageBySize } from "./utils.js";
2
+ export { createImageFactory } from "./create-image-factory";
3
+ //# sourceMappingURL=exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../src/media/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}