UNPKG

tupleson

Version:

A hackable JSON serializer/deserializer

1 lines 5.2 kB
{"version":3,"sources":["../../src/sync/serialize.ts"],"sourcesContent":["import { TsonCircularReferenceError } from \"../errors.js\";\nimport { GetNonce, getDefaultNonce } from \"../internals/getNonce.js\";\nimport { mapOrReturn } from \"../internals/mapOrReturn.js\";\nimport {\n\tTsonAllTypes,\n\tTsonNonce,\n\tTsonOptions,\n\tTsonSerializeFn,\n\tTsonSerialized,\n\tTsonStringifyFn,\n\tTsonTuple,\n\tTsonTypeTesterCustom,\n\tTsonTypeTesterPrimitive,\n} from \"./syncTypes.js\";\n\ntype WalkFn = (value: unknown) => unknown;\ntype WalkerFactory = (nonce: TsonNonce) => WalkFn;\n\nfunction getHandlers(opts: TsonOptions) {\n\ttype Handler = (typeof opts.types)[number];\n\n\tconst byPrimitive: Partial<\n\t\tRecord<TsonAllTypes, Extract<Handler, TsonTypeTesterPrimitive>>\n\t> = {};\n\tconst nonPrimitives: Extract<Handler, TsonTypeTesterCustom>[] = [];\n\n\tfor (const handler of opts.types) {\n\t\tif (handler.primitive) {\n\t\t\tif (byPrimitive[handler.primitive]) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Multiple handlers for primitive ${handler.primitive} found`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tbyPrimitive[handler.primitive] = handler;\n\t\t} else {\n\t\t\tnonPrimitives.push(handler);\n\t\t}\n\t}\n\n\tconst getNonce: GetNonce = opts.nonce\n\t\t? (opts.nonce as GetNonce)\n\t\t: getDefaultNonce;\n\n\treturn [getNonce, nonPrimitives, byPrimitive] as const;\n}\n\nexport function createTsonStringify(opts: TsonOptions): TsonStringifyFn {\n\tconst serializer = createTsonSerialize(opts);\n\n\treturn ((obj: unknown, space?: number | string) =>\n\t\tJSON.stringify(serializer(obj), null, space)) as TsonStringifyFn;\n}\n\nexport function createTsonSerialize(opts: TsonOptions): TsonSerializeFn {\n\tconst [getNonce, nonPrimitive, byPrimitive] = getHandlers(opts);\n\n\tconst walker: WalkerFactory = (nonce) => {\n\t\tconst seen = new WeakSet();\n\t\tconst cache = new WeakMap<object, unknown>();\n\n\t\tconst walk: WalkFn = (value) => {\n\t\t\tconst type = typeof value;\n\t\t\tconst isComplex = !!value && type === \"object\";\n\n\t\t\tif (isComplex) {\n\t\t\t\tif (seen.has(value)) {\n\t\t\t\t\tconst cached = cache.get(value);\n\t\t\t\t\tif (!cached) {\n\t\t\t\t\t\tthrow new TsonCircularReferenceError(value);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn cached;\n\t\t\t\t}\n\n\t\t\t\tseen.add(value);\n\t\t\t}\n\n\t\t\tconst cacheAndReturn = (result: unknown) => {\n\t\t\t\tif (isComplex) {\n\t\t\t\t\tcache.set(value, result);\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t};\n\n\t\t\tconst primitiveHandler = byPrimitive[type];\n\t\t\tif (\n\t\t\t\tprimitiveHandler &&\n\t\t\t\t(!primitiveHandler.test || primitiveHandler.test(value))\n\t\t\t) {\n\t\t\t\treturn cacheAndReturn([\n\t\t\t\t\tprimitiveHandler.key,\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\twalk(primitiveHandler.serialize!(value)),\n\t\t\t\t\tnonce,\n\t\t\t\t] as TsonTuple);\n\t\t\t}\n\n\t\t\tfor (const handler of nonPrimitive) {\n\t\t\t\tif (handler.test(value)) {\n\t\t\t\t\treturn cacheAndReturn([\n\t\t\t\t\t\thandler.key,\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\twalk(handler.serialize!(value)),\n\t\t\t\t\t\tnonce,\n\t\t\t\t\t] as TsonTuple);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn cacheAndReturn(mapOrReturn(value, walk));\n\t\t};\n\n\t\treturn walk;\n\t};\n\n\treturn ((obj): TsonSerialized => {\n\t\tconst nonce = getNonce();\n\t\tconst json = walker(nonce)(obj);\n\n\t\treturn {\n\t\t\tjson,\n\t\t\tnonce,\n\t\t} as TsonSerialized<any>;\n\t}) as TsonSerializeFn;\n}\n"],"mappings":"AAAA,SAAS,kCAAkC;AAC3C,SAAmB,uBAAuB;AAC1C,SAAS,mBAAmB;AAgB5B,SAAS,YAAY,MAAmB;AAGvC,QAAM,cAEF,CAAC;AACL,QAAM,gBAA0D,CAAC;AAEjE,aAAW,WAAW,KAAK,OAAO;AACjC,QAAI,QAAQ,WAAW;AACtB,UAAI,YAAY,QAAQ,SAAS,GAAG;AACnC,cAAM,IAAI;AAAA,UACT,mCAAmC,QAAQ,SAAS;AAAA,QACrD;AAAA,MACD;AAEA,kBAAY,QAAQ,SAAS,IAAI;AAAA,IAClC,OAAO;AACN,oBAAc,KAAK,OAAO;AAAA,IAC3B;AAAA,EACD;AAEA,QAAM,WAAqB,KAAK,QAC5B,KAAK,QACN;AAEH,SAAO,CAAC,UAAU,eAAe,WAAW;AAC7C;AAEO,SAAS,oBAAoB,MAAoC;AACvE,QAAM,aAAa,oBAAoB,IAAI;AAE3C,SAAQ,CAAC,KAAc,UACtB,KAAK,UAAU,WAAW,GAAG,GAAG,MAAM,KAAK;AAC7C;AAEO,SAAS,oBAAoB,MAAoC;AACvE,QAAM,CAAC,UAAU,cAAc,WAAW,IAAI,YAAY,IAAI;AAE9D,QAAM,SAAwB,CAAC,UAAU;AACxC,UAAM,OAAO,oBAAI,QAAQ;AACzB,UAAM,QAAQ,oBAAI,QAAyB;AAE3C,UAAM,OAAe,CAAC,UAAU;AAC/B,YAAM,OAAO,OAAO;AACpB,YAAM,YAAY,CAAC,CAAC,SAAS,SAAS;AAEtC,UAAI,WAAW;AACd,YAAI,KAAK,IAAI,KAAK,GAAG;AACpB,gBAAM,SAAS,MAAM,IAAI,KAAK;AAC9B,cAAI,CAAC,QAAQ;AACZ,kBAAM,IAAI,2BAA2B,KAAK;AAAA,UAC3C;AAEA,iBAAO;AAAA,QACR;AAEA,aAAK,IAAI,KAAK;AAAA,MACf;AAEA,YAAM,iBAAiB,CAAC,WAAoB;AAC3C,YAAI,WAAW;AACd,gBAAM,IAAI,OAAO,MAAM;AAAA,QACxB;AAEA,eAAO;AAAA,MACR;AAEA,YAAM,mBAAmB,YAAY,IAAI;AACzC,UACC,qBACC,CAAC,iBAAiB,QAAQ,iBAAiB,KAAK,KAAK,IACrD;AACD,eAAO,eAAe;AAAA,UACrB,iBAAiB;AAAA;AAAA,UAEjB,KAAK,iBAAiB,UAAW,KAAK,CAAC;AAAA,UACvC;AAAA,QACD,CAAc;AAAA,MACf;AAEA,iBAAW,WAAW,cAAc;AACnC,YAAI,QAAQ,KAAK,KAAK,GAAG;AACxB,iBAAO,eAAe;AAAA,YACrB,QAAQ;AAAA;AAAA,YAER,KAAK,QAAQ,UAAW,KAAK,CAAC;AAAA,YAC9B;AAAA,UACD,CAAc;AAAA,QACf;AAAA,MACD;AAEA,aAAO,eAAe,YAAY,OAAO,IAAI,CAAC;AAAA,IAC/C;AAEA,WAAO;AAAA,EACR;AAEA,SAAQ,CAAC,QAAwB;AAChC,UAAM,QAAQ,SAAS;AACvB,UAAM,OAAO,OAAO,KAAK,EAAE,GAAG;AAE9B,WAAO;AAAA,MACN;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;","names":[]}