From 14894874ce2c20b134e3ed1a8ee37897419b8ec5 Mon Sep 17 00:00:00 2001 From: haozi Date: Sun, 10 Dec 2023 22:09:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Replace=20deepFreeze=20w?= =?UTF-8?q?ith=20readonly=20to=20provide=20better=20error=20messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/App.tsx | 9 +++++++++ demo/api.ts | 8 ++++++-- package.json | 2 +- src/index.ts | 47 +++++++++++++++++++++++++++++++++++++---------- 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/demo/App.tsx b/demo/App.tsx index 1fecced..9674c32 100644 --- a/demo/App.tsx +++ b/demo/App.tsx @@ -2,6 +2,15 @@ import React, { useState } from 'react' import Item from './Item' import ItemIdmp from './ItemIdmp' // import idmp from '../src' +// import { getUserDataIdmp } from './api' + +// getUserDataIdmp('123').then((d) => { +// console.log(123, d) +// d.extra.a = { +// a: 1, +// b: 2, +// } +// }) // const getInfo = async () => { // // const API = `https://haozi.meaa/?api/your-info` diff --git a/demo/api.ts b/demo/api.ts index 20ceeca..2acb861 100644 --- a/demo/api.ts +++ b/demo/api.ts @@ -11,13 +11,17 @@ export const getUserData = async (userId: string) => { const API = `https://haozi.me/?id=${userId}&t=${Math.random()}` await fetch(API).then((d) => d.text()) - const res = { id: userId, val: Math.random() } + const res = { + id: userId, + val: Math.random(), + extra: { a: { b: { c: 111 } } }, + } return res } export const getUserDataIdmp = (userId: string) => { const key = `getUserData:${userId}` - return idmp(key, () => getUserData(userId)) + return idmp(key, () => getUserData(userId), { maxAge: 60 * 1000 }) } export const getUserDataIdmp2 = (userId: string) => { diff --git a/package.json b/package.json index 60d004c..deeb21a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "idmp", - "version": "1.8.4", + "version": "1.9.0", "keywords": [ "cache response", "swr without hooks", diff --git a/src/index.ts b/src/index.ts index 9437f3c..0857940 100644 --- a/src/index.ts +++ b/src/index.ts @@ -61,16 +61,43 @@ const DEFAULT_MAX_AGE = 3000 const _7days = 604800000 const noop = () => {} const udf = undefined -const deepFreeze = /* @__PURE__ */ (obj: any): T => { - if (!obj) return obj - if (typeof obj !== 'object') return obj - Object.keys(obj).forEach((property) => { - if (typeof obj[property] === 'object' && !Object.isFrozen(obj[property])) { - deepFreeze(obj[property]) - } +// const deepFreeze = /* @__PURE__ */ (obj: any): T => { +// if (!obj) return obj +// if (typeof obj !== 'object') return obj + +// Object.keys(obj).forEach((property) => { +// if (typeof obj[property] === 'object' && !Object.isFrozen(obj[property])) { +// deepFreeze(obj[property]) +// } +// }) +// return Object.freeze(obj) +// } + +const defineReactive = (obj: any, key: string | symbol, value: any) => { + readonly(value) + Object.defineProperty(obj, key, { + get: () => value, + set: (newValue) => { + const msg = `[idmp error] The data is read-only, set ${key.toString()}=${JSON.stringify( + newValue, + )} is not allow` + console.error(`%c ${msg}`, 'font-weight: lighter; color: red') + throw new Error(msg) + }, + }) +} + +const readonly = (obj: T): T => { + if (obj === null || typeof obj !== 'object') { + return obj + } + + Object.keys(obj).forEach((key) => { + defineReactive(obj, key, (obj as any)[key]) }) - return Object.freeze(obj) + + return obj } const getRange = (maxAge: number) => { @@ -120,7 +147,7 @@ const idmp = ( options?: IdmpOptions, ): Promise => { if (process.env.NODE_ENV !== 'production') { - options = deepFreeze(options) + options = readonly(options) } const { @@ -275,7 +302,7 @@ const idmp = ( cache[K.oneCallPromiseFunc]() .then((data: T) => { if (process.env.NODE_ENV !== 'production') { - cache[K.resData] = deepFreeze(data) + cache[K.resData] = readonly(data) } else { cache[K.resData] = data }