UNPKG

gqty

Version:

The No-GraphQL Client for TypeScript

131 lines (126 loc) 4.03 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const index = require('../Error/index.js'); require('../Utils/hash.js'); const object = require('../Utils/object.js'); const utils = require('./utils.js'); const refKey = Symbol("__ref"); const isNormalizedObjectShell = (value) => shells.has(value); const deshell = (input) => isNormalizedObjectShell(input) ? input.toJSON() : input; const shells = /* @__PURE__ */ new Set(); const normalizeObject = (data, { identity, onConflict = (_, t) => t, store }) => { if (typeof data !== "object" || Array.isArray(data)) { throw new index.GQtyError( `Only objects can be normalized, received ${typeof data}.` ); } const id = identity(data); if (!id) return; const existing = store.get(id); data = deshell(data); if (existing) { data = object.deepAssign({}, [existing.toJSON(), data], onConflict); existing.$set(data); return existing; } else { const result = new Proxy( { [refKey]: data }, { ownKeys(target) { return Reflect.ownKeys(target[refKey]); }, getOwnPropertyDescriptor(target, key) { return Reflect.getOwnPropertyDescriptor(target[refKey], key); }, set(target, key, value) { return Reflect.set(target[refKey], key, value); }, get(target, key) { var _a; if (key === "$set") { return (value) => { target[refKey] = value; }; } if (key === "toJSON") { return () => target[refKey]; } return (_a = Reflect.get(target, key)) != null ? _a : Reflect.get(target[refKey], key); } } ); shells.add(result); store.set(id, result, { // Has to use strong reference as this is usually the only reference, // the cache is referencing the object via an internal identifier string. strong: true }); return result; } }; const deepNormalizeObject = (data, options) => { return walk(data); function walk(input, depth = 0) { if (depth < 15 && input && typeof input === "object") { for (const [key, value] of Object.entries(input)) { input[key] = walk(value, depth + 1); } if (!Array.isArray(input) && utils.isCacheObject(input)) { const id = options.identity(input); if (id) { const norbj = normalizeObject(input, options); if (norbj) { return norbj; } } } } return input; } }; const defaultNormalizationHandler = Object.freeze({ identity(value) { var _a; if (!value || typeof value !== "object" || Array.isArray(value)) return; const identityFields = [value.__typename, (_a = value.id) != null ? _a : value._id]; if (identityFields.some((field) => field === void 0)) return; return identityFields.join(":"); }, onConflict(existing, incoming) { const mergeObjects = (a, b) => { const result = { ...a, ...b }; if (isNormalizedObjectShell(a)) { a.$set(result); return a; } else if (isNormalizedObjectShell(b)) { b.$set(result); return b; } return result; }; if (Array.isArray(existing) && Array.isArray(incoming)) { if (existing.length === incoming.length) { return; } else { existing.splice(0, existing.length, ...incoming); } return existing; } else if (utils.isCacheObject(existing) && utils.isCacheObject(incoming)) { return mergeObjects(existing, incoming); } return; } }); const isSubsetOf = (a, b) => { for (const [key, value] of Object.entries(a)) { if (value !== b[key]) { return false; } } return true; }; exports.deepNormalizeObject = deepNormalizeObject; exports.defaultNormalizationHandler = defaultNormalizationHandler; exports.isNormalizedObjectShell = isNormalizedObjectShell; exports.isSubsetOf = isSubsetOf; exports.normalizeObject = normalizeObject;