Events & Logging

Event Types

ElectroDB can be supplied with callbacks (see: loggers and listeners to learn how) to be invoked after certain request lifecycles. This can be useful for logging, analytics, expanding functionality, and more. The following are events currently supported by ElectroDB — if you would like to see additional events feel free to create a GitHub issue to discuss your concept/need!

Query Event

The query event occurs when a query is made via the terminal method go() . The event includes the exact parameters given to the provided client, the ElectroDB method used, and the ElectroDB configuration provided.

Type:

interface ElectroQueryEvent<P extends any = any> {
  type: "query";
  method:
    | "put"
    | "get"
    | "query"
    | "scan"
    | "update"
    | "delete"
    | "remove"
    | "patch"
    | "create"
    | "batchGet"
    | "batchWrite";
  config: any;
  params: P;
}

Example Input:

const prop1 = "22874c81-27c4-4264-92c3-b280aa79aa30";
const prop2 = "366aade8-a7c0-4328-8e14-0331b185de4e";
const prop3 = "3ec9ed0c-7497-4d05-bdb8-86c09a618047";

entity.update({ prop1, prop2 }).set({ prop3 }).go();

Example Output:

{
  "type": "query",
  "method": "update",
  "params": {
    "UpdateExpression": "SET #prop3 = :prop3_u0, #prop1 = :prop1_u0, #prop2 = :prop2_u0, #__edb_e__ = :__edb_e___u0, #__edb_v__ = :__edb_v___u0",
    "ExpressionAttributeNames": {
      "#prop3": "prop3",
      "#prop1": "prop1",
      "#prop2": "prop2",
      "#__edb_e__": "__edb_e__",
      "#__edb_v__": "__edb_v__"
    },
    "ExpressionAttributeValues": {
      ":prop3_u0": "3ec9ed0c-7497-4d05-bdb8-86c09a618047",
      ":prop1_u0": "22874c81-27c4-4264-92c3-b280aa79aa30",
      ":prop2_u0": "366aade8-a7c0-4328-8e14-0331b185de4e",
      ":__edb_e___u0": "entity",
      ":__edb_v___u0": "1"
    },
    "TableName": "electro",
    "Key": {
      "pk": "$test#prop1_22874c81-27c4-4264-92c3-b280aa79aa30",
      "sk": "$testcollection#entity_1#prop2_366aade8-a7c0-4328-8e14-0331b185de4e"
    }
  },
  "config": {}
}

Results Event

The results event occurs when results are returned from DynamoDB. The event includes the exact results returned from the provided client, the ElectroDB method used, and the ElectroDB configuration provided. Note this event handles both failed (or thrown) results in addition to returned (or resolved) results.

Pro-Tip: Use this event to hook into the DynamoDB’s consumed capacity statistics to learn more about the impact and cost associated with your queries.

Type::

interface ElectroResultsEvent<R extends any = any> {
  type: "results";
  method:
    | "put"
    | "get"
    | "query"
    | "scan"
    | "update"
    | "delete"
    | "remove"
    | "patch"
    | "create"
    | "batchGet"
    | "batchWrite";
  config: any;
  results: R;
  success: boolean;
}

Example Input:

const prop1 = "22874c81-27c4-4264-92c3-b280aa79aa30";
const prop2 = "366aade8-a7c0-4328-8e14-0331b185de4e";

entity.get({ prop1, prop2 }).go();

Example Output:

{
  "type": "results",
  "method": "get",
  "config": {  },
  "success": true,
  "results": {
    "Item": {
      "prop2": "366aade8-a7c0-4328-8e14-0331b185de4e",
      "sk": "$testcollection#entity_1#prop2_366aade8-a7c0-4328-8e14-0331b185de4e",
      "prop1": "22874c81-27c4-4264-92c3-b280aa79aa30",
      "prop3": "3ec9ed0c-7497-4d05-bdb8-86c09a618047",
      "__edb_e__": "entity",
      "__edb_v__": "1",
      "pk": "$test_1#prop1_22874c81-27c4-4264-92c3-b280aa79aa30"
    }
  }
}

Loggers

A logger callback function can be provided both the at the instantiation of an Entity or Service instance or as an Execution Option. The property logger is implemented as a convenience property; under the hood ElectroDB uses this property identically to how it uses a Listener.

On the instantiation of an Entity:

import { DynamoDB } from "aws-sdk";
import { Entity, ElectroEvent } from "electrodb";

const table = "my_table_name";
const client = new DynamoDB.DocumentClient();
const logger = (event: ElectroEvent) => {
  console.log(JSON.stringify(event, null, 4));
};

const task = new Entity(
  {
    // your model
  },
  {
    client,
    table,
    logger, // <----- logger listener
  },
);

On the instantiation of an Service:

import { DynamoDB } from "aws-sdk";
import { Entity, ElectroEvent } from "electrodb";

const table = "my_table_name";
const client = new DynamoDB.DocumentClient();
const logger = (event: ElectroEvent) => {
  console.log(JSON.stringify(event, null, 4));
};

const task = new Entity({
  // your model
});

const user = new Entity({
  // your model
});

const service = new Service(
  { task, user },
  {
    client,
    table,
    logger, // <----- logger listener
  },
);

As an Execution Option:

const logger = (event: ElectroEvent) => {
  console.log(JSON.stringify(event, null, 4));
};

task.query.assigned({ userId }).go({ logger });

Listeners

ElectroDB can be supplied with callbacks (called “Listeners”) to be invoked after certain request lifecycles. Unlike Attribute Getters and Setters, Listeners are implemented to react to events passively, not to modify values during the request lifecycle. Listeners can be useful for logging, analytics, expanding functionality, and more. Listeners can be provided at the instantiation of an Entity or Service instance and/or as an Execution Option.

Listeners treated as synchronous callbacks and are not awaited. In the event that a callback throws an exception, ElectroDB will quietly catch and log the exception with console.error to prevent the exception from impacting your query.

On the instantiation of an Entity:

import { DynamoDB } from "aws-sdk";
import { Entity, ElectroEvent } from "electrodb";

const table = "my_table_name";
const client = new DynamoDB.DocumentClient();
const listener1 = (event: ElectroEvent) => {
  // do work
};

const listener2 = (event: ElectroEvent) => {
  // do work
};

const task = new Entity(
  {
    // your model
  },
  {
    client,
    table,
    listeners: [
      listener1,
      listener2, // <----- supports multiple listeners
    ],
  },
);

On the instantiation of an Service:

import { DynamoDB } from "aws-sdk";
import { Entity, ElectroEvent } from "electrodb";

const table = "my_table_name";
const client = new DynamoDB.DocumentClient();

const listener1 = (event: ElectroEvent) => {
  // do work
};

const listener2 = (event: ElectroEvent) => {
  // do work
};

const task = new Entity({
  // your model
});

const user = new Entity({
  // your model
});

const service = new Service(
  { task, user },
  {
    client,
    table,
    listeners: [
      listener1,
      listener2, // <----- supports multiple listeners
    ],
  },
);

As an Execution Option:

const listener1 = (event: ElectroEvent) => {
  // do work
};

const listener2 = (event: ElectroEvent) => {
  // do work
};

task.query.assigned({ userId }).go({ listeners: [listener1, listener2] });