ImageDefinition
ImageDefinition
is a specialized CoValue designed specifically for managing images in Jazz applications. It extends beyond basic file storage by supporting multiple resolutions of the same image and progressive loading patterns.
Beyond ImageDefinition
, Jazz offers higher-level functions and components that make it easier to use images:
createImage()
- function to create anImageDefinition
from a fileProgressiveImg
- React component to display an image with progressive loadinguseProgressiveImg
- React hook to load an image in your own component
The Image Upload example demonstrates use of ProgressiveImg
and ImageDefinition
.
Creating Images
The easiest way to create and use images in your Jazz application is with the createImage()
function:
import {
createImage } from "jazz-browser-media-images"; // Create an image from a file input async function
function createImage(imageBlobOrFile: Blob | File, options?: { owner?: Group | Account; maxSize?: 256 | 1024 | 2048; }): Promise<co.loaded<typeof ImageDefinition>>
function handleFileUpload(event: React.ChangeEvent<HTMLInputElement>): Promise<void>
handleFileUpload(event: React.ChangeEvent<HTMLInputElement>
event:export namespace React
React.interface React.ChangeEvent<T = Element>
ChangeEvent<HTMLInputElement>) { constconst file: File | undefined
file =event: React.ChangeEvent<HTMLInputElement>
event.React.ChangeEvent<HTMLInputElement>.target: EventTarget & HTMLInputElement
target.HTMLInputElement.files: FileList | null
Returns a FileList object on a file type input object. [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/files)files?.[0]; if (const file: File | undefined
file) { // Creates ImageDefinition with multiple resolutions automatically constimage = await
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
createImage(
function createImage(imageBlobOrFile: Blob | File, options?: { owner?: Group | Account; maxSize?: 256 | 1024 | 2048; }): Promise<co.loaded<typeof ImageDefinition>>
const file: File
file, {owner?: Group | Account | undefined
owner:const myGroup: Group
myGroup }); // Store the image in your application datame.
const me: AccountInstance<{ root: CoMapSchema<{}>; profile: CoProfileSchema<{ name: z.z.ZodString; image: z.ZodOptional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Group | Account>, { ...; }>>; }>; }>
profile.
Account.profile: { name: string; image: ({ originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap) | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap & Profile
image =
image: ({ originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap) | undefined
image; } }
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
Note: createImage()
requires a browser environment as it uses browser APIs to process images.
The createImage()
function:
- Creates an
ImageDefinition
with the right properties - Generates a small placeholder for immediate display
- Creates multiple resolution variants of your image
- Returns the created
ImageDefinition
Configuration Options
You can configure createImage()
with additional options:
// Configuration options const
options = {
const options: { owner: Account | ({ [x: string]: any; } & Account); maxSize: 1024; }
owner:
owner: Account | ({ [x: string]: any; } & Account)
me, // Owner for access control
const me: Account | ({ [x: string]: any; } & Account)
maxSize: 1024
maxSize: 1024 as 1024 // Maximum resolution to generate }; // Setting maxSize controls which resolutions are generated: // 256: Only creates the smallest resolution (256px on longest side) // 1024: Creates 256px and 1024px resolutions // 2048: Creates 256px, 1024px, and 2048px resolutions // undefined: Creates all resolutions including the original size constimage = await
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
createImage(
function createImage(imageBlobOrFile: Blob | File, options?: { owner?: Group | Account; maxSize?: 256 | 1024 | 2048; }): Promise<Loaded<typeof ImageDefinition>>
const file: File
file,options);
const options: { owner: Account | ({ [x: string]: any; } & Account); maxSize: 1024; }
Ownership
Like other CoValues, you can specify ownership when creating image definitions.
const
const teamGroup: Group
teamGroup =class Group
Group.create();
Group.create<Group>(this: CoValueClass<Group>, options?: { owner: Account; } | Account): Group
const teamGroup: Group
teamGroup.Group.addMember(member: Account, role: AccountRole): void (+1 overload)
addMember(colleagueAccount, "writer"); // Create an image with shared ownership const
const colleagueAccount: Account | ({ [x: string]: any; } & Account)
teamImage = await
const teamImage: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
createImage(
function createImage(imageBlobOrFile: Blob | File, options?: { owner?: Group | Account; maxSize?: 256 | 1024 | 2048; }): Promise<Loaded<typeof ImageDefinition>>
const file: File
file, {owner?: Group | Account | undefined
owner:const teamGroup: Group
teamGroup });
See Groups as permission scopes for more information on how to use groups to control access to images.
Displaying Images with ProgressiveImg
For a complete progressive loading experience, use the ProgressiveImg
component:
import * as React from "react"; // ---cut--- import { ProgressiveImg } from "jazz-react"; import { co } from "jazz-tools"; const Image = co.image(); function GalleryView({ image }: { image: co.loaded<typeof Image> }) { return ( <div className="image-container"> <ProgressiveImg image={image} // The image definition to load targetWidth={800} // Looks for the best available resolution for a 800px image > {({ src }) => ( <img src={src} alt="Gallery image" className="gallery-image" /> )} </ProgressiveImg> </div> ); }
The ProgressiveImg
component handles:
- Showing a placeholder while loading
- Automatically selecting the appropriate resolution
- Progressive enhancement as higher resolutions become available
- Cleaning up resources when unmounted
Using useProgressiveImg
Hook
For more control over image loading, you can implement your own progressive image component:
import {
useProgressiveImg } from "jazz-react"; function
function useProgressiveImg({ image, maxWidth, targetWidth, }: { image: co.loaded<typeof ImageDefinition> | null | undefined; maxWidth?: number; targetWidth?: number; }): { src: string | undefined; res: "placeholder" | `${number}x${number}` | undefined; originalSize: [number, number] | undefined; }
CustomImageComponent({
function CustomImageComponent({ image }: { image: co.loaded<typeof Image>; }): React.JSX.Element
image }: {
image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
image:
image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
import co
co.loaded<typeof
type loaded<T extends CoValueClass | AnyCoSchema, R extends ResolveQuery<T> = true> = R extends boolean | undefined ? NonNullable<InstanceOfSchemaCoValuesNullable<T>> : [NonNullable<InstanceOfSchemaCoValuesNullable<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<... export loaded
Image> }) { const {
const Image: WithHelpers<CoMapSchema<{ originalSize: ZodTuple<[ZodNumber, ZodNumber], null>; placeholderDataURL: ZodOptional<ZodString>; }, $catchall<...>, Account | Group>, { ...; }>
const src: string | undefined
src, // Data URI containing the image data as a base64 string, // or a placeholder image URIconst res: "placeholder" | `${number}x${number}` | undefined
res, // The current resolutionconst originalSize: [number, number] | undefined
originalSize // The original size of the image } =useProgressiveImg({
function useProgressiveImg({ image, maxWidth, targetWidth, }: { image: co.loaded<typeof ImageDefinition> | null | undefined; maxWidth?: number; targetWidth?: number; }): { src: string | undefined; res: "placeholder" | `${number}x${number}` | undefined; originalSize: [number, number] | undefined; }
image:
image: ({ originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap) | null | undefined
image, // The image definition to load
image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
targetWidth?: number | undefined
targetWidth: 800 // Limit to resolutions up to 800px wide }); // When image is not available yet if (!const src: string | undefined
src) { return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
divReact.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="image-loading-fallback">Loading image...</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>; } // When image is loading, show a placeholder if (const res: "placeholder" | `${number}x${number}` | undefined
res === "placeholder") { return <JSX.IntrinsicElements.img: React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>
imgReact.ImgHTMLAttributes<HTMLImageElement>.src?: string | undefined
src={const src: string
src}React.ImgHTMLAttributes<HTMLImageElement>.alt?: string | undefined
alt="Loading..."React.HTMLAttributes<T>.className?: string | undefined
className="blur-effect" />; } // Full image display with custom overlay return ( <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
divReact.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="custom-image-wrapper"> <JSX.IntrinsicElements.img: React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>
imgReact.ImgHTMLAttributes<HTMLImageElement>.src?: string | undefined
src={const src: string
src}React.ImgHTMLAttributes<HTMLImageElement>.alt?: string | undefined
alt="Custom image"React.HTMLAttributes<T>.className?: string | undefined
className="custom-image" /> <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
divReact.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="image-overlay"> <JSX.IntrinsicElements.span: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
spanReact.HTMLAttributes<T>.className?: string | undefined
className="image-caption">Resolution: {const res: `${number}x${number}` | undefined
res}</JSX.IntrinsicElements.span: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
span> </JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> </JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> ); }
Understanding ImageDefinition
Behind the scenes, ImageDefinition
is a specialized CoValue that stores:
- The original image dimensions (
originalSize
) - An optional placeholder (
placeholderDataURL
) for immediate display - Multiple resolution variants of the same image as
FileStream
s
Each resolution is stored with a key in the format "widthxheight"
(e.g., "1920x1080"
, "800x450"
).
// Structure of an ImageDefinition const
image =
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
ImageDefinition.
const ImageDefinition: WithHelpers<CoMapSchema<{ originalSize: ZodTuple<[ZodNumber, ZodNumber], null>; placeholderDataURL: ZodOptional<ZodString>; }, $catchall<...>, Account | Group>, { ...; }>
create({
create: (init: { placeholderDataURL?: string | undefined; originalSize: [number, number]; }, options?: Account | Group | { owner: Account | Group; unique?: CoValueUniqueness["uniqueness"]; } | undefined) => { ...; } & ... 1 more ... & CoMap
originalSize: [number, number]
originalSize: [1920, 1080],placeholderDataURL?: string | undefined
placeholderDataURL: "data:image/jpeg;base64,/9j/4AAQSkZJRg...", }); // Accessing the highest available resolution consthighestRes =
const highestRes: { res: `${number}x${number}`; stream: import("/vercel/path0/packages/jazz-tools/dist/internal").BinaryCoStream; } | undefined
ImageDefinition.
const ImageDefinition: WithHelpers<CoMapSchema<{ originalSize: ZodTuple<[ZodNumber, ZodNumber], null>; placeholderDataURL: ZodOptional<ZodString>; }, $catchall<...>, Account | Group>, { ...; }>
highestResAvailable(
function highestResAvailable(imageDef: Loaded<import("/vercel/path0/packages/jazz-tools/dist/internal").CoMapSchema<{ originalSize: ZodTuple<[ZodNumber, ZodNumber], null>; placeholderDataURL: ZodOptional<ZodString>; }, $catchall<import("/vercel/path0/packages/jazz-tools/dist/internal").FileStreamSchema>, import("/vercel/path0/packages/jazz-tools/dist/internal").Account | import("/vercel/path0/packages/jazz-tools/dist/internal").Group>>, options?: { maxWidth?: number; targetWidth?: number; }): { res: `${number}x${number}`; stream: import("/vercel/path0/packages/jazz-tools/dist/internal").BinaryCoStream; } | undefined
image); if (
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
highestRes) {
const highestRes: { res: `${number}x${number}`; stream: import("/vercel/path0/packages/jazz-tools/dist/internal").BinaryCoStream; } | undefined
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.log(`Found resolution: ${highestRes.
const highestRes: { res: `${number}x${number}`; stream: import("/vercel/path0/packages/jazz-tools/dist/internal").BinaryCoStream; }
res: `${number}x${number}`
res}`);var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.log(`Stream: ${highestRes.
const highestRes: { res: `${number}x${number}`; stream: import("/vercel/path0/packages/jazz-tools/dist/internal").BinaryCoStream; }
stream: FileStream
stream}`); }
For more details on using ImageDefinition
directly, see the VanillaJS docs.
Fallback Behavior
highestResAvailable
returns the largest resolution that fits your constraints. If a resolution has incomplete data, it falls back to the next available lower resolution.
const
image =
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
ImageDefinition.
const ImageDefinition: WithHelpers<CoMapSchema<{ originalSize: ZodTuple<[ZodNumber, ZodNumber], null>; placeholderDataURL: ZodOptional<ZodString>; }, $catchall<...>, Account | Group>, { ...; }>
create({
create: (init: { placeholderDataURL?: string | undefined; originalSize: [number, number]; }, options?: Account | Group | { owner: Account | Group; unique?: CoValueUniqueness["uniqueness"]; } | undefined) => { ...; } & ... 1 more ... & CoMap
originalSize: [number, number]
originalSize: [1920, 1080], });image["1920x1080"] =
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
class FileStream
FileStreams are `CoFeed`s that contain binary data, collaborative versions of `Blob`s.FileStream.
FileStream.create<FileStream>(this: CoValueClass<FileStream>, options?: { owner?: Account | Group; } | Account | Group): FileStream
Create a new empty `FileStream` instance.create(); // Empty image uploadimage["800x450"] = await
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
class FileStream
FileStreams are `CoFeed`s that contain binary data, collaborative versions of `Blob`s.FileStream.
FileStream.createFromBlob(blob: Blob | File, options?: { owner?: Group | Account; onProgress?: (progress: number) => void; } | Account | Group): Promise<FileStream>
Create a `FileStream` from a `Blob` or `File`createFromBlob(const mediumSizeBlob: Blob
mediumSizeBlob); consthighestRes =
const highestRes: { res: `${number}x${number}`; stream: import("/vercel/path0/packages/jazz-tools/dist/coValues/coFeed").BinaryCoStream; } | undefined
ImageDefinition.
const ImageDefinition: WithHelpers<CoMapSchema<{ originalSize: ZodTuple<[ZodNumber, ZodNumber], null>; placeholderDataURL: ZodOptional<ZodString>; }, $catchall<...>, Account | Group>, { ...; }>
highestResAvailable(
function highestResAvailable(imageDef: Loaded<import("/vercel/path0/packages/jazz-tools/dist/internal").CoMapSchema<{ originalSize: ZodTuple<[ZodNumber, ZodNumber], null>; placeholderDataURL: ZodOptional<ZodString>; }, $catchall<import("/vercel/path0/packages/jazz-tools/dist/internal").FileStreamSchema>, import("/vercel/path0/packages/jazz-tools/dist/internal").Account | import("/vercel/path0/packages/jazz-tools/dist/internal").Group>>, options?: { maxWidth?: number; targetWidth?: number; }): { res: `${number}x${number}`; stream: import("/vercel/path0/packages/jazz-tools/dist/coValues/coFeed").BinaryCoStream; } | undefined
image);
const image: { originalSize: [number, number]; placeholderDataURL: string | undefined; } & { [key: string]: FileStream; } & CoMap
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.log(highestRes?.
const highestRes: { res: `${number}x${number}`; stream: import("/vercel/path0/packages/jazz-tools/dist/coValues/coFeed").BinaryCoStream; } | undefined
res: `${number}x${number}` | undefined
res); // 800x450