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,15 +1,3 @@
1
- import { FileStream } from "jazz-tools";
2
- import { CreateImageOptions, createImageFactory } from "./create-image.js";
3
- export { highestResAvailable, loadImage, loadImageBySize } from "./utils.js";
4
- export { createImageFactory };
5
- export declare function createImage(imageBlobOrFile: Blob | File | string, options?: CreateImageOptions): Promise<{
6
- readonly [key: string]: FileStream;
7
- } & {
8
- readonly original: FileStream | null;
9
- readonly originalSize: [number, number];
10
- readonly placeholderDataURL: string | undefined;
11
- readonly progressive: boolean;
12
- } & {
13
- readonly [key: string]: FileStream | null;
14
- } & import("jazz-tools").CoMap>;
1
+ export * from "./exports";
2
+ export { createImage } from "./create-image/browser";
15
3
  //# sourceMappingURL=index.browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../src/media/index.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,UAAU,EAA0B,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,wBAAsB,WAAW,CAC/B,eAAe,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACrC,OAAO,CAAC,EAAE,kBAAkB;;;;;;;;;gCAQ7B"}
1
+ {"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../src/media/index.browser.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
@@ -3,24 +3,24 @@ import {
3
3
  highestResAvailable,
4
4
  loadImage,
5
5
  loadImageBySize
6
- } from "./chunk-KR2V6X2N.js";
6
+ } from "./chunk-W3S526L3.js";
7
7
 
8
- // src/media/index.browser.ts
8
+ // src/media/create-image/browser.ts
9
9
  import { FileStream } from "jazz-tools";
10
- async function createImage(imageBlobOrFile, options) {
11
- return createImageFactory({
10
+ var createImage = createImageFactory(
11
+ {
12
12
  createFileStreamFromSource,
13
13
  getImageSize,
14
14
  getPlaceholderBase64,
15
15
  resize
16
- })(imageBlobOrFile, options || {});
17
- }
18
- async function createFileStreamFromSource(imageBlobOrFile, owner) {
19
- if (typeof imageBlobOrFile === "string") {
20
- throw new Error(
21
- "createFileStreamFromSource(string) is not supported on this platform"
22
- );
16
+ },
17
+ (imageBlobOrFile) => {
18
+ if (typeof imageBlobOrFile === "string") {
19
+ throw new Error("createImage(string) is not supported on this platform");
20
+ }
23
21
  }
22
+ );
23
+ async function createFileStreamFromSource(imageBlobOrFile, owner) {
24
24
  return FileStream.createFromBlob(imageBlobOrFile, owner);
25
25
  }
26
26
  function getImageFromBlob(blob) {
@@ -38,16 +38,10 @@ function getImageFromBlob(blob) {
38
38
  });
39
39
  }
40
40
  async function getImageSize(imageBlobOrFile) {
41
- if (typeof imageBlobOrFile === "string") {
42
- throw new Error("getImageSize(string) is not supported on browser");
43
- }
44
41
  const image = await getImageFromBlob(imageBlobOrFile);
45
42
  return { width: image.width, height: image.height };
46
43
  }
47
44
  async function getPlaceholderBase64(imageBlobOrFile) {
48
- if (typeof imageBlobOrFile === "string") {
49
- throw new Error("getPlaceholderBase64(string) is not supported on browser");
50
- }
51
45
  const image = await getImageFromBlob(imageBlobOrFile);
52
46
  const { width, height } = resizeDimensionsKeepingAspectRatio(
53
47
  image.width,
@@ -76,9 +70,6 @@ var resizeDimensionsKeepingAspectRatio = (width, height, maxSize) => {
76
70
  }
77
71
  };
78
72
  async function resize(imageBlobOrFile, width, height) {
79
- if (typeof imageBlobOrFile === "string") {
80
- throw new Error("resize(string) is not supported on browser");
81
- }
82
73
  const mimeType = imageBlobOrFile.type;
83
74
  const image = await getImageFromBlob(imageBlobOrFile);
84
75
  const canvas = document.createElement("canvas");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/media/index.browser.ts"],"sourcesContent":["import { Account, FileStream, Group, ImageDefinition } from \"jazz-tools\";\nimport { CreateImageOptions, createImageFactory } from \"./create-image.js\";\n\nexport { highestResAvailable, loadImage, loadImageBySize } from \"./utils.js\";\n\nexport { createImageFactory };\n\nexport async function createImage(\n imageBlobOrFile: Blob | File | string,\n options?: CreateImageOptions,\n) {\n return createImageFactory({\n createFileStreamFromSource,\n getImageSize,\n getPlaceholderBase64,\n resize,\n })(imageBlobOrFile, options || {});\n}\n\n// Image Manipulations\nasync function createFileStreamFromSource(\n imageBlobOrFile: Blob | File | string,\n owner?: Account | Group,\n): Promise<FileStream> {\n if (typeof imageBlobOrFile === \"string\") {\n throw new Error(\n \"createFileStreamFromSource(string) is not supported on this platform\",\n );\n }\n\n return FileStream.createFromBlob(imageBlobOrFile, owner);\n}\n\n// using createImageBitmap is ~10x slower than Image object\n// Image object: 640 milliseconds\n// createImageBitmap: 8128 milliseconds\nfunction getImageFromBlob(blob: Blob): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n resolve(img);\n URL.revokeObjectURL(img.src);\n };\n img.onerror = () => {\n reject(new Error(\"Failed to load image\"));\n URL.revokeObjectURL(img.src);\n };\n img.src = URL.createObjectURL(blob);\n });\n}\n\nasync function getImageSize(\n imageBlobOrFile: Blob | File | string,\n): Promise<{ width: number; height: number }> {\n if (typeof imageBlobOrFile === \"string\") {\n throw new Error(\"getImageSize(string) is not supported on browser\");\n }\n\n const image = await getImageFromBlob(imageBlobOrFile);\n\n return { width: image.width, height: image.height };\n}\n\nasync function getPlaceholderBase64(\n imageBlobOrFile: Blob | File | string,\n): Promise<string> {\n if (typeof imageBlobOrFile === \"string\") {\n throw new Error(\"getPlaceholderBase64(string) is not supported on browser\");\n }\n\n const image = await getImageFromBlob(imageBlobOrFile);\n\n const { width, height } = resizeDimensionsKeepingAspectRatio(\n image.width,\n image.height,\n 8,\n );\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) {\n throw new Error(\"Failed to get context\");\n }\n\n ctx.drawImage(image, 0, 0, width, height);\n\n return canvas.toDataURL(\"image/png\");\n}\n\nconst resizeDimensionsKeepingAspectRatio = (\n width: number,\n height: number,\n maxSize: number,\n): { width: number; height: number } => {\n if (width <= maxSize && height <= maxSize) {\n return { width, height };\n }\n\n const aspectRatio = width / height;\n\n if (width >= height) {\n return { width: maxSize, height: Math.round(maxSize / aspectRatio) };\n } else {\n return { width: Math.round(maxSize * aspectRatio), height: maxSize };\n }\n};\n\nasync function resize(\n imageBlobOrFile: Blob | File | string,\n width: number,\n height: number,\n): Promise<Blob> {\n if (typeof imageBlobOrFile === \"string\") {\n throw new Error(\"resize(string) is not supported on browser\");\n }\n\n const mimeType = imageBlobOrFile.type;\n\n const image = await getImageFromBlob(imageBlobOrFile);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) {\n throw new Error(\"Failed to get context\");\n }\n\n ctx.drawImage(image, 0, 0, width, height);\n\n return new Promise<Blob>((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error(\"Failed to convert canvas to blob\"));\n return;\n }\n resolve(blob);\n },\n mimeType,\n 0.8,\n );\n });\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/media/create-image/browser.ts"],"sourcesContent":["import { Account, FileStream, Group } from \"jazz-tools\";\nimport { createImageFactory } from \"../create-image-factory\";\n\n/**\n * Creates an ImageDefinition from an image File or Blob with built-in UX features.\n *\n * This function creates a specialized CoValue for managing images in Jazz applications.\n * It supports blurry placeholders, built-in resizing, and progressive loading patterns.\n *\n * @returns Promise that resolves to an ImageDefinition\n *\n * @example\n * ```ts\n * import { createImage } from \"jazz-tools/media\";\n *\n * // Create an image from a file input\n * async function handleFileUpload(event: React.ChangeEvent<HTMLInputElement>) {\n * const file = event.target.files?.[0];\n * if (file) {\n * // Creates ImageDefinition with a blurry placeholder, limited to 1024px\n * // on the longest side, and multiple resolutions automatically\n * const image = await createImage(file, {\n * owner: me._owner,\n * maxSize: 1024,\n * placeholder: \"blur\",\n * progressive: true,\n * });\n *\n * // Store the image in your application data\n * me.profile.image = image;\n * }\n * }\n * ```\n */\nexport const createImage = createImageFactory(\n {\n createFileStreamFromSource,\n getImageSize,\n getPlaceholderBase64,\n resize,\n },\n (imageBlobOrFile) => {\n if (typeof imageBlobOrFile === \"string\") {\n throw new Error(\"createImage(string) is not supported on this platform\");\n }\n },\n);\n\n// Image Manipulations\nasync function createFileStreamFromSource(\n imageBlobOrFile: Blob | File,\n owner?: Account | Group,\n): Promise<FileStream> {\n return FileStream.createFromBlob(imageBlobOrFile, owner);\n}\n\n// using createImageBitmap is ~10x slower than Image object\n// Image object: 640 milliseconds\n// createImageBitmap: 8128 milliseconds\nfunction getImageFromBlob(blob: Blob): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n resolve(img);\n URL.revokeObjectURL(img.src);\n };\n img.onerror = () => {\n reject(new Error(\"Failed to load image\"));\n URL.revokeObjectURL(img.src);\n };\n img.src = URL.createObjectURL(blob);\n });\n}\n\nasync function getImageSize(\n imageBlobOrFile: Blob | File,\n): Promise<{ width: number; height: number }> {\n const image = await getImageFromBlob(imageBlobOrFile);\n\n return { width: image.width, height: image.height };\n}\n\nasync function getPlaceholderBase64(\n imageBlobOrFile: Blob | File,\n): Promise<string> {\n const image = await getImageFromBlob(imageBlobOrFile);\n\n const { width, height } = resizeDimensionsKeepingAspectRatio(\n image.width,\n image.height,\n 8,\n );\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) {\n throw new Error(\"Failed to get context\");\n }\n\n ctx.drawImage(image, 0, 0, width, height);\n\n return canvas.toDataURL(\"image/png\");\n}\n\nconst resizeDimensionsKeepingAspectRatio = (\n width: number,\n height: number,\n maxSize: number,\n): { width: number; height: number } => {\n if (width <= maxSize && height <= maxSize) {\n return { width, height };\n }\n\n const aspectRatio = width / height;\n\n if (width >= height) {\n return { width: maxSize, height: Math.round(maxSize / aspectRatio) };\n } else {\n return { width: Math.round(maxSize * aspectRatio), height: maxSize };\n }\n};\n\nasync function resize(\n imageBlobOrFile: Blob | File,\n width: number,\n height: number,\n): Promise<Blob> {\n const mimeType = imageBlobOrFile.type;\n\n const image = await getImageFromBlob(imageBlobOrFile);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) {\n throw new Error(\"Failed to get context\");\n }\n\n ctx.drawImage(image, 0, 0, width, height);\n\n return new Promise<Blob>((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error(\"Failed to convert canvas to blob\"));\n return;\n }\n resolve(blob);\n },\n mimeType,\n 0.8,\n );\n });\n}\n"],"mappings":";;;;;;;;AAAA,SAAkB,kBAAyB;AAkCpC,IAAM,cAAc;AAAA,EACzB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,CAAC,oBAAoB;AACnB,QAAI,OAAO,oBAAoB,UAAU;AACvC,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAAA,EACF;AACF;AAGA,eAAe,2BACb,iBACA,OACqB;AACrB,SAAO,WAAW,eAAe,iBAAiB,KAAK;AACzD;AAKA,SAAS,iBAAiB,MAAuC;AAC/D,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,MAAM,IAAI,MAAM;AACtB,QAAI,SAAS,MAAM;AACjB,cAAQ,GAAG;AACX,UAAI,gBAAgB,IAAI,GAAG;AAAA,IAC7B;AACA,QAAI,UAAU,MAAM;AAClB,aAAO,IAAI,MAAM,sBAAsB,CAAC;AACxC,UAAI,gBAAgB,IAAI,GAAG;AAAA,IAC7B;AACA,QAAI,MAAM,IAAI,gBAAgB,IAAI;AAAA,EACpC,CAAC;AACH;AAEA,eAAe,aACb,iBAC4C;AAC5C,QAAM,QAAQ,MAAM,iBAAiB,eAAe;AAEpD,SAAO,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,OAAO;AACpD;AAEA,eAAe,qBACb,iBACiB;AACjB,QAAM,QAAQ,MAAM,iBAAiB,eAAe;AAEpD,QAAM,EAAE,OAAO,OAAO,IAAI;AAAA,IACxB,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACF;AAEA,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,QAAQ;AACf,SAAO,SAAS;AAEhB,QAAM,MAAM,OAAO,WAAW,IAAI;AAElC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAEA,MAAI,UAAU,OAAO,GAAG,GAAG,OAAO,MAAM;AAExC,SAAO,OAAO,UAAU,WAAW;AACrC;AAEA,IAAM,qCAAqC,CACzC,OACA,QACA,YACsC;AACtC,MAAI,SAAS,WAAW,UAAU,SAAS;AACzC,WAAO,EAAE,OAAO,OAAO;AAAA,EACzB;AAEA,QAAM,cAAc,QAAQ;AAE5B,MAAI,SAAS,QAAQ;AACnB,WAAO,EAAE,OAAO,SAAS,QAAQ,KAAK,MAAM,UAAU,WAAW,EAAE;AAAA,EACrE,OAAO;AACL,WAAO,EAAE,OAAO,KAAK,MAAM,UAAU,WAAW,GAAG,QAAQ,QAAQ;AAAA,EACrE;AACF;AAEA,eAAe,OACb,iBACA,OACA,QACe;AACf,QAAM,WAAW,gBAAgB;AAEjC,QAAM,QAAQ,MAAM,iBAAiB,eAAe;AAEpD,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,QAAQ;AACf,SAAO,SAAS;AAEhB,QAAM,MAAM,OAAO,WAAW,IAAI;AAElC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAEA,MAAI,UAAU,OAAO,GAAG,GAAG,OAAO,MAAM;AAExC,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,WAAO;AAAA,MACL,CAAC,SAAS;AACR,YAAI,CAAC,MAAM;AACT,iBAAO,IAAI,MAAM,kCAAkC,CAAC;AACpD;AAAA,QACF;AACA,gBAAQ,IAAI;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":[]}
@@ -1,7 +1,6 @@
1
1
  import type { ImageDefinition } from "jazz-tools";
2
- import { CreateImageOptions, SourceType, createImageFactory } from "./create-image.js";
3
- export { highestResAvailable, loadImage, loadImageBySize } from "./utils.js";
4
- export { createImageFactory };
2
+ import { CreateImageOptions } from "./create-image-factory";
3
+ export * from "./exports";
5
4
  /**
6
5
  * Creates an ImageDefinition from an image file or blob with built-in UX features.
7
6
  *
@@ -32,7 +31,16 @@ export { createImageFactory };
32
31
  * }
33
32
  * }
34
33
  * ```
34
+ * ```
35
+ */
36
+ export declare function createImage(imageBlobOrFile: Blob | File, options?: CreateImageOptions): Promise<ImageDefinition>;
37
+ /**
38
+ * Creates an ImageDefinition from an image file path with built-in UX features.
35
39
  *
40
+ * This function creates a specialized CoValue for managing images in Jazz applications.
41
+ * It supports blurry placeholders, built-in resizing, and progressive loading patterns.
42
+ *
43
+ * @returns Promise that resolves to an ImageDefinition
36
44
  * @example
37
45
  * ```ts
38
46
  * // React Native example
@@ -49,5 +57,5 @@ export { createImageFactory };
49
57
  * }
50
58
  * ```
51
59
  */
52
- export declare function createImage(imageBlobOrFile: SourceType, options?: CreateImageOptions): Promise<ImageDefinition>;
60
+ export declare function createImage(filePath: string, options?: CreateImageOptions): Promise<ImageDefinition>;
53
61
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,eAAe,EAAE,UAAU,EAC3B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,cAAc,WAAW,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,eAAe,EAAE,IAAI,GAAG,IAAI,EAC5B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAAC"}
@@ -3,7 +3,7 @@ import {
3
3
  highestResAvailable,
4
4
  loadImage,
5
5
  loadImageBySize
6
- } from "./chunk-KR2V6X2N.js";
6
+ } from "./chunk-W3S526L3.js";
7
7
  export {
8
8
  createImageFactory,
9
9
  highestResAvailable,
@@ -1,17 +1,3 @@
1
- import type { Account, Group } from "jazz-tools";
2
- import { FileStream } from "jazz-tools";
3
- import { CreateImageOptions, SourceType, createImageFactory } from "./create-image.js";
4
- export { highestResAvailable, loadImage, loadImageBySize } from "./utils.js";
5
- export { createImageFactory };
6
- export declare function createImage(imageBlobOrFile: Blob | File | string, options?: CreateImageOptions): Promise<{
7
- readonly [key: string]: FileStream;
8
- } & {
9
- readonly original: FileStream | null;
10
- readonly originalSize: [number, number];
11
- readonly placeholderDataURL: string | undefined;
12
- readonly progressive: boolean;
13
- } & {
14
- readonly [key: string]: FileStream | null;
15
- } & import("jazz-tools").CoMap>;
16
- export declare function createFileStreamFromSource(filePath: SourceType, owner?: Account | Group): Promise<FileStream>;
1
+ export * from "./exports";
2
+ export { createImage } from "./create-image/react-native";
17
3
  //# sourceMappingURL=index.native.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.native.d.ts","sourceRoot":"","sources":["../../src/media/index.native.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAI9B,wBAAsB,WAAW,CAC/B,eAAe,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACrC,OAAO,CAAC,EAAE,kBAAkB;;;;;;;;;gCAmB7B;AAmFD,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,UAAU,EACpB,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,GACtB,OAAO,CAAC,UAAU,CAAC,CAarB"}
1
+ {"version":3,"file":"index.native.d.ts","sourceRoot":"","sources":["../../src/media/index.native.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC"}
@@ -3,13 +3,28 @@ import {
3
3
  highestResAvailable,
4
4
  loadImage,
5
5
  loadImageBySize
6
- } from "./chunk-KR2V6X2N.js";
6
+ } from "./chunk-W3S526L3.js";
7
7
 
8
- // src/media/index.native.ts
8
+ // src/media/create-image/react-native.ts
9
9
  import { FileStream } from "jazz-tools";
10
10
  import { Image } from "react-native";
11
11
  var ImageResizer;
12
- async function createImage(imageBlobOrFile, options) {
12
+ var createImage = createImageFactory(
13
+ {
14
+ getImageSize,
15
+ getPlaceholderBase64,
16
+ createFileStreamFromSource,
17
+ resize
18
+ },
19
+ (filePath) => {
20
+ if (typeof filePath !== "string") {
21
+ throw new Error(
22
+ "createImage(Blob | File) is not supported on this platform"
23
+ );
24
+ }
25
+ }
26
+ );
27
+ async function getResizer() {
13
28
  if (!ImageResizer) {
14
29
  try {
15
30
  ImageResizer = (await import("@bam.tech/react-native-image-resizer")).default;
@@ -19,34 +34,15 @@ async function createImage(imageBlobOrFile, options) {
19
34
  );
20
35
  }
21
36
  }
22
- return createImageFactory({
23
- getImageSize,
24
- getPlaceholderBase64,
25
- createFileStreamFromSource,
26
- resize
27
- })(imageBlobOrFile, options || {});
37
+ return ImageResizer;
28
38
  }
29
39
  async function getImageSize(filePath) {
30
- if (typeof filePath !== "string") {
31
- throw new Error(
32
- "createImage(Blob | File) is not supported on this platform"
33
- );
34
- }
35
40
  const { width, height } = await Image.getSize(filePath);
36
41
  return { width, height };
37
42
  }
38
43
  async function getPlaceholderBase64(filePath) {
39
- if (typeof filePath !== "string") {
40
- throw new Error(
41
- "createImage(Blob | File) is not supported on this platform"
42
- );
43
- }
44
- if (!ImageResizer) {
45
- throw new Error(
46
- "ImageResizer is not installed, please run `npm install @bam.tech/react-native-image-resizer`"
47
- );
48
- }
49
- const { uri } = await ImageResizer.createResizedImage(
44
+ const ImageResizer2 = await getResizer();
45
+ const { uri } = await ImageResizer2.createResizedImage(
50
46
  filePath,
51
47
  8,
52
48
  8,
@@ -56,18 +52,9 @@ async function getPlaceholderBase64(filePath) {
56
52
  return imageUrlToBase64(uri);
57
53
  }
58
54
  async function resize(filePath, width, height) {
59
- if (typeof filePath !== "string") {
60
- throw new Error(
61
- "createImage(Blob | File) is not supported on this platform"
62
- );
63
- }
64
- if (!ImageResizer) {
65
- throw new Error(
66
- "ImageResizer is not installed, please run `npm install @bam.tech/react-native-image-resizer`"
67
- );
68
- }
55
+ const ImageResizer2 = await getResizer();
69
56
  const mimeType = await getMimeType(filePath);
70
- const { uri } = await ImageResizer.createResizedImage(
57
+ const { uri } = await ImageResizer2.createResizedImage(
71
58
  filePath,
72
59
  width,
73
60
  height,
@@ -86,11 +73,6 @@ function contentTypeToFormat(contentType) {
86
73
  return "PNG";
87
74
  }
88
75
  async function createFileStreamFromSource(filePath, owner) {
89
- if (typeof filePath !== "string") {
90
- throw new Error(
91
- "createImage(Blob | File) is not supported on this platform"
92
- );
93
- }
94
76
  const blob = await fetch(filePath).then((res) => res.blob());
95
77
  const arrayBuffer = await toArrayBuffer(blob);
96
78
  return FileStream.createFromArrayBuffer(arrayBuffer, blob.type, void 0, {
@@ -125,7 +107,6 @@ async function imageUrlToBase64(url) {
125
107
  });
126
108
  }
127
109
  export {
128
- createFileStreamFromSource,
129
110
  createImage,
130
111
  createImageFactory,
131
112
  highestResAvailable,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/media/index.native.ts"],"sourcesContent":["import type ImageResizerType from \"@bam.tech/react-native-image-resizer\";\nimport type { Account, Group } from \"jazz-tools\";\nimport { FileStream } from \"jazz-tools\";\nimport { Image } from \"react-native\";\nimport {\n CreateImageOptions,\n SourceType,\n createImageFactory,\n} from \"./create-image.js\";\n\nexport { highestResAvailable, loadImage, loadImageBySize } from \"./utils.js\";\nexport { createImageFactory };\n\nlet ImageResizer: typeof ImageResizerType | undefined;\n\nexport async function createImage(\n imageBlobOrFile: Blob | File | string,\n options?: CreateImageOptions,\n) {\n if (!ImageResizer) {\n try {\n ImageResizer = (await import(\"@bam.tech/react-native-image-resizer\"))\n .default;\n } catch (e) {\n throw new Error(\n \"ImageResizer is not installed, please run `npm install @bam.tech/react-native-image-resizer`\",\n );\n }\n }\n\n return createImageFactory({\n getImageSize,\n getPlaceholderBase64,\n createFileStreamFromSource,\n resize,\n })(imageBlobOrFile, options || {});\n}\n\nasync function getImageSize(\n filePath: SourceType,\n): Promise<{ width: number; height: number }> {\n if (typeof filePath !== \"string\") {\n throw new Error(\n \"createImage(Blob | File) is not supported on this platform\",\n );\n }\n\n const { width, height } = await Image.getSize(filePath);\n\n return { width, height };\n}\n\nasync function getPlaceholderBase64(filePath: SourceType): Promise<string> {\n if (typeof filePath !== \"string\") {\n throw new Error(\n \"createImage(Blob | File) is not supported on this platform\",\n );\n }\n\n if (!ImageResizer) {\n throw new Error(\n \"ImageResizer is not installed, please run `npm install @bam.tech/react-native-image-resizer`\",\n );\n }\n\n const { uri } = await ImageResizer.createResizedImage(\n filePath,\n 8,\n 8,\n \"PNG\",\n 100,\n );\n\n return imageUrlToBase64(uri);\n}\n\nasync function resize(\n filePath: SourceType,\n width: number,\n height: number,\n): Promise<string> {\n if (typeof filePath !== \"string\") {\n throw new Error(\n \"createImage(Blob | File) is not supported on this platform\",\n );\n }\n\n if (!ImageResizer) {\n throw new Error(\n \"ImageResizer is not installed, please run `npm install @bam.tech/react-native-image-resizer`\",\n );\n }\n\n const mimeType = await getMimeType(filePath);\n\n const { uri } = await ImageResizer.createResizedImage(\n filePath,\n width,\n height,\n contentTypeToFormat(mimeType),\n 80,\n );\n\n return uri;\n}\n\nfunction getMimeType(filePath: string): Promise<string> {\n return fetch(filePath)\n .then((res) => res.blob())\n .then((blob) => blob.type);\n}\n\nfunction contentTypeToFormat(contentType: string) {\n if (contentType.includes(\"image/png\")) return \"PNG\";\n if (contentType.includes(\"image/jpeg\")) return \"JPEG\";\n if (contentType.includes(\"image/webp\")) return \"WEBP\";\n return \"PNG\";\n}\n\nexport async function createFileStreamFromSource(\n filePath: SourceType,\n owner?: Account | Group,\n): Promise<FileStream> {\n if (typeof filePath !== \"string\") {\n throw new Error(\n \"createImage(Blob | File) is not supported on this platform\",\n );\n }\n\n const blob = await fetch(filePath).then((res) => res.blob());\n const arrayBuffer = await toArrayBuffer(blob);\n\n return FileStream.createFromArrayBuffer(arrayBuffer, blob.type, undefined, {\n owner,\n });\n}\n\n// TODO: look for more efficient way to do this as React Native hasn't blob.arrayBuffer()\nfunction toArrayBuffer(blob: Blob): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n resolve(reader.result as ArrayBuffer);\n };\n reader.onerror = (error) => {\n reject(error);\n };\n reader.readAsArrayBuffer(blob);\n });\n}\n\nasync function imageUrlToBase64(url: string): Promise<string> {\n const response = await fetch(url);\n const blob = await response.blob();\n return new Promise((onSuccess, onError) => {\n try {\n const reader = new FileReader();\n reader.onload = function () {\n onSuccess(reader.result as string);\n };\n reader.readAsDataURL(blob);\n } catch (e) {\n onError(e);\n }\n });\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/media/create-image/react-native.ts"],"sourcesContent":["import type ImageResizerType from \"@bam.tech/react-native-image-resizer\";\nimport type { Account, Group } from \"jazz-tools\";\nimport { FileStream } from \"jazz-tools\";\nimport { Image } from \"react-native\";\nimport { createImageFactory } from \"../create-image-factory\";\n\nlet ImageResizer: typeof ImageResizerType | undefined;\n\n/**\n * Creates an ImageDefinition from an image file path with built-in UX features.\n *\n * This function creates a specialized CoValue for managing images in Jazz applications.\n * It supports blurry placeholders, built-in resizing, and progressive loading patterns.\n *\n * @returns Promise that resolves to an ImageDefinition\n *\n * @example\n * ```ts\n * import { createImage } from \"jazz-tools/media\";\n *\n * async function uploadImageFromCamera(imagePath: string) {\n * const image = await createImage(imagePath, {\n * maxSize: 800,\n * placeholder: \"blur\",\n * progressive: false,\n * });\n *\n * return image;\n * }\n * ```\n */\nexport const createImage = createImageFactory(\n {\n getImageSize,\n getPlaceholderBase64,\n createFileStreamFromSource,\n resize,\n },\n (filePath) => {\n if (typeof filePath !== \"string\") {\n throw new Error(\n \"createImage(Blob | File) is not supported on this platform\",\n );\n }\n },\n);\n\nasync function getResizer(): Promise<typeof ImageResizerType> {\n if (!ImageResizer) {\n try {\n ImageResizer = (await import(\"@bam.tech/react-native-image-resizer\"))\n .default;\n } catch (e) {\n throw new Error(\n \"ImageResizer is not installed, please run `npm install @bam.tech/react-native-image-resizer`\",\n );\n }\n }\n\n return ImageResizer;\n}\n\nasync function getImageSize(\n filePath: string,\n): Promise<{ width: number; height: number }> {\n const { width, height } = await Image.getSize(filePath);\n\n return { width, height };\n}\n\nasync function getPlaceholderBase64(filePath: string): Promise<string> {\n const ImageResizer = await getResizer();\n\n const { uri } = await ImageResizer.createResizedImage(\n filePath,\n 8,\n 8,\n \"PNG\",\n 100,\n );\n\n return imageUrlToBase64(uri);\n}\n\nasync function resize(\n filePath: string,\n width: number,\n height: number,\n): Promise<string> {\n const ImageResizer = await getResizer();\n\n const mimeType = await getMimeType(filePath);\n\n const { uri } = await ImageResizer.createResizedImage(\n filePath,\n width,\n height,\n contentTypeToFormat(mimeType),\n 80,\n );\n\n return uri;\n}\n\nfunction getMimeType(filePath: string): Promise<string> {\n return fetch(filePath)\n .then((res) => res.blob())\n .then((blob) => blob.type);\n}\n\nfunction contentTypeToFormat(contentType: string) {\n if (contentType.includes(\"image/png\")) return \"PNG\";\n if (contentType.includes(\"image/jpeg\")) return \"JPEG\";\n if (contentType.includes(\"image/webp\")) return \"WEBP\";\n return \"PNG\";\n}\n\nexport async function createFileStreamFromSource(\n filePath: string,\n owner?: Account | Group,\n): Promise<FileStream> {\n const blob = await fetch(filePath).then((res) => res.blob());\n const arrayBuffer = await toArrayBuffer(blob);\n\n return FileStream.createFromArrayBuffer(arrayBuffer, blob.type, undefined, {\n owner,\n });\n}\n\n// TODO: look for more efficient way to do this as React Native hasn't blob.arrayBuffer()\nfunction toArrayBuffer(blob: Blob): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n resolve(reader.result as ArrayBuffer);\n };\n reader.onerror = (error) => {\n reject(error);\n };\n reader.readAsArrayBuffer(blob);\n });\n}\n\nasync function imageUrlToBase64(url: string): Promise<string> {\n const response = await fetch(url);\n const blob = await response.blob();\n return new Promise((onSuccess, onError) => {\n try {\n const reader = new FileReader();\n reader.onload = function () {\n onSuccess(reader.result as string);\n };\n reader.readAsDataURL(blob);\n } catch (e) {\n onError(e);\n }\n });\n}\n"],"mappings":";;;;;;;;AAEA,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AAGtB,IAAI;AAyBG,IAAM,cAAc;AAAA,EACzB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,CAAC,aAAa;AACZ,QAAI,OAAO,aAAa,UAAU;AAChC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,aAA+C;AAC5D,MAAI,CAAC,cAAc;AACjB,QAAI;AACF,sBAAgB,MAAM,OAAO,sCAAsC,GAChE;AAAA,IACL,SAAS,GAAG;AACV,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,aACb,UAC4C;AAC5C,QAAM,EAAE,OAAO,OAAO,IAAI,MAAM,MAAM,QAAQ,QAAQ;AAEtD,SAAO,EAAE,OAAO,OAAO;AACzB;AAEA,eAAe,qBAAqB,UAAmC;AACrE,QAAMA,gBAAe,MAAM,WAAW;AAEtC,QAAM,EAAE,IAAI,IAAI,MAAMA,cAAa;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,iBAAiB,GAAG;AAC7B;AAEA,eAAe,OACb,UACA,OACA,QACiB;AACjB,QAAMA,gBAAe,MAAM,WAAW;AAEtC,QAAM,WAAW,MAAM,YAAY,QAAQ;AAE3C,QAAM,EAAE,IAAI,IAAI,MAAMA,cAAa;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB,QAAQ;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,UAAmC;AACtD,SAAO,MAAM,QAAQ,EAClB,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EACxB,KAAK,CAAC,SAAS,KAAK,IAAI;AAC7B;AAEA,SAAS,oBAAoB,aAAqB;AAChD,MAAI,YAAY,SAAS,WAAW,EAAG,QAAO;AAC9C,MAAI,YAAY,SAAS,YAAY,EAAG,QAAO;AAC/C,MAAI,YAAY,SAAS,YAAY,EAAG,QAAO;AAC/C,SAAO;AACT;AAEA,eAAsB,2BACpB,UACA,OACqB;AACrB,QAAM,OAAO,MAAM,MAAM,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC;AAC3D,QAAM,cAAc,MAAM,cAAc,IAAI;AAE5C,SAAO,WAAW,sBAAsB,aAAa,KAAK,MAAM,QAAW;AAAA,IACzE;AAAA,EACF,CAAC;AACH;AAGA,SAAS,cAAc,MAAkC;AACvD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,IAAI,WAAW;AAC9B,WAAO,YAAY,MAAM;AACvB,cAAQ,OAAO,MAAqB;AAAA,IACtC;AACA,WAAO,UAAU,CAAC,UAAU;AAC1B,aAAO,KAAK;AAAA,IACd;AACA,WAAO,kBAAkB,IAAI;AAAA,EAC/B,CAAC;AACH;AAEA,eAAe,iBAAiB,KAA8B;AAC5D,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,IAAI,QAAQ,CAAC,WAAW,YAAY;AACzC,QAAI;AACF,YAAM,SAAS,IAAI,WAAW;AAC9B,aAAO,SAAS,WAAY;AAC1B,kBAAU,OAAO,MAAgB;AAAA,MACnC;AACA,aAAO,cAAc,IAAI;AAAA,IAC3B,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF,CAAC;AACH;","names":["ImageResizer"]}
@@ -0,0 +1,3 @@
1
+ export * from "./exports";
2
+ export { createImage } from "./create-image/server";
3
+ //# sourceMappingURL=index.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.server.d.ts","sourceRoot":"","sources":["../../src/media/index.server.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,103 @@
1
+ import {
2
+ createImageFactory,
3
+ highestResAvailable,
4
+ loadImage,
5
+ loadImageBySize
6
+ } from "./chunk-W3S526L3.js";
7
+
8
+ // src/media/create-image/server.ts
9
+ import { FileStream } from "jazz-tools";
10
+ var sharpModule;
11
+ async function getSharp() {
12
+ if (!sharpModule) {
13
+ sharpModule = await import("sharp").then((m) => m.default);
14
+ }
15
+ return sharpModule;
16
+ }
17
+ var createImage = createImageFactory(
18
+ {
19
+ createFileStreamFromSource,
20
+ getImageSize,
21
+ getPlaceholderBase64,
22
+ resize
23
+ },
24
+ (imageBlobOrFile) => {
25
+ if (typeof imageBlobOrFile === "string") {
26
+ throw new Error("createImage(string) is not supported on this platform");
27
+ }
28
+ }
29
+ );
30
+ function formatToMimeType(format) {
31
+ const formatToTypeMap = {
32
+ avif: "image/avif",
33
+ gif: "image/gif",
34
+ jpeg: "image/jpeg",
35
+ jpg: "image/jpeg",
36
+ png: "image/png",
37
+ webp: "image/webp"
38
+ };
39
+ if (!format) {
40
+ throw new Error("Could not determine image format");
41
+ }
42
+ if (!(format in formatToTypeMap)) {
43
+ throw new Error(`Unsupported image format: ${format}`);
44
+ }
45
+ return formatToTypeMap[format];
46
+ }
47
+ async function createFileStreamFromSource(imageBlobOrBuffer, owner) {
48
+ if (imageBlobOrBuffer instanceof Blob) {
49
+ return FileStream.createFromBlob(imageBlobOrBuffer, { owner });
50
+ }
51
+ const sharp = await getSharp();
52
+ const image = sharp(imageBlobOrBuffer);
53
+ const metadata = await image.metadata();
54
+ const format = metadata.format;
55
+ const mimeType = formatToMimeType(format);
56
+ return FileStream.createFromArrayBuffer(
57
+ imageBlobOrBuffer,
58
+ mimeType,
59
+ void 0,
60
+ { owner }
61
+ );
62
+ }
63
+ async function getImageSize(imageBlobOrBuffer) {
64
+ const imageBuffer = imageBlobOrBuffer instanceof Blob ? await imageBlobOrBuffer.arrayBuffer() : imageBlobOrBuffer;
65
+ const sharp = await getSharp();
66
+ const image = sharp(imageBuffer);
67
+ const metadata = await image.metadata();
68
+ return { width: metadata.width, height: metadata.height };
69
+ }
70
+ async function getPlaceholderBase64(imageBlobOrBuffer) {
71
+ const imageBuffer = imageBlobOrBuffer instanceof Blob ? await imageBlobOrBuffer.arrayBuffer() : imageBlobOrBuffer;
72
+ const sharp = await getSharp();
73
+ const image = sharp(imageBuffer);
74
+ const placeholder = await image.resize({
75
+ width: 8,
76
+ height: 8,
77
+ fit: "inside"
78
+ }).toFormat("png").toBuffer();
79
+ return `data:image/png;base64,${placeholder.toString("base64")}`;
80
+ }
81
+ async function resize(imageBlobOrBuffer, width, height) {
82
+ const imageBuffer = imageBlobOrBuffer instanceof Blob ? await imageBlobOrBuffer.arrayBuffer() : imageBlobOrBuffer;
83
+ const sharp = await getSharp();
84
+ const image = sharp(imageBuffer);
85
+ const metadata = await image.metadata();
86
+ const format = metadata.format;
87
+ const mimeType = formatToMimeType(format);
88
+ const resizedBuffer = await image.resize({
89
+ width,
90
+ height
91
+ }).toBuffer();
92
+ return new Blob([new Uint8Array(resizedBuffer)], {
93
+ type: mimeType
94
+ });
95
+ }
96
+ export {
97
+ createImage,
98
+ createImageFactory,
99
+ highestResAvailable,
100
+ loadImage,
101
+ loadImageBySize
102
+ };
103
+ //# sourceMappingURL=index.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/media/create-image/server.ts"],"sourcesContent":["import { Account, FileStream, Group } from \"jazz-tools\";\nimport type sharp from \"sharp\";\nimport { createImageFactory } from \"../create-image-factory\";\n\nexport type SharpImageType =\n | File\n | Blob\n | Buffer\n | ArrayBuffer\n | Uint8Array\n | Uint8ClampedArray\n | Int8Array\n | Uint16Array\n | Int16Array\n | Uint32Array\n | Int32Array\n | Float32Array\n | Float64Array;\n\nlet sharpModule: typeof import(\"sharp\");\n\nasync function getSharp() {\n if (!sharpModule) {\n sharpModule = await import(\"sharp\").then((m) => m.default);\n }\n\n return sharpModule;\n}\n\n/**\n * Creates an ImageDefinition from an image File, Blob or Buffer with built-in UX features.\n *\n * This function creates a specialized CoValue for managing images in Jazz applications.\n * It supports blurry placeholders, built-in resizing, and progressive loading patterns.\n *\n * @returns Promise that resolves to an ImageDefinition\n *\n * @example\n * ```ts\n * import fs from \"node:fs\";\n * import { createImage } from \"jazz-tools/media\";\n *\n * const imageBuffer = fs.readFileSync(\"path/to/image.jpg\");\n * const image = await createImage(imageBuffer, {\n * maxSize: 800,\n * placeholder: \"blur\",\n * progressive: false,\n * });\n * ```\n */\nexport const createImage = createImageFactory<SharpImageType, Blob>(\n {\n createFileStreamFromSource,\n getImageSize,\n getPlaceholderBase64,\n resize,\n },\n (imageBlobOrFile) => {\n if (typeof imageBlobOrFile === \"string\") {\n throw new Error(\"createImage(string) is not supported on this platform\");\n }\n },\n);\n\nfunction formatToMimeType(format: keyof sharp.FormatEnum | undefined) {\n const formatToTypeMap: Record<\n Extract<\n keyof sharp.FormatEnum,\n \"avif\" | \"gif\" | \"jpeg\" | \"jpg\" | \"png\" | \"webp\"\n >,\n string\n > = {\n avif: \"image/avif\",\n gif: \"image/gif\",\n jpeg: \"image/jpeg\",\n jpg: \"image/jpeg\",\n png: \"image/png\",\n webp: \"image/webp\",\n };\n\n if (!format) {\n throw new Error(\"Could not determine image format\");\n }\n\n if (!(format in formatToTypeMap)) {\n throw new Error(`Unsupported image format: ${format}`);\n }\n\n return formatToTypeMap[format as keyof typeof formatToTypeMap];\n}\n\nasync function createFileStreamFromSource(\n imageBlobOrBuffer: SharpImageType,\n owner?: Account | Group,\n): Promise<FileStream> {\n // `File` is also an instance of `Blob`\n if (imageBlobOrBuffer instanceof Blob) {\n return FileStream.createFromBlob(imageBlobOrBuffer, { owner });\n }\n\n const sharp = await getSharp();\n\n const image = sharp(imageBlobOrBuffer);\n const metadata = await image.metadata();\n const format = metadata.format;\n const mimeType = formatToMimeType(format);\n\n return FileStream.createFromArrayBuffer(\n imageBlobOrBuffer,\n mimeType,\n undefined,\n { owner },\n );\n}\n\nasync function getImageSize(\n imageBlobOrBuffer: SharpImageType,\n): Promise<{ width: number; height: number }> {\n const imageBuffer =\n imageBlobOrBuffer instanceof Blob\n ? await imageBlobOrBuffer.arrayBuffer()\n : imageBlobOrBuffer;\n\n const sharp = await getSharp();\n const image = sharp(imageBuffer);\n const metadata = await image.metadata();\n\n return { width: metadata.width!, height: metadata.height! };\n}\n\nasync function getPlaceholderBase64(\n imageBlobOrBuffer: SharpImageType,\n): Promise<string> {\n const imageBuffer =\n imageBlobOrBuffer instanceof Blob\n ? await imageBlobOrBuffer.arrayBuffer()\n : imageBlobOrBuffer;\n\n const sharp = await getSharp();\n\n const image = sharp(imageBuffer);\n const placeholder = await image\n .resize({\n width: 8,\n height: 8,\n fit: \"inside\",\n })\n .toFormat(\"png\")\n .toBuffer();\n\n return `data:image/png;base64,${placeholder.toString(\"base64\")}`;\n}\n\nasync function resize(\n imageBlobOrBuffer: SharpImageType,\n width: number,\n height: number,\n): Promise<Blob> {\n const imageBuffer =\n imageBlobOrBuffer instanceof Blob\n ? await imageBlobOrBuffer.arrayBuffer()\n : imageBlobOrBuffer;\n\n const sharp = await getSharp();\n\n const image = sharp(imageBuffer);\n const metadata = await image.metadata();\n const format = metadata.format;\n const mimeType = formatToMimeType(format);\n\n const resizedBuffer = await image\n .resize({\n width,\n height,\n })\n .toBuffer();\n\n return new Blob([new Uint8Array(resizedBuffer)], {\n type: mimeType,\n });\n}\n"],"mappings":";;;;;;;;AAAA,SAAkB,kBAAyB;AAmB3C,IAAI;AAEJ,eAAe,WAAW;AACxB,MAAI,CAAC,aAAa;AAChB,kBAAc,MAAM,OAAO,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC3D;AAEA,SAAO;AACT;AAuBO,IAAM,cAAc;AAAA,EACzB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,CAAC,oBAAoB;AACnB,QAAI,OAAO,oBAAoB,UAAU;AACvC,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,QAA4C;AACpE,QAAM,kBAMF;AAAA,IACF,MAAM;AAAA,IACN,KAAK;AAAA,IACL,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAEA,MAAI,EAAE,UAAU,kBAAkB;AAChC,UAAM,IAAI,MAAM,6BAA6B,MAAM,EAAE;AAAA,EACvD;AAEA,SAAO,gBAAgB,MAAsC;AAC/D;AAEA,eAAe,2BACb,mBACA,OACqB;AAErB,MAAI,6BAA6B,MAAM;AACrC,WAAO,WAAW,eAAe,mBAAmB,EAAE,MAAM,CAAC;AAAA,EAC/D;AAEA,QAAM,QAAQ,MAAM,SAAS;AAE7B,QAAM,QAAQ,MAAM,iBAAiB;AACrC,QAAM,WAAW,MAAM,MAAM,SAAS;AACtC,QAAM,SAAS,SAAS;AACxB,QAAM,WAAW,iBAAiB,MAAM;AAExC,SAAO,WAAW;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,MAAM;AAAA,EACV;AACF;AAEA,eAAe,aACb,mBAC4C;AAC5C,QAAM,cACJ,6BAA6B,OACzB,MAAM,kBAAkB,YAAY,IACpC;AAEN,QAAM,QAAQ,MAAM,SAAS;AAC7B,QAAM,QAAQ,MAAM,WAAW;AAC/B,QAAM,WAAW,MAAM,MAAM,SAAS;AAEtC,SAAO,EAAE,OAAO,SAAS,OAAQ,QAAQ,SAAS,OAAQ;AAC5D;AAEA,eAAe,qBACb,mBACiB;AACjB,QAAM,cACJ,6BAA6B,OACzB,MAAM,kBAAkB,YAAY,IACpC;AAEN,QAAM,QAAQ,MAAM,SAAS;AAE7B,QAAM,QAAQ,MAAM,WAAW;AAC/B,QAAM,cAAc,MAAM,MACvB,OAAO;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,EACP,CAAC,EACA,SAAS,KAAK,EACd,SAAS;AAEZ,SAAO,yBAAyB,YAAY,SAAS,QAAQ,CAAC;AAChE;AAEA,eAAe,OACb,mBACA,OACA,QACe;AACf,QAAM,cACJ,6BAA6B,OACzB,MAAM,kBAAkB,YAAY,IACpC;AAEN,QAAM,QAAQ,MAAM,SAAS;AAE7B,QAAM,QAAQ,MAAM,WAAW;AAC/B,QAAM,WAAW,MAAM,MAAM,SAAS;AACtC,QAAM,SAAS,SAAS;AACxB,QAAM,WAAW,iBAAiB,MAAM;AAExC,QAAM,gBAAgB,MAAM,MACzB,OAAO;AAAA,IACN;AAAA,IACA;AAAA,EACF,CAAC,EACA,SAAS;AAEZ,SAAO,IAAI,KAAK,CAAC,IAAI,WAAW,aAAa,CAAC,GAAG;AAAA,IAC/C,MAAM;AAAA,EACR,CAAC;AACH;","names":[]}
@@ -636,13 +636,8 @@ import {
636
636
  useState as useState5
637
637
  } from "react";
638
638
 
639
- // src/media/create-image.ts
640
- import {
641
- ImageDefinition
642
- } from "jazz-tools";
643
-
644
639
  // src/media/utils.ts
645
- import { Account as Account3, FileStream as FileStream2, ImageDefinition as ImageDefinition2 } from "jazz-tools";
640
+ import { Account as Account2, FileStream, ImageDefinition } from "jazz-tools";
646
641
  function highestResAvailable(image, wantedWidth, wantedHeight) {
647
642
  const availableSizes = image.$jazz.raw.keys().filter((key) => /^\d+x\d+$/.test(key)).map((key) => {
648
643
  const [w, h] = key.split("x").map(Number);
@@ -698,9 +693,14 @@ function isLoaded(id) {
698
693
  if (!id) {
699
694
  return false;
700
695
  }
701
- return !!Account3.getMe().$jazz.localNode.getLoaded(id);
696
+ return !!Account2.getMe().$jazz.localNode.getLoaded(id);
702
697
  }
703
698
 
699
+ // src/media/create-image-factory.ts
700
+ import {
701
+ ImageDefinition as ImageDefinition2
702
+ } from "jazz-tools";
703
+
704
704
  // src/react/media/image.tsx
705
705
  import { jsx as jsx6 } from "react/jsx-runtime";
706
706
  var Image = forwardRef(function Image2({ imageId, width, height, ...props }, ref) {