Repository: gatsbyjs/gatsby
File: packages/gatsby-telemetry/src/event-storage.ts (TypeScript)

Code before:
import { ensureDirSync } from "fs-extra"
import { isTruthy } from "./is-truthy"

const fetch = createFetch()

/* The events data collection is a spooled process that
 * buffers events to a local fs based buffer
 * which then is asynchronously flushed to the server.
 * This both increases the fault tolerance and allows collection
 * to continue even when working offline.
 */
module.exports = class EventStorage {
  analyticsApi =
    process.env.GATSBY_TELEMETRY_API || `https://analytics.gatsbyjs.com/events`
  // eslint-disable-line @typescript-eslint/no-explicit-any
  config: Configstore | Record<string, any>
  store: Store
  verbose: boolean
  debugEvents: boolean
  disabled: boolean

  constructor() {
    try {
      this.config = new Configstore(`gatsby`, {}, { globalConfigPath: true })
    } catch (e) {
      // This should never happen
      this.config = {} as Configstore
      this.config.get = (key: string): any => this.config[key]
      this.config.set = (key: string, value: any): any => {
        this.config[key] = value
        return value
      }
      this.config.all = this.config
      this.config.path = path.join(os.tmpdir(), `gatsby`)
      this.config[`telemetry.enabled`] = true
      this.config[`telemetry.machineId`] = `not-a-machine-id`
    }

    const baseDir = path.dirname(this.config.path)

    try {
      ensureDirSync(baseDir)
    } catch (e) {
      // TODO: Log this event
    }

    this.store = new Store(baseDir)
    this.verbose = isTruthy(process.env.GATSBY_TELEMETRY_VERBOSE)
    this.debugEvents = isTruthy(process.env.GATSBY_TELEMETRY_DEBUG)
    this.disabled = isTruthy(process.env.GATSBY_TELEMETRY_DISABLED)
  }

Review comment (suggestion):
If this should never throw, why are we going to all this effort to manually build the store? Can't we just bail? If not, it would be better to create a separate FallbackConfigstore class an instantiate that.

Code after:
import { isTruthy } from "./is-truthy"
import { InMemoryConfigStore } from "./in-memory-store"

const fetch = createFetch()

/* The events data collection is a spooled process that
 * buffers events to a local fs based buffer
 * which then is asynchronously flushed to the server.
 * This both increases the fault tolerance and allows collection
 * to continue even when working offline.
 */
export class EventStorage {
  analyticsApi =
    process.env.GATSBY_TELEMETRY_API || `https://analytics.gatsbyjs.com/events`
  config: Configstore | InMemoryConfigStore
  store: Store
  verbose: boolean
  debugEvents: boolean
  disabled: boolean

  constructor() {
    try {
      this.config = new Configstore(`gatsby`, {}, { globalConfigPath: true })
    } catch (e) {
      this.config = new InMemoryConfigStore()
    }

    const baseDir = path.dirname(this.config.path)

    try {
      ensureDirSync(baseDir)
    } catch (e) {
      // TODO: Log this event
    }

    this.store = new Store(baseDir)
    this.verbose = isTruthy(process.env.GATSBY_TELEMETRY_VERBOSE)
    this.debugEvents = isTruthy(process.env.GATSBY_TELEMETRY_DEBUG)
    this.disabled = isTruthy(process.env.GATSBY_TELEMETRY_DISABLED)
  }

  isTrackingDisabled(): boolean {
    return this.disabled
  }

  addEvent(event: unknown): void {
    if (this.disabled) {
      return
    }

    const eventString = JSON.stringify(event)