OverviewFilesCommitsIssuesDocsReleasesPeers

favela-node / lib / bare-globals.js

51 lines · javascript ref:
// Minimal web-global polyfills for Bare. Bare omits TextEncoder/TextDecoder (which
// several npm deps — e.g. @noble/curves — use at MODULE LOAD) and a global `process`
// (our lib reads process.env / process.exit). Buffer IS a Bare global, so we back the
// polyfills with it. Import this FIRST in any Bare entrypoint, before deps that touch
// these globals. No-op under Node (globals already present).

import bareProcess from 'bare-process'
if (typeof globalThis.process === 'undefined') globalThis.process = bareProcess

if (typeof globalThis.TextEncoder === 'undefined') {
  globalThis.TextEncoder = class TextEncoder {
    get encoding () { return 'utf-8' }
    encode (input = '') { return new Uint8Array(Buffer.from(String(input), 'utf8')) }
    encodeInto (src, dest) {
      const bytes = this.encode(src)
      const n = Math.min(bytes.length, dest.length)
      dest.set(bytes.subarray(0, n))
      return { read: src.length, written: n }
    }
  }
}

// AbortController/AbortSignal — Bare omits them; used by our firehose subscribe
// cancellation AND by streamx (bare-ws sockets). Minimal, no EventTarget dependency;
// covers the subset consumers use (aborted + add/removeEventListener('abort')).
if (typeof globalThis.AbortController === 'undefined') {
  class AbortSignal {
    constructor () { this.aborted = false; this.reason = undefined; this._listeners = [] }
    addEventListener (type, cb) { if (type === 'abort') this._listeners.push(cb) }
    removeEventListener (type, cb) { if (type === 'abort') this._listeners = this._listeners.filter(l => l !== cb) }
    _fire () { this.aborted = true; const ls = this._listeners; this._listeners = []; for (const cb of ls) { try { cb() } catch {} } }
  }
  class AbortController {
    constructor () { this.signal = new AbortSignal() }
    abort (reason) { if (!this.signal.aborted) { this.signal.reason = reason; this.signal._fire() } }
  }
  globalThis.AbortSignal = AbortSignal
  globalThis.AbortController = AbortController
}

if (typeof globalThis.TextDecoder === 'undefined') {
  globalThis.TextDecoder = class TextDecoder {
    get encoding () { return 'utf-8' }
    decode (input) {
      if (input == null) return ''
      const u8 = input instanceof Uint8Array ? input : new Uint8Array(input.buffer || input, input.byteOffset || 0, input.byteLength)
      return Buffer.from(u8).toString('utf8')
    }
  }
}