===== ISTEM =====
Solve the following programming task.

TASK: Custom JSON.stringify

Write a function 'jsonStringify(value)' that converts objects, arrays, strings, numbers and booleans into JSON text without using the native JSON.stringify.

STARTER CODE (javascript):
function jsonStringify(value) {
  // Write your code here
}

module.exports = { jsonStringify };


RULES:
- Keep the function name and signature EXACTLY as given.
- Return working code only. No explanations.
- Put the code in a single ``` block.
- Try to solve it first. If you genuinely cannot, write only this single
  line instead of producing faulty code: CANNOT_SOLVE

===== HAM YANIT =====
```javascript
function jsonStringify(value) {
  const ancestors = new Set();

  function quote(text) {
    let result = '"';

    for (let i = 0; i < text.length; i++) {
      const code = text.charCodeAt(i);

      switch (code) {
        case 0x22: result += '\\"'; break;
        case 0x5c: result += '\\\\'; break;
        case 0x08: result += '\\b'; break;
        case 0x0c: result += '\\f'; break;
        case 0x0a: result += '\\n'; break;
        case 0x0d: result += '\\r'; break;
        case 0x09: result += '\\t'; break;
        default:
          if (code < 0x20) {
            result += '\\u' + code.toString(16).padStart(4, '0');
          } else if (code >= 0xd800 && code <= 0xdbff) {
            const next = text.charCodeAt(i + 1);
            if (next >= 0xdc00 && next <= 0xdfff) {
              result += text[i] + text[++i];
            } else {
              result += '\\u' + code.toString(16).padStart(4, '0');
            }
          } else if (code >= 0xdc00 && code <= 0xdfff) {
            result += '\\u' + code.toString(16).padStart(4, '0');
          } else {
            result += text[i];
          }
      }
    }

    return result + '"';
  }

  function unbox(object) {
    const methods = [
      Number.prototype.valueOf,
      String.prototype.valueOf,
      Boolean.prototype.valueOf,
      BigInt.prototype.valueOf
    ];

    for (let i = 0; i < methods.length; i++) {
      let primitive;
      try {
        primitive = Reflect.apply(methods[i], object, []);
      } catch {
        continue;
      }

      if (i === 0) return +object;
      if (i === 1) return String(object);
      return primitive;
    }

    return object;
  }

  function serialize(current, key) {
    const type = typeof current;

    if (
      current !== null &&
      (type === 'object' || type === 'function' || type === 'bigint')
    ) {
      const toJSON = current.toJSON;
      if (typeof toJSON === 'function') {
        current = Reflect.apply(toJSON, current, [key]);
      }
    }

    if (current !== null && typeof current === 'object') {
      current = unbox(current);
    }

    if (current === null) return 'null';

    switch (typeof current) {
      case 'string':
        return quote(current);
      case 'number':
        return Number.isFinite(current) ? String(current) : 'null';
      case 'boolean':
        return current ? 'true' : 'false';
      case 'bigint':
        throw new TypeError('Cannot serialize a BigInt');
      case 'undefined':
      case 'function':
      case 'symbol':
        return undefined;
    }

    if (ancestors.has(current)) {
      throw new TypeError('Converting circular structure to JSON');
    }

    ancestors.add(current);

    try {
      const parts = [];

      if (Array.isArray(current)) {
        const length = current.length;
        for (let i = 0; i < length; i++) {
          const item = serialize(current[i], String(i));
          parts.push(item === undefined ? 'null' : item);
        }
        return '[' + parts.join(',') + ']';
      }

      for (const property of Object.keys(current)) {
        const item = serialize(current[property], property);
        if (item !== undefined) {
          parts.push(quote(property) + ':' + item);
        }
      }

      return '{' + parts.join(',') + '}';
    } finally {
      ancestors.delete(current);
    }
  }

  return serialize(value, '');
}

module.exports = { jsonStringify };
```