History Patterns

Jazz's automatic history tracking enables powerful patterns for building collaborative features. Here's how to implement common history-based functionality.

Audit Logs

Build a complete audit trail showing all changes to your data:

function 
function getAuditLog(task: Task): {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
getAuditLog
(
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
:
type Task = {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
Task
) {
const const changes: any[]changes = []; // Collect edits for all fields const const fields: string[]fields = var Object: ObjectConstructor
Provides functionality common to all JavaScript objects.
Object
.ObjectConstructor.keys(o: {}): string[] (+1 overload)
Returns the names of the enumerable string properties and methods of an object.
@paramo Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
keys
(
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
);
for (const const field: stringfield of const fields: string[]fields) { const const editField: "title" | "status"editField = const field: stringfield as keyof typeof
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
;
if (!
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
[const editField: "title" | "status"editField]) continue;
for (const const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit of
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
[const editField: "title" | "status"editField].all: CoMapEdit<string>[] | CoMapEdit<"todo" | "in-progress" | "completed">[]all) {
const changes: any[]changes.Array<any>.push(...items: any[]): number
Appends new elements to the end of an array, and returns the new length of the array.
@paramitems New elements to add to the array.
push
({
field: stringfield, value: string | undefinedvalue: const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit.value?: string | undefinedvalue, by: Account | nullby: const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit.by: Account | nullby, at: Dateat: const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit.madeAt: DatemadeAt, }); } } // Sort by timestamp (newest first) return
const changes: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
changes
.
Array<{ field: string; value: string | undefined; by: Account | null; at: Date; }>.sort(compareFn?: ((a: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}, b: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}) => number) | undefined): {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
Sorts an array in place. This method mutates the array and returns a reference to the same array.
@paramcompareFn Function used to determine the order of the elements. It is expected to return a negative value if the first argument is less than the second argument, zero if they're equal, and a positive value otherwise. If omitted, the elements are sorted in ascending, ASCII character order. ```ts [11,2,22,1].sort((a, b) => a - b) ```
sort
((
a: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
a
,
b: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
b
) =>
b: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
b
.at: Dateat.Date.getTime(): number
Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC.
getTime
() -
a: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
a
.at: Dateat.Date.getTime(): number
Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC.
getTime
());
} // Use it to show change history const
const auditLog: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
auditLog
=
function getAuditLog(task: Task): {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
getAuditLog
(
const task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
);
const auditLog: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
auditLog
.
Array<{ field: string; value: string | undefined; by: Account | null; at: Date; }>.forEach(callbackfn: (value: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}, index: number, array: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]) => void, thisArg?: any): void
Performs the specified action for each element in an array.
@paramcallbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
forEach
((
entry: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
entry
) => {
const const when: stringwhen =
entry: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
entry
.at: Dateat.Date.toLocaleString(locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string (+2 overloads)
Converts a date and time to a string by using the current or specified locale.
@paramlocales A locale string, array of locale strings, Intl.Locale object, or array of Intl.Locale objects that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.@paramoptions An object that contains one or more properties that specify comparison options.
toLocaleString
();
const const who: string | undefinedwho =
entry: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
entry
.by: Account | nullby?.Account.profile: Profile | null | undefinedprofile?.Profile.name: string | undefinedname;
const const what: stringwhat =
entry: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
entry
.field: stringfield;
const const value: string | undefinedvalue =
entry: {
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
entry
.value: string | undefinedvalue;
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 ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
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.
@sincev0.1.100
log
(`${const when: stringwhen} - ${const who: string | undefinedwho} changed ${const what: stringwhat} to "${const value: string | undefinedvalue}"`);
// 22/05/2025, 12:00:00 - Alice changed title to "New task" });

Activity Feeds

Show recent activity across your application:

function 
function getRecentActivity(projects: Project[], since: Date): {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
getRecentActivity
(
projects: ({
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap)[]
projects
:
type Project = {
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
Project
[], since: Datesince: Date) {
const const activity: any[]activity = []; for (const
const project: {
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
project
of
projects: ({
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap)[]
projects
) {
// Get all fields that might have edits const const fields: string[]fields = var Object: ObjectConstructor
Provides functionality common to all JavaScript objects.
Object
.ObjectConstructor.keys(o: {}): string[] (+1 overload)
Returns the names of the enumerable string properties and methods of an object.
@paramo Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
keys
(
const project: {
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
project
);
// Check each field for edit history for (const const field: stringfield of const fields: string[]fields) { const const editField: "name" | "status"editField = const field: stringfield as keyof typeof
const project: {
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
project
.
CoMap._edits: {
    name?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
;
// Skip if no edits exist for this field if (!
const project: {
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
project
.
CoMap._edits: {
    name?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
[const editField: "name" | "status"editField]) continue;
for (const const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit of
const project: {
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
project
.
CoMap._edits: {
    name?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
[const editField: "name" | "status"editField].all: CoMapEdit<string>[] | CoMapEdit<"todo" | "in-progress" | "completed">[]all) {
// Only include edits made after the 'since' date if (const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit.madeAt: DatemadeAt > since: Datesince) { const activity: any[]activity.Array<any>.push(...items: any[]): number
Appends new elements to the end of an array, and returns the new length of the array.
@paramitems New elements to add to the array.
push
({
project: stringproject:
const project: {
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
project
.name: stringname,
field: stringfield, value: string | undefinedvalue: const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit.value?: string | undefinedvalue, by: Account | nullby: const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit.by: Account | nullby, at: Dateat: const edit: CoMapEdit<string> | CoMapEdit<"todo" | "in-progress" | "completed">edit.madeAt: DatemadeAt }); } } } } return
const activity: {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
activity
.
Array<{ project: string; field: string; value: string | undefined; by: Account | null; at: Date; }>.sort(compareFn?: ((a: {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}, b: {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}) => number) | undefined): {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
Sorts an array in place. This method mutates the array and returns a reference to the same array.
@paramcompareFn Function used to determine the order of the elements. It is expected to return a negative value if the first argument is less than the second argument, zero if they're equal, and a positive value otherwise. If omitted, the elements are sorted in ascending, ASCII character order. ```ts [11,2,22,1].sort((a, b) => a - b) ```
sort
((
a: {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
a
,
b: {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
b
) =>
b: {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
b
.at: Dateat.Date.getTime(): number
Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC.
getTime
() -
a: {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}
a
.at: Dateat.Date.getTime(): number
Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC.
getTime
());
} // Show activity from the last hour const const hourAgo: DatehourAgo = new
var Date: DateConstructor
new (value: number | string | Date) => Date (+4 overloads)
Date
(var Date: DateConstructor
Enables basic storage and retrieval of dates and times.
Date
.DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).
now
() - 60 * 60 * 1000);
const
const recentActivity: {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
recentActivity
=
function getRecentActivity(projects: Project[], since: Date): {
    project: string;
    field: string;
    value: string | undefined;
    by: Account | null;
    at: Date;
}[]
getRecentActivity
(
const myProjects: ({
    name: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap)[]
myProjects
, const hourAgo: DatehourAgo);
// [{ // project: "New project", // field: "name", // value: "New project", // by: Account, // at: Date // }]

Change Indicators

Show when something was last updated:

function 
function getLastUpdated(task: Task): {
    updatedBy: any;
    updatedAt: any;
    message: string;
} | null
getLastUpdated
(
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
:
type Task = {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
Task
) {
// Find the most recent edit across all fields let let lastEdit: anylastEdit: any = null; for (const const field: stringfield of var Object: ObjectConstructor
Provides functionality common to all JavaScript objects.
Object
.ObjectConstructor.keys(o: {}): string[] (+1 overload)
Returns the names of the enumerable string properties and methods of an object.
@paramo Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
keys
(
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
)) {
const const editField: "title" | "status"editField = const field: stringfield as keyof typeof
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
;
// Skip if no edits exist for this field if (!
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
[const editField: "title" | "status"editField]) continue;
const const fieldEdit: LastAndAllCoMapEdits<string> | LastAndAllCoMapEdits<"todo" | "in-progress" | "completed">fieldEdit =
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
[const editField: "title" | "status"editField];
if (const fieldEdit: LastAndAllCoMapEdits<string> | LastAndAllCoMapEdits<"todo" | "in-progress" | "completed">fieldEdit && (!let lastEdit: anylastEdit || const fieldEdit: LastAndAllCoMapEdits<string> | LastAndAllCoMapEdits<"todo" | "in-progress" | "completed">fieldEdit.madeAt: DatemadeAt > let lastEdit: anylastEdit.madeAt)) { let lastEdit: anylastEdit = const fieldEdit: LastAndAllCoMapEdits<string> | LastAndAllCoMapEdits<"todo" | "in-progress" | "completed">fieldEdit; } } if (!let lastEdit: anylastEdit) return null; return { updatedBy: anyupdatedBy: let lastEdit: anylastEdit.by?.profile?.name, updatedAt: anyupdatedAt: let lastEdit: anylastEdit.madeAt, message: stringmessage: `Last updated by ${let lastEdit: anylastEdit.by?.profile?.name} at ${let lastEdit: anylastEdit.madeAt.toLocaleString()}` }; } const
const lastUpdated: {
    updatedBy: any;
    updatedAt: any;
    message: string;
} | null
lastUpdated
=
function getLastUpdated(task: Task): {
    updatedBy: any;
    updatedAt: any;
    message: string;
} | null
getLastUpdated
(
const task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
);
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 ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
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.
@sincev0.1.100
log
(
const lastUpdated: {
    updatedBy: any;
    updatedAt: any;
    message: string;
} | null
lastUpdated
?.message: string | undefinedmessage);
// "Last updated by Alice at 22/05/2025, 12:00:00"

Finding Specific Changes

Query history for specific events:

// Find when a task was completed
function function findCompletionTime(task: Task): Date | nullfindCompletionTime(
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
:
type Task = {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
Task
): Date | null {
if (!
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
.status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefinedstatus) return null;
// find() returns the FIRST completion time // If status toggles (completed → in-progress → completed), // this gives you the earliest completion, not the latest const const completionEdit: CoMapEdit<"todo" | "in-progress" | "completed"> | undefinedcompletionEdit =
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
.status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed">status.all: CoMapEdit<"todo" | "in-progress" | "completed">[]all.Array<CoMapEdit<"todo" | "in-progress" | "completed">>.find(predicate: (value: CoMapEdit<"todo" | "in-progress" | "completed">, index: number, obj: CoMapEdit<"todo" | "in-progress" | "completed">[]) => unknown, thisArg?: any): CoMapEdit<...> | undefined (+1 overload)
Returns the value of the first element in the array where predicate is true, and undefined otherwise.
@parampredicate find calls predicate once for each element of the array, in ascending order, until it finds one where predicate returns true. If such an element is found, find immediately returns that element value. Otherwise, find returns undefined.@paramthisArg If provided, it will be used as the this value for each invocation of predicate. If it is not provided, undefined is used instead.
find
(
edit: CoMapEdit<"todo" | "in-progress" | "completed">edit => edit: CoMapEdit<"todo" | "in-progress" | "completed">edit.value?: "todo" | "in-progress" | "completed" | undefinedvalue === "completed" ); return const completionEdit: CoMapEdit<"todo" | "in-progress" | "completed"> | undefinedcompletionEdit?.madeAt: Date | undefinedmadeAt || null; } // To get the LATEST completion time instead reverse the array, then find: function function findLatestCompletionTime(task: Task): Date | nullfindLatestCompletionTime(
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
:
type Task = {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
Task
): Date | null {
if (!
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
.status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefinedstatus) return null;
// Reverse and find (stops at first match) const const latestCompletionEdit: CoMapEdit<"todo" | "in-progress" | "completed"> | undefinedlatestCompletionEdit =
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
.status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed">status.all: CoMapEdit<"todo" | "in-progress" | "completed">[]all
.Array<CoMapEdit<"todo" | "in-progress" | "completed">>.slice(start?: number, end?: number): CoMapEdit<"todo" | "in-progress" | "completed">[]
Returns a copy of a section of an array. For both start and end, a negative index can be used to indicate an offset from the end of the array. For example, -2 refers to the second to last element of the array.
@paramstart The beginning index of the specified portion of the array. If start is undefined, then the slice begins at index 0.@paramend The end index of the specified portion of the array. This is exclusive of the element at the index 'end'. If end is undefined, then the slice extends to the end of the array.
slice
() // Create copy to avoid mutating original
.Array<CoMapEdit<"todo" | "in-progress" | "completed">>.reverse(): CoMapEdit<"todo" | "in-progress" | "completed">[]
Reverses the elements in an array in place. This method mutates the array and returns a reference to the same array.
reverse
()
.Array<CoMapEdit<"todo" | "in-progress" | "completed">>.find(predicate: (value: CoMapEdit<"todo" | "in-progress" | "completed">, index: number, obj: CoMapEdit<"todo" | "in-progress" | "completed">[]) => unknown, thisArg?: any): CoMapEdit<...> | undefined (+1 overload)
Returns the value of the first element in the array where predicate is true, and undefined otherwise.
@parampredicate find calls predicate once for each element of the array, in ascending order, until it finds one where predicate returns true. If such an element is found, find immediately returns that element value. Otherwise, find returns undefined.@paramthisArg If provided, it will be used as the this value for each invocation of predicate. If it is not provided, undefined is used instead.
find
(edit: CoMapEdit<"todo" | "in-progress" | "completed">edit => edit: CoMapEdit<"todo" | "in-progress" | "completed">edit.value?: "todo" | "in-progress" | "completed" | undefinedvalue === "completed");
return const latestCompletionEdit: CoMapEdit<"todo" | "in-progress" | "completed"> | undefinedlatestCompletionEdit?.madeAt: Date | undefinedmadeAt || null; } 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 ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
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.
@sincev0.1.100
log
(function findCompletionTime(task: Task): Date | nullfindCompletionTime(
const task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
)); // First completion
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 ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
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.
@sincev0.1.100
log
(function findLatestCompletionTime(task: Task): Date | nullfindLatestCompletionTime(
const task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
)); // Most recent completion
// Find who made a specific change function function findWhoChanged(task: Task, field: string, value: any): Account | nullfindWhoChanged(
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
:
type Task = {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
Task
, field: stringfield: string, value: anyvalue: any) {
const const edits: LastAndAllCoMapEdits<string> | LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefinededits =
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
[field: stringfield as keyof typeof
task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
.
CoMap._edits: {
    title?: LastAndAllCoMapEdits<string> | undefined;
    status?: LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefined;
}
@categoryCollaboration
_edits
];
if (!const edits: LastAndAllCoMapEdits<string> | LastAndAllCoMapEdits<"todo" | "in-progress" | "completed"> | undefinededits) return null; const const matchingEdit: CoMapEdit<string> | undefinedmatchingEdit = const edits: LastAndAllCoMapEdits<string> | LastAndAllCoMapEdits<"todo" | "in-progress" | "completed">edits.all: CoMapEdit<"todo" | "in-progress" | "completed">[] | CoMapEdit<string>[]all.Array<T>.find(predicate: (value: CoMapEdit<string>, index: number, obj: CoMapEdit<string>[]) => unknown, thisArg?: any): CoMapEdit<string> | undefined
Returns the value of the first element in the array where predicate is true, and undefined otherwise.
@parampredicate find calls predicate once for each element of the array, in ascending order, until it finds one where predicate returns true. If such an element is found, find immediately returns that element value. Otherwise, find returns undefined.@paramthisArg If provided, it will be used as the this value for each invocation of predicate. If it is not provided, undefined is used instead.
find
(edit: CoMapEdit<string>edit => edit: CoMapEdit<string>edit.value?: string | undefinedvalue === value: anyvalue);
return const matchingEdit: CoMapEdit<string> | undefinedmatchingEdit?.by: Account | null | undefinedby || null; } const const account: Account | nullaccount = function findWhoChanged(task: Task, field: string, value: any): Account | nullfindWhoChanged(
const task: {
    title: string;
    status: "todo" | "in-progress" | "completed";
} & CoMap
task
, "status", "completed");
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 ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
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.
@sincev0.1.100
log
(const account: Account | nullaccount?.Account.profile: Profile | null | undefinedprofile?.Profile.name: string | undefinedname);
// Alice

Further Reading