History
Jazz tracks every change to your data automatically. See who changed what, when they did it, and even look at your data from any point in the past.
See the version history example for reference.
Let's use the following schema to see how we can use the edit history.
const
Task =
const Task: CoMapSchema<{ title: z.z.ZodString; status: z.z.ZodLiteral<"todo" | "in-progress" | "completed">; }>
import co
co.map({
map<{ title: z.z.ZodString; status: z.z.ZodLiteral<"todo" | "in-progress" | "completed">; }>(shape: { title: z.z.ZodString; status: z.z.ZodLiteral<"todo" | "in-progress" | "completed">; }): CoMapSchema<...> export map
title: z.z.ZodString
title:import z
z.string(),
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString export string
status: z.z.ZodLiteral<"todo" | "in-progress" | "completed">
status:import z
z.literal(["todo", "in-progress", "completed"]), });
literal<["todo", "in-progress", "completed"]>(value: ["todo", "in-progress", "completed"], params?: string | z.z.core.$ZodLiteralParams): z.z.ZodLiteral<"todo" | "in-progress" | "completed"> (+1 overload) export literal
The _edits Property
Every CoValue has an _edits
property that contains the complete history for each field. Here's
how to get the edit history for task.status
:
// Access edit history for a field
task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
_edits.
CoMap._edits: { title?: LastAndAllCoMapEdits<string> | undefined; status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined; }
status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
status // Returns the latest edittask.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
_edits.
CoMap._edits: { title?: LastAndAllCoMapEdits<string> | undefined; status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined; }
status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
status?.all: CoMapEdit<"todo" | "in-progress" | "completed">[] | undefined
all // Returns array of all edits in chronological order // Check if edits exist if (task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
_edits.
CoMap._edits: { title?: LastAndAllCoMapEdits<string> | undefined; status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined; }
status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
status) { constconst name: string | undefined
name =task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
_edits.
CoMap._edits: { title?: LastAndAllCoMapEdits<string> | undefined; status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined; }
status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed">
status.by: Account | null
by?.Account.profile: Profile | null | undefined
profile?.Profile.name: string | undefined
name;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(`Last changed by ${const name: string | undefined
name}`); }
Edit Structure
Each edit contains:
const
const edit: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
edit =task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
_edits.
CoMap._edits: { title?: LastAndAllCoMapEdits<string> | undefined; status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined; }
status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
status; // The edit object contains:const edit: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
edit?.value?: "todo" | "in-progress" | "completed" | undefined
value // The new value: "in-progress"const edit: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
edit?.by: Account | null | undefined
by // Account that made the changeconst edit: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
edit?.madeAt: Date | undefined
madeAt // Date when the change occurred
Accessing History
Latest Edit
Get the most recent change to a field:
// Direct access to latest edit const
const latest: LastAndAllCoMapEdits<string> | undefined
latest =task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
_edits.
CoMap._edits: { title?: LastAndAllCoMapEdits<string> | undefined; status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined; }
title?: LastAndAllCoMapEdits<string> | undefined
title; if (const latest: LastAndAllCoMapEdits<string> | undefined
latest) {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(`Title is now "${const latest: LastAndAllCoMapEdits<string>
latest.value?: string | undefined
value}"`); }
All Edits
Get the complete history for a field:
// Get all edits (chronologically) const
const allStatusEdits: CoMapEdit<"todo" | "in-progress" | "completed">[]
allStatusEdits =task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
_edits.
CoMap._edits: { title?: LastAndAllCoMapEdits<string> | undefined; status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined; }
status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
status?.all: CoMapEdit<"todo" | "in-progress" | "completed">[] | undefined
all || [];const allStatusEdits: CoMapEdit<"todo" | "in-progress" | "completed">[]
allStatusEdits.Array<CoMapEdit<"todo" | "in-progress" | "completed">>.forEach(callbackfn: (value: CoMapEdit<"todo" | "in-progress" | "completed">, index: number, array: CoMapEdit<"todo" | "in-progress" | "completed">[]) => void, thisArg?: any): void
Performs the specified action for each element in an array.forEach((edit: CoMapEdit<"todo" | "in-progress" | "completed">
edit,index: number
index) => {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(`Edit ${index: number
index}: ${edit: CoMapEdit<"todo" | "in-progress" | "completed">
edit.value?: "todo" | "in-progress" | "completed" | undefined
value} at ${edit: CoMapEdit<"todo" | "in-progress" | "completed">
edit.madeAt: Date
madeAt.Date.toISOString(): string
Returns a date as a string value in ISO format.toISOString()}`); }); // Edit 0: todo at 2025-05-22T13:00:00.000Z // Edit 1: in-progress at 2025-05-22T14:00:00.000Z // Edit 2: completed at 2025-05-22T15:30:00.000Z
Initial Values
The first edit contains the initial value:
const
const allEdits: CoMapEdit<"todo" | "in-progress" | "completed">[]
allEdits =task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
_edits.
CoMap._edits: { title?: LastAndAllCoMapEdits<string> | undefined; status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined; }
status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined
status?.all: CoMapEdit<"todo" | "in-progress" | "completed">[] | undefined
all || []; constconst initialValue: "todo" | "in-progress" | "completed" | undefined
initialValue =const allEdits: CoMapEdit<"todo" | "in-progress" | "completed">[]
allEdits[0]?.value?: "todo" | "in-progress" | "completed" | undefined
value;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(`Started as: ${const initialValue: "todo" | "in-progress" | "completed" | undefined
initialValue}`); // Started as: todo
Created Date and Last Updated Date
To show created date and last updated date, use the _createdAt
and _lastUpdatedAt
getters.
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(newDate(
var Date: DateConstructor new (value: number | string | Date) => Date (+4 overloads)
task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
CoMap._createdAt: number
The timestamp of the creation time of the CoMap_createdAt));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(newDate(
var Date: DateConstructor new (value: number | string | Date) => Date (+4 overloads)
task.
const task: { title: string; status: "todo" | "in-progress" | "completed"; } & CoMap
CoMap._lastUpdatedAt: number
The timestamp of the last updated time of the CoMap_lastUpdatedAt));
Requirements
- CoValues must be loaded to access history (see Subscription & Loading)
- History is only available for fields defined in your schema
- Edit arrays are ordered chronologically (oldest to newest)
Common Patterns
For practical implementations using history, see History Patterns:
- Building audit logs
- Creating activity feeds
- Implementing undo/redo
- Showing change indicators
- Querying historical data