CoFeeds

CoFeeds are append-only data structures that track entries from different user sessions and accounts. Unlike other CoValues where everyone edits the same data, CoFeeds maintain separate streams for each session.

Each account can have multiple sessions (different browser tabs, devices, or app instances), making CoFeeds ideal for building features like activity logs, presence indicators, and notification systems.

The following examples demonstrate a practical use of CoFeeds:

  • Multi-cursors - track user presence on a canvas with multiple cursors and out of bounds indicators
  • Reactions - store per-user emoji reaction using a CoFeed

Creating CoFeeds

CoFeeds are defined by specifying the type of items they'll contain, similar to how you define CoLists:

// Define a schema for feed items
const 
const Activity: CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>
Activity
= import coco.
map<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>(shape: {
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}): CoMapSchema<...>
export map
map
({
timestamp: z.z.ZodDatetimestamp: import zz.
function date(params?: string | z.z.core.$ZodDateParams): z.z.ZodDate
export date
date
(),
action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">action: import zz.
literal<["watering", "planting", "harvesting", "maintenance"]>(value: ["watering", "planting", "harvesting", "maintenance"], params?: string | z.z.core.$ZodLiteralParams): z.z.ZodLiteral<...> (+1 overload)
export literal
literal
(["watering", "planting", "harvesting", "maintenance"]),
notes: z.ZodOptional<z.z.ZodString>notes: import zz.
optional<z.z.ZodString>(innerType: z.z.ZodString): z.ZodOptional<z.z.ZodString>
export optional
optional
(import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
()),
}); // Define a feed of garden activities const
const ActivityFeed: CoFeedSchema<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
ActivityFeed
= import coco.
feed<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>(element: CoMapSchema<...>): CoFeedSchema<...>
export feed
feed
(
const Activity: CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>
Activity
);
// Create a feed instance const
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
=
const ActivityFeed: CoFeedSchema<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
ActivityFeed
.
function create(init: CoFeedInit<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>, options?: {
    owner: Account | Group;
} | Account | Group): CoFeedInstance<...>
create
([]);

Ownership

Like other CoValues, you can specify ownership when creating CoFeeds.

const const teamGroup: GroupteamGroup = class Group
@categoryIdentity & Permissions
Group
.
Group.create<Group>(this: CoValueClass<Group>, options?: {
    owner: Account;
} | Account): Group
create
();
const teamGroup: GroupteamGroup.Group.addMember(member: Account, role: AccountRole): void (+1 overload)addMember(
const colleagueAccount: Account | ({
    [x: string]: any;
} & Account)
colleagueAccount
, "writer");
const
const teamFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
teamFeed
=
const ActivityFeed: CoFeedSchema<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
ActivityFeed
.
function create(init: CoFeedInit<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>, options?: {
    owner: Account | Group;
} | Account | Group): CoFeedInstance<...>
create
([], { owner: Group | Accountowner: const teamGroup: GroupteamGroup });

See Groups as permission scopes for more information on how to use groups to control access to CoFeeds.

Reading from CoFeeds

Since CoFeeds are made of entries from users over multiple sessions, you can access entries in different ways - from a specific user's session or from their account as a whole.

Per-Session Access

To retrieve entries from a session:

// Get the feed for a specific session
const 
const sessionFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
sessionFeed
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.perSession: {
    [key: `${RawAccountID}_session_z${string}`]: CoFeedEntry<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap>;
    [key: `sealer_z${string}/signer_z${string}_session_z${string}`]: CoFeedEntry<...>;
}
The per-session view of this `CoFeed`
@categoryContent
perSession
[const sessionId: `${RawAccountID}_session_z${string}` | `sealer_z${string}/signer_z${string}_session_z${string}`sessionId];
// Latest entry from a session 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 sessionFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
sessionFeed
?.
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null
value
?.action: "watering" | "planting" | "harvesting" | "maintenance" | undefinedaction); // "watering"

For convenience, you can also access the latest entry from the current session with inCurrentSession:

// Get the feed for the current session
const 
const currentSessionFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
currentSessionFeed
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.inCurrentSession: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
The current session's view of this `CoFeed` This is a shortcut for `this.perSession` where the session ID is the current session ID.
@categoryContent
inCurrentSession
;
// Latest entry from the current session 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 currentSessionFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
currentSessionFeed
?.
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null | undefined
value
?.action: "watering" | "planting" | "harvesting" | "maintenance" | undefinedaction); // "harvesting"

Per-Account Access

To retrieve entries from a specific account (with entries from all sessions combined) use perAccount:

// Get the feed for a specific account
const 
const accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.perAccount: {
    [key: string]: CoFeedEntry<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap>;
}
The per-account view of this `CoFeed`
@example```ts // Access entries directly by account ID const aliceEntries = feed[aliceAccount.id]; console.log(aliceEntries.value); // Latest value from Alice // Iterate through all accounts' entries for (const [accountId, entries] of Object.entries(feed)) { console.log(`Latest entry from ${accountId}:`, entries.value); // Access all entries from this account for (const entry of entries.all) { console.log(`Entry made at ${entry.madeAt}:`, entry.value); } } ```@categoryContent
perAccount
[const accountId: stringaccountId];
// Latest entry from the account 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 accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
.
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null
value
?.action: "watering" | "planting" | "harvesting" | "maintenance" | undefinedaction); // "watering"

For convenience, you can also access the latest entry from the current account with byMe:

// Get the feed for the current account
const 
const myLatestEntry: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
myLatestEntry
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.byMe: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
The current account's view of this `CoFeed`
@categoryContent
byMe
;
// Latest entry from the current account 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 myLatestEntry: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
myLatestEntry
?.
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null | undefined
value
?.action: "watering" | "planting" | "harvesting" | "maintenance" | undefinedaction); // "harvesting"

Feed Entries

All Entries

To retrieve all entries from a CoFeed:

// Get the feeds for a specific account and session
const 
const accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.perAccount: {
    [key: string]: CoFeedEntry<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap>;
}
The per-account view of this `CoFeed`
@example```ts // Access entries directly by account ID const aliceEntries = feed[aliceAccount.id]; console.log(aliceEntries.value); // Latest value from Alice // Iterate through all accounts' entries for (const [accountId, entries] of Object.entries(feed)) { console.log(`Latest entry from ${accountId}:`, entries.value); // Access all entries from this account for (const entry of entries.all) { console.log(`Entry made at ${entry.madeAt}:`, entry.value); } } ```@categoryContent
perAccount
[const accountId: stringaccountId];
const
const sessionFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
sessionFeed
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.perSession: {
    [key: `${RawAccountID}_session_z${string}`]: CoFeedEntry<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap>;
    [key: `sealer_z${string}/signer_z${string}_session_z${string}`]: CoFeedEntry<...>;
}
The per-session view of this `CoFeed`
@categoryContent
perSession
[const sessionId: `${RawAccountID}_session_z${string}` | `sealer_z${string}/signer_z${string}_session_z${string}`sessionId];
// Iterate over all entries from the account for (const
const entry: SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
of
const accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
.
all: IterableIterator<SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>>
all
) {
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 entry: SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
.
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null
value
);
} // Iterate over all entries from the session for (const
const entry: SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
of
const sessionFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
sessionFeed
.
all: IterableIterator<SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>>
all
) {
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 entry: SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
.
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null
value
);
}

Latest Entry

To retrieve the latest entry from a CoFeed, ie. the last update:

// Get the latest entry from the current account
const 
const latestEntry: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
latestEntry
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.byMe: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
The current account's view of this `CoFeed`
@categoryContent
byMe
;
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
(`My last action was ${
const latestEntry: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | undefined
latestEntry
?.
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null | undefined
value
?.action: "watering" | "planting" | "harvesting" | "maintenance" | undefinedaction}`);
// "My last action was harvesting" // Get the latest entry from each account const
const latestEntriesByAccount: {
    accountName: string | undefined;
    value: NonNullable<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap> | null;
}[]
latestEntriesByAccount
= var Object: ObjectConstructor
Provides functionality common to all JavaScript objects.
Object
.
ObjectConstructor.values<CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>>(o: {
    [s: string]: CoFeedEntry<{
        ...;
    } & CoMap>;
} | ArrayLike<...>): CoFeedEntry<...>[] (+1 overload)
Returns an array of values of the enumerable own properties 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.
values
(
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.perAccount: {
    [key: string]: CoFeedEntry<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap>;
}
The per-account view of this `CoFeed`
@example```ts // Access entries directly by account ID const aliceEntries = feed[aliceAccount.id]; console.log(aliceEntries.value); // Latest value from Alice // Iterate through all accounts' entries for (const [accountId, entries] of Object.entries(feed)) { console.log(`Latest entry from ${accountId}:`, entries.value); // Access all entries from this account for (const entry of entries.all) { console.log(`Entry made at ${entry.madeAt}:`, entry.value); } } ```@categoryContent
perAccount
).
Array<CoFeedEntry<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>>.map<{
    accountName: string | undefined;
    value: NonNullable<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap> | null;
}>(callbackfn: (value: CoFeedEntry<...>, index: number, array: CoFeedEntry<...>[]) => {
    accountName: string | undefined;
    value: NonNullable<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap> | null;
}, thisArg?: any): {
    accountName: string | undefined;
    value: NonNullable<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap> | null;
}[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method 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.
map
(
entry: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
=> ({
accountName: string | undefinedaccountName:
entry: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
.by: Account | nullby?.Account.profile: Profile | null | undefinedprofile?.Profile.name: string | undefinedname,
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null
value
:
entry: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
.
value: NonNullable<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap> | null
value
,
}));

Writing to CoFeeds

CoFeeds are append-only; you can add new items, but not modify existing ones. This creates a chronological record of events or activities.

Adding Items

// Log a new activity
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.push(...items: ({
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap)[]): void
Push items to this `CoFeed` Items are appended to the current session's log. Each session (tab, device, app instance) maintains its own append-only log, which is then aggregated into the per-account view.
@example```ts // Adds items to current session's log feed.push("item1", "item2"); // View items from current session console.log(feed.inCurrentSession); // View aggregated items from all sessions for current account console.log(feed.byMe); ```@categoryContent
push
(
const Activity: CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>
Activity
.
create: (init: {
    notes?: string | undefined;
    timestamp: Date;
    action: NonNullable<"watering" | "planting" | "harvesting" | "maintenance">;
}, options?: {
    owner: Account | Group;
    unique?: CoValueUniqueness["uniqueness"];
} | Account | Group) => {
    ...;
} & CoMap
create
({
timestamp: Datetimestamp: new
var Date: DateConstructor
new () => Date (+4 overloads)
Date
(),
action: NonNullable<"watering" | "planting" | "harvesting" | "maintenance">action: "watering", notes?: string | undefinednotes: "Extra water for new seedlings" }));

Each item is automatically associated with the current user's session. You don't need to specify which session the item belongs to - Jazz handles this automatically.

Understanding Session Context

Each entry is automatically added to the current session's feed. When a user has multiple open sessions (like both a mobile app and web browser), each session creates its own separate entries:

// On mobile device:
const fromMobileFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
fromMobileFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.push(...items: ({
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap)[]): void
Push items to this `CoFeed` Items are appended to the current session's log. Each session (tab, device, app instance) maintains its own append-only log, which is then aggregated into the per-account view.
@example```ts // Adds items to current session's log feed.push("item1", "item2"); // View items from current session console.log(feed.inCurrentSession); // View aggregated items from all sessions for current account console.log(feed.byMe); ```@categoryContent
push
(
const Activity: CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>
Activity
.
create: (init: {
    notes?: string | undefined;
    timestamp: Date;
    action: NonNullable<"watering" | "planting" | "harvesting" | "maintenance">;
}, options?: {
    owner: Account | Group;
    unique?: CoValueUniqueness["uniqueness"];
} | Account | Group) => {
    ...;
} & CoMap
create
({
timestamp: Datetimestamp: new
var Date: DateConstructor
new () => Date (+4 overloads)
Date
(),
action: NonNullable<"watering" | "planting" | "harvesting" | "maintenance">action: "harvesting", notes?: string | undefinednotes: "Vegetable patch" })); // On web browser (same user):
const fromBrowserFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
fromBrowserFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.push(...items: ({
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap)[]): void
Push items to this `CoFeed` Items are appended to the current session's log. Each session (tab, device, app instance) maintains its own append-only log, which is then aggregated into the per-account view.
@example```ts // Adds items to current session's log feed.push("item1", "item2"); // View items from current session console.log(feed.inCurrentSession); // View aggregated items from all sessions for current account console.log(feed.byMe); ```@categoryContent
push
(
const Activity: CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>
Activity
.
create: (init: {
    notes?: string | undefined;
    timestamp: Date;
    action: NonNullable<"watering" | "planting" | "harvesting" | "maintenance">;
}, options?: {
    owner: Account | Group;
    unique?: CoValueUniqueness["uniqueness"];
} | Account | Group) => {
    ...;
} & CoMap
create
({
timestamp: Datetimestamp: new
var Date: DateConstructor
new () => Date (+4 overloads)
Date
(),
action: NonNullable<"watering" | "planting" | "harvesting" | "maintenance">action: "planting", notes?: string | undefinednotes: "Flower bed" })); // These are separate entries in the same feed, from the same account

Metadata

CoFeeds support metadata, which is useful for tracking information about the feed itself.

By

The by property is the account that made the entry.

const 
const accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.perAccount: {
    [key: string]: CoFeedEntry<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap>;
}
The per-account view of this `CoFeed`
@example```ts // Access entries directly by account ID const aliceEntries = feed[aliceAccount.id]; console.log(aliceEntries.value); // Latest value from Alice // Iterate through all accounts' entries for (const [accountId, entries] of Object.entries(feed)) { console.log(`Latest entry from ${accountId}:`, entries.value); // Access all entries from this account for (const entry of entries.all) { console.log(`Entry made at ${entry.madeAt}:`, entry.value); } } ```@categoryContent
perAccount
[const accountId: stringaccountId];
// Get the account that made the last entry 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 accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
?.by: Account | nullby);

MadeAt

The madeAt property is a timestamp of when the entry was added to the feed.

const 
const accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
=
const activityFeed: CoFeedInstance<CoMapSchema<{
    timestamp: z.z.ZodDate;
    action: z.z.ZodLiteral<"watering" | "planting" | "harvesting" | "maintenance">;
    notes: z.ZodOptional<z.z.ZodString>;
}>>
activityFeed
.
CoFeed<{ timestamp: Date; action: "watering" | "planting" | "harvesting" | "maintenance"; notes: string | undefined; } & CoMap>.perAccount: {
    [key: string]: CoFeedEntry<{
        timestamp: Date;
        action: "watering" | "planting" | "harvesting" | "maintenance";
        notes: string | undefined;
    } & CoMap>;
}
The per-account view of this `CoFeed`
@example```ts // Access entries directly by account ID const aliceEntries = feed[aliceAccount.id]; console.log(aliceEntries.value); // Latest value from Alice // Iterate through all accounts' entries for (const [accountId, entries] of Object.entries(feed)) { console.log(`Latest entry from ${accountId}:`, entries.value); // Access all entries from this account for (const entry of entries.all) { console.log(`Entry made at ${entry.madeAt}:`, entry.value); } } ```@categoryContent
perAccount
[const accountId: stringaccountId];
// Get the timestamp of the last update 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 accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
?.madeAt: DatemadeAt);
// Get the timestamp of each entry for (const
const entry: SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
of
const accountFeed: CoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
accountFeed
.
all: IterableIterator<SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>>
all
) {
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 entry: SingleCoFeedEntry<{
    timestamp: Date;
    action: "watering" | "planting" | "harvesting" | "maintenance";
    notes: string | undefined;
} & CoMap>
entry
.madeAt: DatemadeAt);
}

Best Practices

When to Use CoFeeds

  • Use CoFeeds when:

    • You need to track per-user/per-session data
    • Time-based information matters (activity logs, presence)
  • Consider alternatives when:

    • Data needs to be collaboratively edited (use CoMaps or CoLists)
    • You need structured relationships (use CoMaps/CoLists with references)