@lomray/react-mobx-manager 3.5.1 → 3.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/suspense-query.js +1 -1
- package/suspense-query.js.map +1 -1
package/package.json
CHANGED
package/suspense-query.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{makeExported as r}from"./make-exported.js";class s{promise;subqueries=new Map;store;params;constructor(s,{fieldName:e="sR",errorFields:t=["name","message"]}={}){this.store=s,this.params={fieldName:e,errorFields:t};const i=s.init?.bind(s);s.init=()=>{this.throwError(),i?.()},r(s,{[e]:"simple"})}errorJson(r){r.toJSON=()=>this.params.errorFields.reduce(((s,e)=>({...s,[e]:r?.[e]})),{})}jsonToError(r,s){return this.params.errorFields.forEach((e=>{r[e]=s?.[e]})),r}throwError(){const r=this.store[this.params.fieldName];if(r?.error)throw this.jsonToError(new Error(r?.message??r?.name),r)}isComplete(r){const s=this.store[this.params.fieldName];return s?.error&&this.throwError(),!0===s?.done&&s.hash===r}query=(r,e={})=>{const{hash:t=""}=e,{fieldName:i}=this.params;if(!this.isComplete(t))return this.store[i]?.hash!==t&&(this.store[i]={hash:t,done:!1},this.promise=void 0),this.promise||(this.promise=r(),this.promise.then((()=>{this.store[i]={hash:t,done:!0}}),(r=>{this.errorJson(r),this.store[i]={error:r}}))),s.run(this.promise)};subquery=(r,e)=>{const{id:t,hash:i}=e,o=this.subqueries.get(t);if(!o)return void this.subqueries.set(t,{hash:i});if(o?.hash===i)return s.run(o?.promise);const h=r();return this.subqueries.set(t,{hash:i,promise:h}),s.run(h)};static run=r=>{if(r){switch(r.status){case"fulfilled":return r.value;case"pending":throw r;case"rejected":throw r.reason;default:r.status="pending",r.then((s=>{r.status="fulfilled",r.value=s}),(s=>{r.status="rejected",r.reason=s}))}throw r}}}export{s as default};
|
|
1
|
+
import{makeExported as r}from"./make-exported.js";class s{promise;subqueries=new Map;store;params;constructor(s,{fieldName:e="sR",errorFields:t=["name","message"]}={}){this.store=s,this.params={fieldName:e,errorFields:t};const i=s.init?.bind(s);s.init=()=>{this.throwError(),i?.()},r(s,{[e]:"simple"})}errorJson(r){r.toJSON=()=>this.params.errorFields.reduce(((s,e)=>({...s,[e]:r?.[e]})),{})}jsonToError(r,s){return this.params.errorFields.forEach((e=>{r[e]=s?.[e]})),r}throwError(){const r=this.store[this.params.fieldName];if(r?.error)throw this.jsonToError(new Error(r?.error?.message??r?.error?.name),r?.error)}isComplete(r){const s=this.store[this.params.fieldName];return s?.error&&this.throwError(),!0===s?.done&&s.hash===r}query=(r,e={})=>{const{hash:t=""}=e,{fieldName:i}=this.params;if(!this.isComplete(t))return this.store[i]?.hash!==t&&(this.store[i]={hash:t,done:!1},this.promise=void 0),this.promise||(this.promise=r(),this.promise.then((()=>{this.store[i]={hash:t,done:!0}}),(r=>{this.errorJson(r),this.store[i]={error:r}}))),s.run(this.promise)};subquery=(r,e)=>{const{id:t,hash:i}=e,o=this.subqueries.get(t);if(!o)return void this.subqueries.set(t,{hash:i});if(o?.hash===i)return s.run(o?.promise);const h=r();return this.subqueries.set(t,{hash:i,promise:h}),s.run(h)};static run=r=>{if(r){switch(r.status){case"fulfilled":return r.value;case"pending":throw r;case"rejected":throw r.reason;default:r.status="pending",r.then((s=>{r.status="fulfilled",r.value=s}),(s=>{r.status="rejected",r.reason=s}))}throw r}}}export{s as default};
|
|
2
2
|
//# sourceMappingURL=suspense-query.js.map
|
package/suspense-query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suspense-query.js","sources":["../src/suspense-query.ts"],"sourcesContent":["import { makeExported } from './make-exported';\nimport type { TInitStore } from './types';\n\nexport interface IPromise<TReturn> extends Promise<TReturn> {\n status?: 'fulfilled' | 'pending' | 'rejected';\n value?: TReturn;\n reason?: any;\n}\n\ninterface ISuspenseQueryParams {\n fieldName?: string; // field name in target store for save suspense state\n errorFields?: string[];\n}\n\ninterface ISuspenseQueryOptions {\n hash?: unknown;\n}\n\ninterface ISuspenseSubqueryOptions {\n id: string;\n hash: unknown;\n}\n\n/**\n * Run request and cache promise\n * Sync suspense status between server and client\n */\nclass SuspenseQuery {\n /**\n * @protected\n */\n protected promise: Promise<any> | undefined;\n\n /**\n * Subqueries info\n */\n protected subqueries: Map<string, { hash: unknown; promise?: IPromise<any> }> = new Map();\n\n /**\n * Target store\n */\n protected readonly store: TInitStore;\n\n /**\n * @protected\n */\n protected readonly params: Required<ISuspenseQueryParams>;\n\n /**\n * @constructor\n */\n constructor(\n store: TInitStore,\n { fieldName = 'sR', errorFields = ['name', 'message'] }: ISuspenseQueryParams = {},\n ) {\n this.store = store;\n this.params = { fieldName, errorFields };\n\n const defaultInit = store.init?.bind(store);\n\n store.init = () => {\n this.throwError(); // throw error immediately from server side if exist\n defaultInit?.();\n };\n\n makeExported(store, { [fieldName]: 'simple' });\n }\n\n /**\n * Error to json\n */\n protected errorJson(e: any): void {\n e.toJSON = () =>\n this.params.errorFields.reduce(\n (res, name) => ({\n ...res,\n [name]: e?.[name],\n }),\n {},\n );\n }\n\n /**\n * Assign custom error fields to error\n */\n protected jsonToError(e: Error, values: Record<string, any>): Error {\n this.params.errorFields.forEach((name) => {\n e[name] = values?.[name];\n });\n\n return e;\n }\n\n /**\n * Throw suspense error\n */\n protected throwError(): void {\n const value = this.store[this.params.fieldName];\n\n // pass error to error boundary\n if (value?.error) {\n throw this.jsonToError(\n new Error((value?.message ?? value?.name) as string),\n value as Record<string, any>,\n );\n }\n }\n\n /**\n * Detect if suspense is restored from server side:\n * - throw error if exist\n * - skip run suspense if already completed\n */\n protected isComplete(hash: unknown): boolean {\n const value = this.store[this.params.fieldName];\n\n // pass error to error boundary\n if (value?.error) {\n this.throwError();\n }\n\n return value?.done === true && value.hash === hash;\n }\n\n /**\n * Run request\n * Save request resolve status\n */\n public query = <TReturn>(\n promise: () => Promise<TReturn>,\n options: ISuspenseQueryOptions = {},\n ): TReturn | undefined => {\n const { hash = '' } = options;\n const { fieldName } = this.params;\n\n if (this.isComplete(hash)) {\n return;\n }\n\n if (this.store[fieldName]?.hash !== hash) {\n this.store[fieldName] = { hash, done: false };\n this.promise = undefined;\n }\n\n if (!this.promise) {\n this.promise = promise();\n\n this.promise.then(\n () => {\n this.store[fieldName] = { hash, done: true };\n },\n (e) => {\n this.errorJson(e);\n\n this.store[fieldName] = { error: e };\n },\n );\n }\n\n return SuspenseQuery.run<TReturn>(this.promise);\n };\n\n /**\n * Run subquery\n * Re-fetch data from query by hash changes in children components\n * NOTE: only client side\n */\n public subquery = <TReturn>(\n promise: () => Promise<TReturn>,\n options: ISuspenseSubqueryOptions,\n ): TReturn | undefined => {\n const { id, hash } = options;\n const subquery = this.subqueries.get(id);\n\n // skip first run\n if (!subquery) {\n this.subqueries.set(id, { hash });\n\n return undefined;\n }\n\n if (subquery?.hash === hash) {\n return SuspenseQuery.run<TReturn>(subquery?.promise);\n }\n\n const newQuery = promise();\n\n this.subqueries.set(id, { hash, promise: newQuery });\n\n return SuspenseQuery.run<TReturn>(newQuery);\n };\n\n /**\n * Change status of promise.\n * Throw promise to react suspense\n */\n public static run = <TReturn>(promise: IPromise<TReturn> | undefined): TReturn | undefined => {\n if (!promise) {\n return;\n }\n\n switch (promise.status) {\n case 'fulfilled':\n return promise.value;\n\n case 'pending':\n throw promise;\n\n case 'rejected':\n throw promise.reason;\n\n default:\n promise.status = 'pending';\n\n promise.then(\n (result) => {\n promise.status = 'fulfilled';\n promise.value = result;\n },\n (reason) => {\n promise.status = 'rejected';\n promise.reason = reason;\n },\n );\n }\n\n throw promise;\n };\n}\n\nexport default SuspenseQuery;\n"],"names":["SuspenseQuery","promise","subqueries","Map","store","params","constructor","fieldName","errorFields","this","defaultInit","init","bind","throwError","makeExported","errorJson","e","toJSON","reduce","res","name","jsonToError","values","forEach","value","error","Error","message","isComplete","hash","done","query","options","undefined","then","run","subquery","id","get","set","newQuery","static","status","reason","result"],"mappings":"kDA2BA,MAAMA,EAIMC,QAKAC,WAAsE,IAAIC,IAKjEC,MAKAC,OAKnBC,YACEF,GACAG,UAAEA,EAAY,KAAIC,YAAEA,EAAc,CAAC,OAAQ,YAAqC,IAEhFC,KAAKL,MAAQA,EACbK,KAAKJ,OAAS,CAAEE,YAAWC,eAE3B,MAAME,EAAcN,EAAMO,MAAMC,KAAKR,GAErCA,EAAMO,KAAO,KACXF,KAAKI,aACLH,KAAe,EAGjBI,EAAaV,EAAO,CAAEG,CAACA,GAAY,UACpC,CAKSQ,UAAUC,GAClBA,EAAEC,OAAS,IACTR,KAAKJ,OAAOG,YAAYU,QACtB,CAACC,EAAKC,KAAU,IACXD,EACHC,CAACA,GAAOJ,IAAII,MAEd,CAAE,EAEP,CAKSC,YAAYL,EAAUM,GAK9B,OAJAb,KAAKJ,OAAOG,YAAYe,SAASH,IAC/BJ,EAAEI,GAAQE,IAASF,EAAK,IAGnBJ,CACR,CAKSH,aACR,MAAMW,EAAQf,KAAKL,MAAMK,KAAKJ,OAAOE,WAGrC,GAAIiB,GAAOC,MACT,MAAMhB,KAAKY,YACT,IAAIK,MAAOF,
|
|
1
|
+
{"version":3,"file":"suspense-query.js","sources":["../src/suspense-query.ts"],"sourcesContent":["import { makeExported } from './make-exported';\nimport type { TInitStore } from './types';\n\nexport interface IPromise<TReturn> extends Promise<TReturn> {\n status?: 'fulfilled' | 'pending' | 'rejected';\n value?: TReturn;\n reason?: any;\n}\n\ninterface ISuspenseQueryParams {\n fieldName?: string; // field name in target store for save suspense state\n errorFields?: string[];\n}\n\ninterface ISuspenseQueryOptions {\n hash?: unknown;\n}\n\ninterface ISuspenseSubqueryOptions {\n id: string;\n hash: unknown;\n}\n\n/**\n * Run request and cache promise\n * Sync suspense status between server and client\n */\nclass SuspenseQuery {\n /**\n * @protected\n */\n protected promise: Promise<any> | undefined;\n\n /**\n * Subqueries info\n */\n protected subqueries: Map<string, { hash: unknown; promise?: IPromise<any> }> = new Map();\n\n /**\n * Target store\n */\n protected readonly store: TInitStore;\n\n /**\n * @protected\n */\n protected readonly params: Required<ISuspenseQueryParams>;\n\n /**\n * @constructor\n */\n constructor(\n store: TInitStore,\n { fieldName = 'sR', errorFields = ['name', 'message'] }: ISuspenseQueryParams = {},\n ) {\n this.store = store;\n this.params = { fieldName, errorFields };\n\n const defaultInit = store.init?.bind(store);\n\n store.init = () => {\n this.throwError(); // throw error immediately from server side if exist\n defaultInit?.();\n };\n\n makeExported(store, { [fieldName]: 'simple' });\n }\n\n /**\n * Error to json\n */\n protected errorJson(e: any): void {\n e.toJSON = () =>\n this.params.errorFields.reduce(\n (res, name) => ({\n ...res,\n [name]: e?.[name],\n }),\n {},\n );\n }\n\n /**\n * Assign custom error fields to error\n */\n protected jsonToError(e: Error, values: Record<string, any>): Error {\n this.params.errorFields.forEach((name) => {\n e[name] = values?.[name];\n });\n\n return e;\n }\n\n /**\n * Throw suspense error\n */\n protected throwError(): void {\n const value = this.store[this.params.fieldName];\n\n // pass error to error boundary\n if (value?.error) {\n throw this.jsonToError(\n new Error((value?.error?.message ?? value?.error?.name) as string),\n value?.error as Record<string, any>,\n );\n }\n }\n\n /**\n * Detect if suspense is restored from server side:\n * - throw error if exist\n * - skip run suspense if already completed\n */\n protected isComplete(hash: unknown): boolean {\n const value = this.store[this.params.fieldName];\n\n // pass error to error boundary\n if (value?.error) {\n this.throwError();\n }\n\n return value?.done === true && value.hash === hash;\n }\n\n /**\n * Run request\n * Save request resolve status\n */\n public query = <TReturn>(\n promise: () => Promise<TReturn>,\n options: ISuspenseQueryOptions = {},\n ): TReturn | undefined => {\n const { hash = '' } = options;\n const { fieldName } = this.params;\n\n if (this.isComplete(hash)) {\n return;\n }\n\n if (this.store[fieldName]?.hash !== hash) {\n this.store[fieldName] = { hash, done: false };\n this.promise = undefined;\n }\n\n if (!this.promise) {\n this.promise = promise();\n\n this.promise.then(\n () => {\n this.store[fieldName] = { hash, done: true };\n },\n (e) => {\n this.errorJson(e);\n\n this.store[fieldName] = { error: e };\n },\n );\n }\n\n return SuspenseQuery.run<TReturn>(this.promise);\n };\n\n /**\n * Run subquery\n * Re-fetch data from query by hash changes in children components\n * NOTE: only client side\n */\n public subquery = <TReturn>(\n promise: () => Promise<TReturn>,\n options: ISuspenseSubqueryOptions,\n ): TReturn | undefined => {\n const { id, hash } = options;\n const subquery = this.subqueries.get(id);\n\n // skip first run\n if (!subquery) {\n this.subqueries.set(id, { hash });\n\n return undefined;\n }\n\n if (subquery?.hash === hash) {\n return SuspenseQuery.run<TReturn>(subquery?.promise);\n }\n\n const newQuery = promise();\n\n this.subqueries.set(id, { hash, promise: newQuery });\n\n return SuspenseQuery.run<TReturn>(newQuery);\n };\n\n /**\n * Change status of promise.\n * Throw promise to react suspense\n */\n public static run = <TReturn>(promise: IPromise<TReturn> | undefined): TReturn | undefined => {\n if (!promise) {\n return;\n }\n\n switch (promise.status) {\n case 'fulfilled':\n return promise.value;\n\n case 'pending':\n throw promise;\n\n case 'rejected':\n throw promise.reason;\n\n default:\n promise.status = 'pending';\n\n promise.then(\n (result) => {\n promise.status = 'fulfilled';\n promise.value = result;\n },\n (reason) => {\n promise.status = 'rejected';\n promise.reason = reason;\n },\n );\n }\n\n throw promise;\n };\n}\n\nexport default SuspenseQuery;\n"],"names":["SuspenseQuery","promise","subqueries","Map","store","params","constructor","fieldName","errorFields","this","defaultInit","init","bind","throwError","makeExported","errorJson","e","toJSON","reduce","res","name","jsonToError","values","forEach","value","error","Error","message","isComplete","hash","done","query","options","undefined","then","run","subquery","id","get","set","newQuery","static","status","reason","result"],"mappings":"kDA2BA,MAAMA,EAIMC,QAKAC,WAAsE,IAAIC,IAKjEC,MAKAC,OAKnBC,YACEF,GACAG,UAAEA,EAAY,KAAIC,YAAEA,EAAc,CAAC,OAAQ,YAAqC,IAEhFC,KAAKL,MAAQA,EACbK,KAAKJ,OAAS,CAAEE,YAAWC,eAE3B,MAAME,EAAcN,EAAMO,MAAMC,KAAKR,GAErCA,EAAMO,KAAO,KACXF,KAAKI,aACLH,KAAe,EAGjBI,EAAaV,EAAO,CAAEG,CAACA,GAAY,UACpC,CAKSQ,UAAUC,GAClBA,EAAEC,OAAS,IACTR,KAAKJ,OAAOG,YAAYU,QACtB,CAACC,EAAKC,KAAU,IACXD,EACHC,CAACA,GAAOJ,IAAII,MAEd,CAAE,EAEP,CAKSC,YAAYL,EAAUM,GAK9B,OAJAb,KAAKJ,OAAOG,YAAYe,SAASH,IAC/BJ,EAAEI,GAAQE,IAASF,EAAK,IAGnBJ,CACR,CAKSH,aACR,MAAMW,EAAQf,KAAKL,MAAMK,KAAKJ,OAAOE,WAGrC,GAAIiB,GAAOC,MACT,MAAMhB,KAAKY,YACT,IAAIK,MAAOF,GAAOC,OAAOE,SAAWH,GAAOC,OAAOL,MAClDI,GAAOC,MAGZ,CAOSG,WAAWC,GACnB,MAAML,EAAQf,KAAKL,MAAMK,KAAKJ,OAAOE,WAOrC,OAJIiB,GAAOC,OACThB,KAAKI,cAGgB,IAAhBW,GAAOM,MAAiBN,EAAMK,OAASA,CAC/C,CAMME,MAAQ,CACb9B,EACA+B,EAAiC,MAEjC,MAAMH,KAAEA,EAAO,IAAOG,GAChBzB,UAAEA,GAAcE,KAAKJ,OAE3B,IAAII,KAAKmB,WAAWC,GAwBpB,OApBIpB,KAAKL,MAAMG,IAAYsB,OAASA,IAClCpB,KAAKL,MAAMG,GAAa,CAAEsB,OAAMC,MAAM,GACtCrB,KAAKR,aAAUgC,GAGZxB,KAAKR,UACRQ,KAAKR,QAAUA,IAEfQ,KAAKR,QAAQiC,MACX,KACEzB,KAAKL,MAAMG,GAAa,CAAEsB,OAAMC,MAAM,EAAM,IAE7Cd,IACCP,KAAKM,UAAUC,GAEfP,KAAKL,MAAMG,GAAa,CAAEkB,MAAOT,EAAG,KAKnChB,EAAcmC,IAAa1B,KAAKR,QAAQ,EAQ1CmC,SAAW,CAChBnC,EACA+B,KAEA,MAAMK,GAAEA,EAAER,KAAEA,GAASG,EACfI,EAAW3B,KAAKP,WAAWoC,IAAID,GAGrC,IAAKD,EAGH,YAFA3B,KAAKP,WAAWqC,IAAIF,EAAI,CAAER,SAK5B,GAAIO,GAAUP,OAASA,EACrB,OAAO7B,EAAcmC,IAAaC,GAAUnC,SAG9C,MAAMuC,EAAWvC,IAIjB,OAFAQ,KAAKP,WAAWqC,IAAIF,EAAI,CAAER,OAAM5B,QAASuC,IAElCxC,EAAcmC,IAAaK,EAAS,EAOtCC,WAAuBxC,IAC5B,GAAKA,EAAL,CAIA,OAAQA,EAAQyC,QACd,IAAK,YACH,OAAOzC,EAAQuB,MAEjB,IAAK,UACH,MAAMvB,EAER,IAAK,WACH,MAAMA,EAAQ0C,OAEhB,QACE1C,EAAQyC,OAAS,UAEjBzC,EAAQiC,MACLU,IACC3C,EAAQyC,OAAS,YACjBzC,EAAQuB,MAAQoB,CAAM,IAEvBD,IACC1C,EAAQyC,OAAS,WACjBzC,EAAQ0C,OAASA,CAAM,IAK/B,MAAM1C,CA3BL,CA2BY"}
|