effector-storage 6.1.0 → 7.0.0
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/README.md +7 -40
- package/async-storage/index.cjs.map +1 -1
- package/async-storage/index.d.cts +24 -0
- package/async-storage/index.d.ts +14 -18
- package/async-storage/index.js.flow +6 -5
- package/async-storage/index.js.map +1 -1
- package/async-storage/package.json +15 -2
- package/broadcast/index.cjs.map +1 -1
- package/broadcast/index.d.cts +94 -0
- package/broadcast/index.d.ts +63 -85
- package/broadcast/index.js.flow +23 -25
- package/broadcast/index.js.map +1 -1
- package/broadcast/package.json +15 -2
- package/core/index.cjs +1 -1
- package/core/index.cjs.map +1 -1
- package/core/index.d.cts +77 -0
- package/core/index.d.ts +53 -66
- package/core/index.js +1 -1
- package/core/index.js.flow +14 -14
- package/core/index.js.map +1 -1
- package/core/package.json +15 -2
- package/index.d.cts +97 -0
- package/index.d.ts +68 -99
- package/index.js.flow +27 -28
- package/local/index.d.cts +99 -0
- package/local/index.d.ts +67 -90
- package/local/index.js.flow +25 -27
- package/local/package.json +15 -2
- package/log/index.cjs.map +1 -1
- package/log/index.d.cts +19 -0
- package/log/index.d.ts +11 -11
- package/log/index.js.flow +6 -5
- package/log/index.js.map +1 -1
- package/log/package.json +15 -2
- package/memory/index.d.cts +95 -0
- package/memory/index.d.ts +63 -82
- package/memory/index.js.flow +23 -25
- package/memory/package.json +15 -2
- package/nil/index.cjs.map +1 -1
- package/nil/index.d.cts +18 -0
- package/nil/index.d.ts +10 -10
- package/nil/index.js.flow +6 -5
- package/nil/index.js.map +1 -1
- package/nil/package.json +15 -2
- package/package.json +101 -57
- package/query/index.cjs.map +1 -1
- package/query/index.d.cts +108 -0
- package/query/index.d.ts +75 -104
- package/query/index.js.flow +30 -28
- package/query/index.js.map +1 -1
- package/query/package.json +15 -2
- package/session/index.d.cts +99 -0
- package/session/index.d.ts +67 -90
- package/session/index.js.flow +25 -27
- package/session/package.json +15 -2
- package/storage/index.cjs.map +1 -1
- package/storage/index.d.cts +23 -0
- package/storage/index.d.ts +15 -22
- package/storage/index.js.flow +7 -6
- package/storage/index.js.map +1 -1
- package/storage/package.json +15 -2
- package/tools/index.cjs.map +1 -1
- package/tools/{index.cjs.d.ts → index.d.cts} +33 -58
- package/tools/index.d.ts +33 -58
- package/tools/index.js.flow +13 -10
- package/tools/index.js.map +1 -1
- package/tools/package.json +15 -2
- package/async-storage/index.cjs.d.ts +0 -28
- package/broadcast/index.cjs.d.ts +0 -116
- package/core/index.cjs.d.ts +0 -90
- package/index.cjs.d.ts +0 -128
- package/local/index.cjs.d.ts +0 -122
- package/log/index.cjs.d.ts +0 -19
- package/memory/index.cjs.d.ts +0 -114
- package/nil/index.cjs.d.ts +0 -18
- package/query/index.cjs.d.ts +0 -137
- package/rn/async/index.cjs +0 -2
- package/rn/async/index.cjs.d.ts +0 -120
- package/rn/async/index.cjs.map +0 -1
- package/rn/async/index.d.ts +0 -120
- package/rn/async/index.js +0 -2
- package/rn/async/index.js.flow +0 -135
- package/rn/async/index.js.map +0 -1
- package/rn/async/package.json +0 -8
- package/rn/encrypted/index.cjs +0 -2
- package/rn/encrypted/index.cjs.d.ts +0 -120
- package/rn/encrypted/index.cjs.map +0 -1
- package/rn/encrypted/index.d.ts +0 -120
- package/rn/encrypted/index.js +0 -2
- package/rn/encrypted/index.js.flow +0 -137
- package/rn/encrypted/index.js.map +0 -1
- package/rn/encrypted/package.json +0 -8
- package/session/index.cjs.d.ts +0 -122
- package/storage/index.cjs.d.ts +0 -30
package/broadcast/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/broadcast/adapter.ts","../../src/broadcast/index.ts"],"sourcesContent":["import type { StorageAdapter } from '../types'\n\nexport interface BroadcastConfig {\n channel?: string\n}\n\n/**\n * BroadcastChannel instances cache\n */\nconst channels = new Map<string, BroadcastChannel>()\n\n/**\n * BroadcastChannel adapter factory\n */\nexport function adapter({\n channel = 'effector-storage',\n}: BroadcastConfig): StorageAdapter {\n let created: BroadcastChannel | undefined\n const bus = channels.get(channel) ?? (created = new BroadcastChannel(channel))\n if (created) channels.set(channel, created)\n\n const adapter: StorageAdapter = <State>(\n key: string,\n update: (raw?: any) =>
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/broadcast/adapter.ts","../../src/broadcast/index.ts"],"sourcesContent":["import type { StorageAdapter } from '../types'\n\nexport interface BroadcastConfig {\n channel?: string\n}\n\n/**\n * BroadcastChannel instances cache\n */\nconst channels = new Map<string, BroadcastChannel>()\n\n/**\n * BroadcastChannel adapter factory\n */\nexport function adapter({\n channel = 'effector-storage',\n}: BroadcastConfig): StorageAdapter {\n let created: BroadcastChannel | undefined\n const bus = channels.get(channel) ?? (created = new BroadcastChannel(channel))\n if (created) channels.set(channel, created)\n\n const adapter: StorageAdapter = <State>(\n key: string,\n update: (raw?: any) => void\n ) => {\n bus.addEventListener('message', ({ data }) => {\n // according to e2e tests, chromium can call `message`\n // instead of `messageerror`, with `null` as message's data\n if (data == null) {\n update(() => {\n throw new Error('Unable to deserialize message')\n })\n } else if (data.key === key) {\n update(() => {\n return data.value\n })\n }\n })\n\n // I know only one case when this event can be fired:\n // if message was sent from page to shared worker, and it contains `SharedArrayBuffer`\n // https://bugs.webkit.org/show_bug.cgi?id=171216\n bus.addEventListener('messageerror', () => {\n update(() => {\n throw new Error('Unable to deserialize message')\n })\n })\n\n return {\n get(box?: () => State | undefined) {\n if (box) return box()\n },\n\n set(value: State) {\n bus.postMessage({ key, value })\n },\n }\n }\n\n adapter.keyArea = bus\n return adapter\n}\n","import type { Subscription } from 'effector'\nimport type {\n ConfigPersist as BaseConfigPersist,\n ConfigStore as BaseConfigStore,\n ConfigSourceTarget as BaseConfigSourceTarget,\n StorageAdapter,\n} from '../types'\nimport type { BroadcastConfig } from './adapter'\nimport { persist as base } from '../core'\nimport { nil } from '../nil'\nimport { adapter } from './adapter'\n\nexport type {\n Contract,\n Done,\n Fail,\n Finally,\n StorageAdapter,\n StorageAdapterFactory,\n} from '../types'\nexport type { BroadcastConfig } from './adapter'\n\nexport interface ConfigPersist extends BaseConfigPersist {}\n\nexport interface ConfigStore<State, Err = Error>\n extends BroadcastConfig,\n BaseConfigStore<State, Err> {}\n\nexport interface ConfigSourceTarget<State, Err = Error>\n extends BroadcastConfig,\n BaseConfigSourceTarget<State, Err> {}\n\nexport interface Persist {\n <State, Err = Error>(config: ConfigSourceTarget<State, Err>): Subscription\n <State, Err = Error>(config: ConfigStore<State, Err>): Subscription\n}\n\n/**\n * Function, checking if `BroadcastChannel` exists and accessible\n */\nfunction supports() {\n return typeof BroadcastChannel !== 'undefined'\n}\n\n/**\n * Creates BroadcastChannel string adapter\n */\nbroadcast.factory = true as const\nexport function broadcast(config?: BroadcastConfig): StorageAdapter {\n return supports()\n ? adapter({\n ...config,\n })\n : nil({ keyArea: 'broadcast' })\n}\n\n/**\n * Creates custom partially applied `persist`\n * with predefined BroadcastChannel adapter\n */\nexport function createPersist(defaults?: ConfigPersist): Persist {\n return (config) =>\n base({\n adapter: broadcast,\n ...defaults,\n ...config,\n })\n}\n\n/**\n * Default partially applied `persist`\n */\nexport const persist = createPersist()\n"],"names":["channels","Map","broadcast","config","BroadcastChannel","channel","created","bus","get","set","adapter","key","update","addEventListener","data","Error","value","box","postMessage","keyArea","nil","createPersist","defaults","base","factory","persist"],"mappings":"iFASA,IAAMA,EAAW,IAAIC,ICuCd,SAASC,EAAUC,GACxB,MARmC,oBAArBC,iBD3BT,UAAiBC,QACtBA,EAAU,qBAEV,IAAIC,EACEC,EAAMP,EAASQ,IAAIH,KAAaC,EAAU,IAAIF,iBAAiBC,IACjEC,GAASN,EAASS,IAAIJ,EAASC,GAEnC,IAAMI,EAA0BA,CAC9BC,EACAC,KAEAL,EAAIM,iBAAiB,WAAW,EAAGC,WAGrB,MAARA,EACFF,GAAO,KACL,MAAM,IAAIG,MAAM,gCAAgC,IAEzCD,EAAKH,MAAQA,GACtBC,GAAO,IACEE,EAAKE,OAEhB,IAMFT,EAAIM,iBAAiB,gBAAgB,KACnCD,GAAO,KACL,MAAM,IAAIG,MAAM,gCAAgC,GAChD,IAGG,CACLP,GAAAA,CAAIS,GACF,GAAIA,EAAK,OAAOA,GACjB,EAEDR,GAAAA,CAAIO,GACFT,EAAIW,YAAY,CAAEP,MAAKK,SACzB,IAKJ,OADAN,EAAQS,QAAUZ,EACXG,CACT,CCXMA,CAAQ,IACHP,IAELiB,EAAI,CAAED,QAAS,aACrB,CAMO,SAASE,EAAcC,GAC5B,OAAQnB,GACNoB,EAAK,CACHb,QAASR,KACNoB,KACAnB,GAET,CApBAD,EAAUsB,SAAU,EAyBPC,IAAAA,EAAUJ"}
|
package/broadcast/package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"
|
|
4
|
+
"types": "index.d.ts",
|
|
5
5
|
"module": "index.js",
|
|
6
|
+
"main": "index.cjs",
|
|
6
7
|
"react-native": "index.js",
|
|
7
|
-
"
|
|
8
|
+
"exports": {
|
|
9
|
+
"./package.json": "./package.json",
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./index.d.ts",
|
|
13
|
+
"default": "./index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./index.d.cts",
|
|
17
|
+
"default": "./index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
8
21
|
}
|
package/core/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("effector"),r=new Map,t=e=>([r],t)=>e(t,r),a=e.createEvent();a.watch((e=>console.error(e.error))),exports.persist=function(o){var{adapter:i,store:s,source:c=s,target:n=s,clock:
|
|
1
|
+
"use strict";var e=require("effector"),r=new Map,t=e=>([r],t)=>e(t,r),a=e.createEvent();a.watch((e=>console.error(e.error))),exports.persist=function(o){var{adapter:i,store:s,source:c=s,target:n=s,clock:f=c,done:l,fail:d=a,finally:u,pickup:p,context:k,key:v,keyPrefix:g="",contract:y}=o;if(!i)throw Error("Adapter is not defined");if(!c)throw Error("Store or source is not defined");if(!n)throw Error("Target is not defined");if(!v&&c.shortName===c.id)throw Error("Key or name is not defined");if(c===n&&!e.is.store(c))throw Error("Source must be different from target");void 0===o.def&&e.is.store(c)&&(o.def=c.defaultState);var m="factory"in i?i(o):i,h=v||c.shortName,w=function(t,a){var o=r.get(t);void 0===o&&(o=new Map,r.set(t,o));var i=o.get(a);return void 0!==i||(i=e.createStore(null,{serialize:"ignore"}),o.set(a,i)),i}(m.keyArea||m,g+h),E=e.createNode(),x=()=>e.clearNode(E),P=e=>({status:r="fail",params:t,result:a,error:o})=>"done"===r?{status:r,key:h,keyPrefix:g,operation:e,value:"get"===e?a:t}:{status:r,key:h,keyPrefix:g,operation:e,value:"function"==typeof t?void 0:t,error:o};return e.withRegion(E,(()=>{var r=e.createStore([],{serialize:"ignore"}),a=m(g+h,(e=>{x(e)})),o=e.attach({source:r,effect:t(a.get)}),i=e.attach({source:r,effect:t(a.set)}),s=e.createEffect((e=>r=>!e||void 0===r||("isData"in e?e.isData(r):e(r))?r:(()=>{throw"getErrorMessages"in e?e.getErrorMessages(r):void 0})())(y)),v=e.createEvent(),E=e.createEvent(),x=o;r.updates.watch((()=>{x=e.scopeBind(o,{safe:!0})})),e.sample({clock:f,source:c,target:E}),e.sample({clock:E,source:w,filter:(e,r)=>r!==e,fn:(e,r)=>r,target:i}),e.sample({clock:[o.doneData,i],filter:e=>void 0!==e,target:w}),e.sample({clock:[o.doneData,w],target:s}),e.sample({clock:s.doneData,filter:e=>void 0!==e,target:n}),e.sample({clock:[o.finally.map(P("get")),i.finally.map(P("set")),s.fail.map(P("validate"))],target:v}),u&&e.sample({clock:v,target:u}),l&&e.sample({clock:v,filter:({status:e})=>"done"===e,fn:({key:e,keyPrefix:r,operation:t,value:a})=>({key:e,keyPrefix:r,operation:t,value:a}),target:l}),e.sample({clock:v,filter:({status:e})=>"fail"===e,fn:({key:e,keyPrefix:r,operation:t,error:a,value:o})=>({key:e,keyPrefix:r,operation:t,error:a,value:o}),target:d}),k&&r.on(k,(([e],r)=>[void 0===r?e:r])),p?(e.sample({clock:p,fn:()=>{},target:o}),r.on(p,(([e],r)=>[void 0===r?e:r]))):o()})),x.unsubscribe=x};
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/core/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/core/area.ts","../../src/core/index.ts"],"sourcesContent":["import type { Store } from 'effector'\nimport { createStore } from 'effector'\n\n/**\n * Keys areas / namespaces cache\n */\nconst areas = new Map<any, Map<string, Store<any>>>()\n\n/**\n * Get store, responsible for the key in key area / namespace\n */\nexport function getAreaStorage<State>(keyArea: any, key: string): Store<State> {\n let area = areas.get(keyArea)\n if (area === undefined) {\n area = new Map()\n areas.set(keyArea, area)\n }\n\n let store = area.get(key)\n if (store !== undefined) {\n return store\n }\n\n store = createStore(null, { serialize: 'ignore' })\n area.set(key, store)\n\n return store\n}\n","import type { Effect, Subscription } from 'effector'\nimport type {\n ConfigAdapter,\n ConfigAdapterFactory,\n ConfigPersist,\n ConfigSourceTarget,\n ConfigStore,\n Contract,\n Done,\n Fail,\n Finally,\n} from '../types'\nimport {\n attach,\n clearNode,\n createEvent,\n createEffect,\n createNode,\n createStore,\n guard,\n is,\n sample,\n scopeBind,\n withRegion,\n} from 'effector'\nimport { getAreaStorage } from './area'\n\n// helper function to swap two function arguments\n// end extract current context from ref-box\nconst contextual =\n <T, C, R>(fn: (value: T, ctx?: C) => R) =>\n ([ref]: [C?], value: T) =>\n fn(value, ref)\n\n// helper function to validate data with contract\nconst contracted =\n <T>(contract?: Contract<T>) =>\n (raw: unknown) =>\n !contract || // no contract -> data is valid\n raw === undefined || // `undefined` is always valid\n ('isData' in contract ? contract.isData(raw) : contract(raw))\n ? (raw as T)\n : (() => {\n throw 'getErrorMessages' in contract\n ? contract.getErrorMessages(raw)\n : undefined\n })()\n\n// helper function for safe bind effects to scope\n// since version 22.4.0 there is `safe` option in `scopeBind`,\n// but as long as effector-storage supports 22.0 this helper is required\nconst safeBind = (fx: Effect<any, any, any>) => {\n try {\n // @ts-expect-error due to old typings in import\n return scopeBind(fx, { safe: true })\n } catch (e) {\n return fx\n }\n}\n\n/**\n * Default sink for unhandled errors\n */\nconst sink = createEvent<Fail<any>>()\nsink.watch((payload) => console.error(payload.error))\n\n/**\n * Main `persist` function\n */\nexport function persist<State, Err = Error>(\n config: Partial<\n (ConfigAdapter | ConfigAdapterFactory<any>) &\n ConfigPersist &\n ConfigStore<State, Err> &\n ConfigSourceTarget<State, Err>\n >\n): Subscription {\n const {\n adapter: adapterOrFactory,\n store,\n source = store,\n target = store,\n clock = source,\n done,\n fail = sink,\n finally: anyway,\n pickup,\n context,\n key: keyName,\n keyPrefix = '',\n contract,\n } = config\n\n if (!adapterOrFactory) {\n throw Error('Adapter is not defined')\n }\n if (!source) {\n throw Error('Store or source is not defined')\n }\n if (!target) {\n throw Error('Target is not defined')\n }\n if (!keyName && source.shortName === (source as any).id) {\n throw Error('Key or name is not defined')\n }\n if (source === target && !is.store(source)) {\n throw Error('Source must be different from target')\n }\n\n // get default value from store, if given\n // this is used in adapter factory\n if ((config as any).def === undefined && is.store(source)) {\n ;(config as any).def = source.defaultState\n }\n\n const adapter =\n 'factory' in adapterOrFactory ? adapterOrFactory(config) : adapterOrFactory\n\n const key = keyName || source.shortName\n const storage = getAreaStorage<State>(\n adapter.keyArea || adapter,\n keyPrefix + key\n )\n const region = createNode()\n const desist = () => clearNode(region)\n\n const op =\n (operation: 'get' | 'set' | 'validate') =>\n ({ status = 'fail', params, result, error }: any): any =>\n status === 'done'\n ? {\n status,\n key,\n keyPrefix,\n operation,\n value: operation === 'get' ? result : params,\n }\n : {\n status,\n key,\n keyPrefix,\n operation,\n value: typeof params === 'function' ? undefined : params, // hide internal \"box\" implementation\n error,\n }\n\n // create all auxiliary units and nodes within the region,\n // to be able to remove them all at once on unsubscription\n withRegion(region, () => {\n const ctx = createStore<[any?]>([], { serialize: 'ignore' })\n\n const value = adapter<State>(keyPrefix + key, (x) => bindedGet(x))\n\n const getFx = attach({\n source: ctx,\n effect: contextual(value.get),\n }) as any as Effect<void, State, Err>\n\n const setFx = attach({\n source: ctx,\n effect: contextual(value.set),\n }) as any as Effect<State, void, Err>\n\n const validateFx = createEffect<unknown, State>(contracted(contract))\n\n const localAnyway = createEvent<Finally<State, Err>>()\n const localDone = localAnyway.filterMap<Done<State>>(\n ({ status, key, keyPrefix, operation, value }) =>\n status === 'done' ? { key, keyPrefix, operation, value } : undefined\n )\n const localFail = localAnyway.filterMap<Fail<Err>>(\n ({ status, key, keyPrefix, operation, error, value }: any) =>\n status === 'fail'\n ? { key, keyPrefix, operation, error, value }\n : undefined\n )\n\n const trigger = createEvent<State>()\n\n let bindedGet: (raw?: any) => any = getFx\n ctx.updates.watch(() => {\n bindedGet = safeBind(getFx)\n })\n\n sample({\n source,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n clock: clock!, // `clock` is always defined, as long as `source` is defined\n target: trigger,\n })\n\n guard({\n source: sample(storage, trigger, (current, proposed) => [\n proposed,\n current,\n ]),\n filter: ([proposed, current]) => proposed !== current,\n target: setFx.prepend(([proposed]: State[]) => proposed),\n })\n sample({ clock: [getFx.doneData, setFx], target: storage as any })\n sample({ clock: [getFx.doneData, storage], target: validateFx as any })\n sample({ clock: validateFx.doneData, target })\n\n sample({\n clock: [\n getFx.finally.map(op('get')),\n setFx.finally.map(op('set')),\n validateFx.fail.map(op('validate')),\n ],\n target: localAnyway,\n })\n\n if (anyway) sample({ clock: localAnyway, target: anyway })\n if (done) sample({ clock: localDone, target: done })\n sample({ clock: localFail, target: fail })\n\n if (context) {\n ctx.on(context, ([ref], payload) => [\n payload === undefined ? ref : payload,\n ])\n }\n\n if (pickup) {\n // pick up value from storage ONLY on `pickup` update\n sample({ clock: pickup, fn: () => undefined, target: getFx })\n ctx.on(pickup, ([ref], payload) => [\n payload === undefined ? ref : payload,\n ])\n } else {\n // kick getter to pick up initial value from storage\n getFx()\n }\n })\n\n return (desist.unsubscribe = desist)\n}\n"],"names":["areas","Map","contextual","fn","ref","value","sink","createEvent","watch","payload","console","error","config","adapter","adapterOrFactory","store","source","target","clock","done","fail","finally","anyway","pickup","context","key","keyName","keyPrefix","contract","Error","shortName","id","is","undefined","def","defaultState","storage","keyArea","area","get","set","createStore","serialize","getAreaStorage","region","createNode","desist","clearNode","op","operation","status","params","result","withRegion","ctx","x","bindedGet","getFx","attach","effect","setFx","validateFx","createEffect","raw","isData","getErrorMessages","contracted","localAnyway","localDone","filterMap","localFail","trigger","updates","fx","scopeBind","safe","e","safeBind","sample","guard","current","proposed","filter","prepend","doneData","map","on","unsubscribe"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/core/area.ts","../../src/core/index.ts"],"sourcesContent":["import type { Store } from 'effector'\nimport { createStore } from 'effector'\n\n/**\n * Keys areas / namespaces cache\n */\nconst areas = new Map<any, Map<string, Store<any>>>()\n\n/**\n * Get store, responsible for the key in key area / namespace\n */\nexport function getAreaStorage<State>(keyArea: any, key: string): Store<State> {\n let area = areas.get(keyArea)\n if (area === undefined) {\n area = new Map()\n areas.set(keyArea, area)\n }\n\n let store = area.get(key)\n if (store !== undefined) {\n return store\n }\n\n store = createStore(null, { serialize: 'ignore' })\n area.set(key, store)\n\n return store\n}\n","import type { Effect, Subscription } from 'effector'\nimport type {\n ConfigAdapter,\n ConfigAdapterFactory,\n ConfigPersist,\n ConfigSourceTarget,\n ConfigStore,\n Contract,\n Done,\n Fail,\n Finally,\n} from '../types'\nimport {\n attach,\n clearNode,\n createEvent,\n createEffect,\n createNode,\n createStore,\n is,\n sample,\n scopeBind,\n withRegion,\n} from 'effector'\nimport { getAreaStorage } from './area'\n\n// helper function to swap two function arguments\n// end extract current context from ref-box\nconst contextual =\n <T, C, R>(fn: (value: T, ctx?: C) => R) =>\n ([ref]: [C?], value: T) =>\n fn(value, ref)\n\n// helper function to validate data with contract\nconst contracted =\n <T>(contract?: Contract<T>) =>\n (raw: unknown) =>\n !contract || // no contract -> data is valid\n raw === undefined || // `undefined` is always valid\n ('isData' in contract ? contract.isData(raw) : contract(raw))\n ? (raw as T)\n : (() => {\n throw 'getErrorMessages' in contract\n ? contract.getErrorMessages(raw)\n : undefined\n })()\n\n/**\n * Default sink for unhandled errors\n */\nconst sink = createEvent<Fail<any>>()\nsink.watch((payload) => console.error(payload.error))\n\n/**\n * Main `persist` function\n */\nexport function persist<State, Err = Error>(\n config: Partial<\n (ConfigAdapter | ConfigAdapterFactory<any>) &\n ConfigPersist &\n ConfigStore<State, Err> &\n ConfigSourceTarget<State, Err>\n >\n): Subscription {\n const {\n adapter: adapterOrFactory,\n store,\n source = store,\n target = store,\n clock = source,\n done,\n fail = sink,\n finally: anyway,\n pickup,\n context,\n key: keyName,\n keyPrefix = '',\n contract,\n } = config\n\n if (!adapterOrFactory) {\n throw Error('Adapter is not defined')\n }\n if (!source) {\n throw Error('Store or source is not defined')\n }\n if (!target) {\n throw Error('Target is not defined')\n }\n if (!keyName && source.shortName === (source as any).id) {\n throw Error('Key or name is not defined')\n }\n if (source === target && !is.store(source)) {\n throw Error('Source must be different from target')\n }\n\n // get default value from store, if given\n // this is used in adapter factory\n if ((config as any).def === undefined && is.store(source)) {\n ;(config as any).def = source.defaultState\n }\n\n const adapter =\n 'factory' in adapterOrFactory ? adapterOrFactory(config) : adapterOrFactory\n\n const key = keyName || source.shortName\n const storage = getAreaStorage<State>(\n adapter.keyArea || adapter,\n keyPrefix + key\n )\n const region = createNode()\n const desist = () => clearNode(region)\n\n const op =\n (operation: 'get' | 'set' | 'validate') =>\n ({ status = 'fail', params, result, error }: any): any =>\n status === 'done'\n ? {\n status,\n key,\n keyPrefix,\n operation,\n value: operation === 'get' ? result : params,\n }\n : {\n status,\n key,\n keyPrefix,\n operation,\n value: typeof params === 'function' ? undefined : params, // hide internal \"box\" implementation\n error,\n }\n\n // create all auxiliary units and nodes within the region,\n // to be able to remove them all at once on unsubscription\n withRegion(region, () => {\n const ctx = createStore<[any?]>([], { serialize: 'ignore' })\n\n const value = adapter<State>(keyPrefix + key, (x) => {\n update(x)\n })\n\n const getFx = attach({\n source: ctx,\n effect: contextual(value.get),\n }) as any as Effect<void, State, Err>\n\n const setFx = attach({\n source: ctx,\n effect: contextual(value.set),\n }) as any as Effect<State, void, Err>\n\n const validateFx = createEffect<unknown, State>(contracted(contract))\n\n const complete = createEvent<Finally<State, Err>>()\n\n const trigger = createEvent<State>()\n\n let update: (raw?: any) => any = getFx\n ctx.updates.watch(() => {\n update = scopeBind(getFx as any, { safe: true })\n })\n\n sample({\n clock, // `clock` is always defined, as long as `source` is defined\n source,\n target: trigger,\n } as any)\n\n sample({\n clock: trigger,\n source: storage,\n filter: (current, proposed) => proposed !== current,\n fn: (_, proposed) => proposed,\n target: setFx,\n })\n\n sample({\n clock: [getFx.doneData, setFx],\n filter: <T>(x?: T | undefined): x is T => x !== undefined,\n target: storage as any,\n })\n\n sample({\n clock: [getFx.doneData, storage],\n target: validateFx as any,\n })\n\n sample({\n clock: validateFx.doneData,\n filter: <T>(x?: T | undefined): x is T => x !== undefined,\n target: target as any,\n })\n\n sample({\n clock: [\n getFx.finally.map(op('get')),\n setFx.finally.map(op('set')),\n validateFx.fail.map(op('validate')),\n ],\n target: complete,\n })\n\n // effector 23 introduced \"targetable\" types - UnitTargetable, StoreWritable, EventCallable\n // so, targeting non-targetable unit is not allowed anymore.\n // soothe typescript by casting to any for a while, until we drop support for effector 22 branch\n if (anyway) {\n sample({\n clock: complete,\n target: anyway as any,\n })\n }\n\n if (done) {\n sample({\n clock: complete,\n filter: ({ status }) => status === 'done',\n fn: ({ key, keyPrefix, operation, value }): Done<State> => ({\n key,\n keyPrefix,\n operation,\n value,\n }),\n target: done as any,\n })\n }\n\n sample({\n clock: complete,\n filter: ({ status }) => status === 'fail',\n fn: ({ key, keyPrefix, operation, error, value }: any): Fail<Err> => ({\n key,\n keyPrefix,\n operation,\n error,\n value,\n }),\n target: fail as any,\n })\n\n if (context) {\n ctx.on(context, ([ref], payload) => [\n payload === undefined ? ref : payload,\n ])\n }\n\n if (pickup) {\n // pick up value from storage ONLY on `pickup` update\n sample({ clock: pickup, fn: () => undefined, target: getFx })\n ctx.on(pickup, ([ref], payload) => [\n payload === undefined ? ref : payload,\n ])\n } else {\n // kick getter to pick up initial value from storage\n getFx()\n }\n })\n\n return (desist.unsubscribe = desist)\n}\n"],"names":["areas","Map","contextual","fn","ref","value","sink","createEvent","watch","payload","console","error","config","adapter","adapterOrFactory","store","source","target","clock","done","fail","finally","anyway","pickup","context","key","keyName","keyPrefix","contract","Error","shortName","id","is","undefined","def","defaultState","storage","keyArea","area","get","set","createStore","serialize","getAreaStorage","region","createNode","desist","clearNode","op","operation","status","params","result","withRegion","ctx","x","update","getFx","attach","effect","setFx","validateFx","createEffect","raw","isData","getErrorMessages","contracted","complete","trigger","updates","scopeBind","safe","sample","filter","current","proposed","_","doneData","map","on","unsubscribe"],"mappings":"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"}
|
package/core/index.d.cts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Unit, Store, Event, Effect, Subscription } from 'effector';
|
|
2
|
+
|
|
3
|
+
interface StorageAdapter {
|
|
4
|
+
<State>(key: string, update: (raw?: any) => void): {
|
|
5
|
+
get(raw?: any, ctx?: any): State | Promise<State | undefined> | undefined;
|
|
6
|
+
set(value: State, ctx?: any): void;
|
|
7
|
+
};
|
|
8
|
+
keyArea?: any;
|
|
9
|
+
noop?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface StorageAdapterFactory<AdapterConfig> {
|
|
12
|
+
(config?: AdapterConfig): StorageAdapter;
|
|
13
|
+
factory: true;
|
|
14
|
+
}
|
|
15
|
+
type Contract<Data> = ((raw: unknown) => raw is Data) | {
|
|
16
|
+
isData: (raw: unknown) => raw is Data;
|
|
17
|
+
getErrorMessages: (raw: unknown) => string[];
|
|
18
|
+
};
|
|
19
|
+
type Done<State> = {
|
|
20
|
+
key: string;
|
|
21
|
+
keyPrefix: string;
|
|
22
|
+
operation: 'set' | 'get';
|
|
23
|
+
value: State;
|
|
24
|
+
};
|
|
25
|
+
type Fail<Err> = {
|
|
26
|
+
key: string;
|
|
27
|
+
keyPrefix: string;
|
|
28
|
+
operation: 'set' | 'get';
|
|
29
|
+
error: Err;
|
|
30
|
+
value?: any;
|
|
31
|
+
};
|
|
32
|
+
type Finally<State, Err> = (Done<State> & {
|
|
33
|
+
status: 'done';
|
|
34
|
+
}) | (Fail<Err> & {
|
|
35
|
+
status: 'fail';
|
|
36
|
+
});
|
|
37
|
+
interface ConfigPersist {
|
|
38
|
+
pickup?: Unit<any>;
|
|
39
|
+
context?: Unit<any>;
|
|
40
|
+
keyPrefix?: string;
|
|
41
|
+
contract?: Contract<any>;
|
|
42
|
+
}
|
|
43
|
+
interface ConfigAdapter {
|
|
44
|
+
adapter: StorageAdapter;
|
|
45
|
+
}
|
|
46
|
+
interface ConfigAdapterFactory<AdapterConfig> {
|
|
47
|
+
adapter: StorageAdapterFactory<AdapterConfig>;
|
|
48
|
+
}
|
|
49
|
+
interface ConfigCommon<State, Err = Error> {
|
|
50
|
+
clock?: Unit<any>;
|
|
51
|
+
done?: Unit<Done<State>>;
|
|
52
|
+
fail?: Unit<Fail<Err>>;
|
|
53
|
+
finally?: Unit<Finally<State, Err>>;
|
|
54
|
+
pickup?: Unit<any>;
|
|
55
|
+
context?: Unit<any>;
|
|
56
|
+
key?: string;
|
|
57
|
+
keyPrefix?: string;
|
|
58
|
+
contract?: Contract<State | undefined>;
|
|
59
|
+
}
|
|
60
|
+
interface ConfigJustStore<State> {
|
|
61
|
+
store: Store<State>;
|
|
62
|
+
}
|
|
63
|
+
interface ConfigJustSourceTarget<State> {
|
|
64
|
+
source: Store<State> | Event<State> | Effect<State, any, any>;
|
|
65
|
+
target: Store<State> | Event<State> | Effect<State, any, any>;
|
|
66
|
+
}
|
|
67
|
+
interface ConfigStore<State, Err = Error> extends ConfigCommon<State, Err>, ConfigJustStore<State> {
|
|
68
|
+
}
|
|
69
|
+
interface ConfigSourceTarget<State, Err = Error> extends ConfigCommon<State, Err>, ConfigJustSourceTarget<State> {
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Main `persist` function
|
|
74
|
+
*/
|
|
75
|
+
declare function persist<State, Err = Error>(config: Partial<(ConfigAdapter | ConfigAdapterFactory<any>) & ConfigPersist & ConfigStore<State, Err> & ConfigSourceTarget<State, Err>>): Subscription;
|
|
76
|
+
|
|
77
|
+
export { persist };
|
package/core/index.d.ts
CHANGED
|
@@ -1,90 +1,77 @@
|
|
|
1
|
-
import { Unit, Store, Event, Effect, Subscription } from 'effector'
|
|
1
|
+
import { Unit, Store, Event, Effect, Subscription } from 'effector';
|
|
2
2
|
|
|
3
3
|
interface StorageAdapter {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
<State>(key: string, update: (raw?: any) => void): {
|
|
5
|
+
get(raw?: any, ctx?: any): State | Promise<State | undefined> | undefined;
|
|
6
|
+
set(value: State, ctx?: any): void;
|
|
7
|
+
};
|
|
8
|
+
keyArea?: any;
|
|
9
|
+
noop?: boolean;
|
|
10
10
|
}
|
|
11
11
|
interface StorageAdapterFactory<AdapterConfig> {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
(config?: AdapterConfig): StorageAdapter;
|
|
13
|
+
factory: true;
|
|
14
14
|
}
|
|
15
|
-
type Contract<Data> =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
getErrorMessages: (raw: unknown) => string[]
|
|
20
|
-
}
|
|
15
|
+
type Contract<Data> = ((raw: unknown) => raw is Data) | {
|
|
16
|
+
isData: (raw: unknown) => raw is Data;
|
|
17
|
+
getErrorMessages: (raw: unknown) => string[];
|
|
18
|
+
};
|
|
21
19
|
type Done<State> = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
20
|
+
key: string;
|
|
21
|
+
keyPrefix: string;
|
|
22
|
+
operation: 'set' | 'get';
|
|
23
|
+
value: State;
|
|
24
|
+
};
|
|
27
25
|
type Fail<Err> = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
type Finally<State, Err> =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
status: 'fail'
|
|
40
|
-
})
|
|
26
|
+
key: string;
|
|
27
|
+
keyPrefix: string;
|
|
28
|
+
operation: 'set' | 'get';
|
|
29
|
+
error: Err;
|
|
30
|
+
value?: any;
|
|
31
|
+
};
|
|
32
|
+
type Finally<State, Err> = (Done<State> & {
|
|
33
|
+
status: 'done';
|
|
34
|
+
}) | (Fail<Err> & {
|
|
35
|
+
status: 'fail';
|
|
36
|
+
});
|
|
41
37
|
interface ConfigPersist {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
pickup?: Unit<any>;
|
|
39
|
+
context?: Unit<any>;
|
|
40
|
+
keyPrefix?: string;
|
|
41
|
+
contract?: Contract<any>;
|
|
46
42
|
}
|
|
47
43
|
interface ConfigAdapter {
|
|
48
|
-
|
|
44
|
+
adapter: StorageAdapter;
|
|
49
45
|
}
|
|
50
46
|
interface ConfigAdapterFactory<AdapterConfig> {
|
|
51
|
-
|
|
47
|
+
adapter: StorageAdapterFactory<AdapterConfig>;
|
|
52
48
|
}
|
|
53
49
|
interface ConfigCommon<State, Err = Error> {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
clock?: Unit<any>;
|
|
51
|
+
done?: Unit<Done<State>>;
|
|
52
|
+
fail?: Unit<Fail<Err>>;
|
|
53
|
+
finally?: Unit<Finally<State, Err>>;
|
|
54
|
+
pickup?: Unit<any>;
|
|
55
|
+
context?: Unit<any>;
|
|
56
|
+
key?: string;
|
|
57
|
+
keyPrefix?: string;
|
|
58
|
+
contract?: Contract<State | undefined>;
|
|
63
59
|
}
|
|
64
60
|
interface ConfigJustStore<State> {
|
|
65
|
-
|
|
61
|
+
store: Store<State>;
|
|
66
62
|
}
|
|
67
63
|
interface ConfigJustSourceTarget<State> {
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
source: Store<State> | Event<State> | Effect<State, any, any>;
|
|
65
|
+
target: Store<State> | Event<State> | Effect<State, any, any>;
|
|
66
|
+
}
|
|
67
|
+
interface ConfigStore<State, Err = Error> extends ConfigCommon<State, Err>, ConfigJustStore<State> {
|
|
68
|
+
}
|
|
69
|
+
interface ConfigSourceTarget<State, Err = Error> extends ConfigCommon<State, Err>, ConfigJustSourceTarget<State> {
|
|
70
70
|
}
|
|
71
|
-
interface ConfigStore<State, Err = Error>
|
|
72
|
-
extends ConfigCommon<State, Err>,
|
|
73
|
-
ConfigJustStore<State> {}
|
|
74
|
-
interface ConfigSourceTarget<State, Err = Error>
|
|
75
|
-
extends ConfigCommon<State, Err>,
|
|
76
|
-
ConfigJustSourceTarget<State> {}
|
|
77
71
|
|
|
78
72
|
/**
|
|
79
73
|
* Main `persist` function
|
|
80
74
|
*/
|
|
81
|
-
declare function persist<State, Err = Error>(
|
|
82
|
-
config: Partial<
|
|
83
|
-
(ConfigAdapter | ConfigAdapterFactory<any>) &
|
|
84
|
-
ConfigPersist &
|
|
85
|
-
ConfigStore<State, Err> &
|
|
86
|
-
ConfigSourceTarget<State, Err>
|
|
87
|
-
>
|
|
88
|
-
): Subscription
|
|
75
|
+
declare function persist<State, Err = Error>(config: Partial<(ConfigAdapter | ConfigAdapterFactory<any>) & ConfigPersist & ConfigStore<State, Err> & ConfigSourceTarget<State, Err>>): Subscription;
|
|
89
76
|
|
|
90
|
-
export { persist }
|
|
77
|
+
export { persist };
|
package/core/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createStore as e,createEvent as r,is as t,createNode as o,withRegion as a,attach as i,createEffect as
|
|
1
|
+
import{createStore as e,createEvent as r,is as t,createNode as o,withRegion as a,attach as i,createEffect as f,scopeBind as n,sample as s,clearNode as c}from"effector";var l=new Map,d=e=>([r],t)=>e(t,r),u=r();function k(k){var{adapter:g,store:v,source:y=v,target:p=v,clock:m=y,done:h,fail:w=u,finally:x,pickup:E,context:P,key:D,keyPrefix:M="",contract:b}=k;if(!g)throw Error("Adapter is not defined");if(!y)throw Error("Store or source is not defined");if(!p)throw Error("Target is not defined");if(!D&&y.shortName===y.id)throw Error("Key or name is not defined");if(y===p&&!t.store(y))throw Error("Source must be different from target");void 0===k.def&&t.store(y)&&(k.def=y.defaultState);var S="factory"in g?g(k):g,z=D||y.shortName,A=function(r,t){var o=l.get(r);void 0===o&&(o=new Map,l.set(r,o));var a=o.get(t);return void 0!==a||(a=e(null,{serialize:"ignore"}),o.set(t,a)),a}(S.keyArea||S,M+z),N=o(),K=()=>c(N),T=e=>({status:r="fail",params:t,result:o,error:a})=>"done"===r?{status:r,key:z,keyPrefix:M,operation:e,value:"get"===e?o:t}:{status:r,key:z,keyPrefix:M,operation:e,value:"function"==typeof t?void 0:t,error:a};return a(N,(()=>{var t=e([],{serialize:"ignore"}),o=S(M+z,(e=>{g(e)})),a=i({source:t,effect:d(o.get)}),c=i({source:t,effect:d(o.set)}),l=f((e=>r=>!e||void 0===r||("isData"in e?e.isData(r):e(r))?r:(()=>{throw"getErrorMessages"in e?e.getErrorMessages(r):void 0})())(b)),u=r(),k=r(),g=a;t.updates.watch((()=>{g=n(a,{safe:!0})})),s({clock:m,source:y,target:k}),s({clock:k,source:A,filter:(e,r)=>r!==e,fn:(e,r)=>r,target:c}),s({clock:[a.doneData,c],filter:e=>void 0!==e,target:A}),s({clock:[a.doneData,A],target:l}),s({clock:l.doneData,filter:e=>void 0!==e,target:p}),s({clock:[a.finally.map(T("get")),c.finally.map(T("set")),l.fail.map(T("validate"))],target:u}),x&&s({clock:u,target:x}),h&&s({clock:u,filter:({status:e})=>"done"===e,fn:({key:e,keyPrefix:r,operation:t,value:o})=>({key:e,keyPrefix:r,operation:t,value:o}),target:h}),s({clock:u,filter:({status:e})=>"fail"===e,fn:({key:e,keyPrefix:r,operation:t,error:o,value:a})=>({key:e,keyPrefix:r,operation:t,error:o,value:a}),target:w}),P&&t.on(P,(([e],r)=>[void 0===r?e:r])),E?(s({clock:E,fn:()=>{},target:a}),t.on(E,(([e],r)=>[void 0===r?e:r]))):a()})),K.unsubscribe=K}u.watch((e=>console.error(e.error)));export{k as persist};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/core/index.js.flow
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* @flow
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { Unit, Store, Event, Effect, Subscription } from
|
|
8
|
+
import { Unit, Store, Event, Effect, Subscription } from "effector";
|
|
9
9
|
declare interface StorageAdapter {
|
|
10
10
|
<State>(
|
|
11
11
|
key: string,
|
|
12
|
-
update: (raw?: any) =>
|
|
12
|
+
update: (raw?: any) => void
|
|
13
13
|
): {
|
|
14
14
|
get(raw?: any, ctx?: any): State | Promise<State | void> | void,
|
|
15
15
|
set(value: State, ctx?: any): void,
|
|
@@ -28,37 +28,37 @@ declare type Contract<Data> =
|
|
|
28
28
|
isData: (raw: mixed) => boolean,
|
|
29
29
|
getErrorMessages: (raw: mixed) => string[],
|
|
30
30
|
...
|
|
31
|
-
}
|
|
31
|
+
};
|
|
32
32
|
declare type Done<State> = {
|
|
33
33
|
key: string,
|
|
34
34
|
keyPrefix: string,
|
|
35
|
-
operation:
|
|
35
|
+
operation: "set" | "get",
|
|
36
36
|
value: State,
|
|
37
37
|
...
|
|
38
|
-
}
|
|
38
|
+
};
|
|
39
39
|
declare type Fail<Err> = {
|
|
40
40
|
key: string,
|
|
41
41
|
keyPrefix: string,
|
|
42
|
-
operation:
|
|
42
|
+
operation: "set" | "get",
|
|
43
43
|
error: Err,
|
|
44
44
|
value?: any,
|
|
45
45
|
...
|
|
46
|
-
}
|
|
46
|
+
};
|
|
47
47
|
declare type Finally<State, Err> =
|
|
48
48
|
| {
|
|
49
49
|
...Done<State>,
|
|
50
50
|
...{
|
|
51
|
-
status:
|
|
51
|
+
status: "done",
|
|
52
52
|
...
|
|
53
53
|
},
|
|
54
54
|
}
|
|
55
55
|
| {
|
|
56
56
|
...Fail<Err>,
|
|
57
57
|
...{
|
|
58
|
-
status:
|
|
58
|
+
status: "fail",
|
|
59
59
|
...
|
|
60
60
|
},
|
|
61
|
-
}
|
|
61
|
+
};
|
|
62
62
|
declare interface ConfigPersist {
|
|
63
63
|
pickup?: Unit<any>;
|
|
64
64
|
context?: Unit<any>;
|
|
@@ -93,12 +93,12 @@ declare type ConfigStore<State, Err = Error> = { ... } & ConfigCommon<
|
|
|
93
93
|
State,
|
|
94
94
|
Err
|
|
95
95
|
> &
|
|
96
|
-
ConfigJustStore<State
|
|
96
|
+
ConfigJustStore<State>;
|
|
97
97
|
declare type ConfigSourceTarget<State, Err = Error> = { ... } & ConfigCommon<
|
|
98
98
|
State,
|
|
99
99
|
Err
|
|
100
100
|
> &
|
|
101
|
-
ConfigJustSourceTarget<State
|
|
101
|
+
ConfigJustSourceTarget<State>;
|
|
102
102
|
declare function persist<State, Err>(
|
|
103
103
|
config: $Rest<
|
|
104
104
|
{
|
|
@@ -109,5 +109,5 @@ declare function persist<State, Err>(
|
|
|
109
109
|
},
|
|
110
110
|
{ ... }
|
|
111
111
|
>
|
|
112
|
-
): Subscription
|
|
113
|
-
declare export { persist }
|
|
112
|
+
): Subscription;
|
|
113
|
+
declare export { persist };
|
package/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/core/area.ts","../../src/core/index.ts"],"sourcesContent":["import type { Store } from 'effector'\nimport { createStore } from 'effector'\n\n/**\n * Keys areas / namespaces cache\n */\nconst areas = new Map<any, Map<string, Store<any>>>()\n\n/**\n * Get store, responsible for the key in key area / namespace\n */\nexport function getAreaStorage<State>(keyArea: any, key: string): Store<State> {\n let area = areas.get(keyArea)\n if (area === undefined) {\n area = new Map()\n areas.set(keyArea, area)\n }\n\n let store = area.get(key)\n if (store !== undefined) {\n return store\n }\n\n store = createStore(null, { serialize: 'ignore' })\n area.set(key, store)\n\n return store\n}\n","import type { Effect, Subscription } from 'effector'\nimport type {\n ConfigAdapter,\n ConfigAdapterFactory,\n ConfigPersist,\n ConfigSourceTarget,\n ConfigStore,\n Contract,\n Done,\n Fail,\n Finally,\n} from '../types'\nimport {\n attach,\n clearNode,\n createEvent,\n createEffect,\n createNode,\n createStore,\n guard,\n is,\n sample,\n scopeBind,\n withRegion,\n} from 'effector'\nimport { getAreaStorage } from './area'\n\n// helper function to swap two function arguments\n// end extract current context from ref-box\nconst contextual =\n <T, C, R>(fn: (value: T, ctx?: C) => R) =>\n ([ref]: [C?], value: T) =>\n fn(value, ref)\n\n// helper function to validate data with contract\nconst contracted =\n <T>(contract?: Contract<T>) =>\n (raw: unknown) =>\n !contract || // no contract -> data is valid\n raw === undefined || // `undefined` is always valid\n ('isData' in contract ? contract.isData(raw) : contract(raw))\n ? (raw as T)\n : (() => {\n throw 'getErrorMessages' in contract\n ? contract.getErrorMessages(raw)\n : undefined\n })()\n\n// helper function for safe bind effects to scope\n// since version 22.4.0 there is `safe` option in `scopeBind`,\n// but as long as effector-storage supports 22.0 this helper is required\nconst safeBind = (fx: Effect<any, any, any>) => {\n try {\n // @ts-expect-error due to old typings in import\n return scopeBind(fx, { safe: true })\n } catch (e) {\n return fx\n }\n}\n\n/**\n * Default sink for unhandled errors\n */\nconst sink = createEvent<Fail<any>>()\nsink.watch((payload) => console.error(payload.error))\n\n/**\n * Main `persist` function\n */\nexport function persist<State, Err = Error>(\n config: Partial<\n (ConfigAdapter | ConfigAdapterFactory<any>) &\n ConfigPersist &\n ConfigStore<State, Err> &\n ConfigSourceTarget<State, Err>\n >\n): Subscription {\n const {\n adapter: adapterOrFactory,\n store,\n source = store,\n target = store,\n clock = source,\n done,\n fail = sink,\n finally: anyway,\n pickup,\n context,\n key: keyName,\n keyPrefix = '',\n contract,\n } = config\n\n if (!adapterOrFactory) {\n throw Error('Adapter is not defined')\n }\n if (!source) {\n throw Error('Store or source is not defined')\n }\n if (!target) {\n throw Error('Target is not defined')\n }\n if (!keyName && source.shortName === (source as any).id) {\n throw Error('Key or name is not defined')\n }\n if (source === target && !is.store(source)) {\n throw Error('Source must be different from target')\n }\n\n // get default value from store, if given\n // this is used in adapter factory\n if ((config as any).def === undefined && is.store(source)) {\n ;(config as any).def = source.defaultState\n }\n\n const adapter =\n 'factory' in adapterOrFactory ? adapterOrFactory(config) : adapterOrFactory\n\n const key = keyName || source.shortName\n const storage = getAreaStorage<State>(\n adapter.keyArea || adapter,\n keyPrefix + key\n )\n const region = createNode()\n const desist = () => clearNode(region)\n\n const op =\n (operation: 'get' | 'set' | 'validate') =>\n ({ status = 'fail', params, result, error }: any): any =>\n status === 'done'\n ? {\n status,\n key,\n keyPrefix,\n operation,\n value: operation === 'get' ? result : params,\n }\n : {\n status,\n key,\n keyPrefix,\n operation,\n value: typeof params === 'function' ? undefined : params, // hide internal \"box\" implementation\n error,\n }\n\n // create all auxiliary units and nodes within the region,\n // to be able to remove them all at once on unsubscription\n withRegion(region, () => {\n const ctx = createStore<[any?]>([], { serialize: 'ignore' })\n\n const value = adapter<State>(keyPrefix + key, (x) => bindedGet(x))\n\n const getFx = attach({\n source: ctx,\n effect: contextual(value.get),\n }) as any as Effect<void, State, Err>\n\n const setFx = attach({\n source: ctx,\n effect: contextual(value.set),\n }) as any as Effect<State, void, Err>\n\n const validateFx = createEffect<unknown, State>(contracted(contract))\n\n const localAnyway = createEvent<Finally<State, Err>>()\n const localDone = localAnyway.filterMap<Done<State>>(\n ({ status, key, keyPrefix, operation, value }) =>\n status === 'done' ? { key, keyPrefix, operation, value } : undefined\n )\n const localFail = localAnyway.filterMap<Fail<Err>>(\n ({ status, key, keyPrefix, operation, error, value }: any) =>\n status === 'fail'\n ? { key, keyPrefix, operation, error, value }\n : undefined\n )\n\n const trigger = createEvent<State>()\n\n let bindedGet: (raw?: any) => any = getFx\n ctx.updates.watch(() => {\n bindedGet = safeBind(getFx)\n })\n\n sample({\n source,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n clock: clock!, // `clock` is always defined, as long as `source` is defined\n target: trigger,\n })\n\n guard({\n source: sample(storage, trigger, (current, proposed) => [\n proposed,\n current,\n ]),\n filter: ([proposed, current]) => proposed !== current,\n target: setFx.prepend(([proposed]: State[]) => proposed),\n })\n sample({ clock: [getFx.doneData, setFx], target: storage as any })\n sample({ clock: [getFx.doneData, storage], target: validateFx as any })\n sample({ clock: validateFx.doneData, target })\n\n sample({\n clock: [\n getFx.finally.map(op('get')),\n setFx.finally.map(op('set')),\n validateFx.fail.map(op('validate')),\n ],\n target: localAnyway,\n })\n\n if (anyway) sample({ clock: localAnyway, target: anyway })\n if (done) sample({ clock: localDone, target: done })\n sample({ clock: localFail, target: fail })\n\n if (context) {\n ctx.on(context, ([ref], payload) => [\n payload === undefined ? ref : payload,\n ])\n }\n\n if (pickup) {\n // pick up value from storage ONLY on `pickup` update\n sample({ clock: pickup, fn: () => undefined, target: getFx })\n ctx.on(pickup, ([ref], payload) => [\n payload === undefined ? ref : payload,\n ])\n } else {\n // kick getter to pick up initial value from storage\n getFx()\n }\n })\n\n return (desist.unsubscribe = desist)\n}\n"],"names":["areas","Map","contextual","fn","ref","value","sink","createEvent","persist","config","adapter","adapterOrFactory","store","source","target","clock","done","fail","finally","anyway","pickup","context","key","keyName","keyPrefix","contract","Error","shortName","id","is","undefined","def","defaultState","storage","keyArea","area","get","set","createStore","serialize","getAreaStorage","region","createNode","desist","clearNode","op","operation","status","params","result","error","withRegion","ctx","x","bindedGet","getFx","attach","effect","setFx","validateFx","createEffect","raw","isData","getErrorMessages","contracted","localAnyway","localDone","filterMap","localFail","trigger","updates","watch","fx","scopeBind","safe","e","safeBind","sample","guard","current","proposed","filter","prepend","doneData","map","on","payload","unsubscribe","console"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/core/area.ts","../../src/core/index.ts"],"sourcesContent":["import type { Store } from 'effector'\nimport { createStore } from 'effector'\n\n/**\n * Keys areas / namespaces cache\n */\nconst areas = new Map<any, Map<string, Store<any>>>()\n\n/**\n * Get store, responsible for the key in key area / namespace\n */\nexport function getAreaStorage<State>(keyArea: any, key: string): Store<State> {\n let area = areas.get(keyArea)\n if (area === undefined) {\n area = new Map()\n areas.set(keyArea, area)\n }\n\n let store = area.get(key)\n if (store !== undefined) {\n return store\n }\n\n store = createStore(null, { serialize: 'ignore' })\n area.set(key, store)\n\n return store\n}\n","import type { Effect, Subscription } from 'effector'\nimport type {\n ConfigAdapter,\n ConfigAdapterFactory,\n ConfigPersist,\n ConfigSourceTarget,\n ConfigStore,\n Contract,\n Done,\n Fail,\n Finally,\n} from '../types'\nimport {\n attach,\n clearNode,\n createEvent,\n createEffect,\n createNode,\n createStore,\n is,\n sample,\n scopeBind,\n withRegion,\n} from 'effector'\nimport { getAreaStorage } from './area'\n\n// helper function to swap two function arguments\n// end extract current context from ref-box\nconst contextual =\n <T, C, R>(fn: (value: T, ctx?: C) => R) =>\n ([ref]: [C?], value: T) =>\n fn(value, ref)\n\n// helper function to validate data with contract\nconst contracted =\n <T>(contract?: Contract<T>) =>\n (raw: unknown) =>\n !contract || // no contract -> data is valid\n raw === undefined || // `undefined` is always valid\n ('isData' in contract ? contract.isData(raw) : contract(raw))\n ? (raw as T)\n : (() => {\n throw 'getErrorMessages' in contract\n ? contract.getErrorMessages(raw)\n : undefined\n })()\n\n/**\n * Default sink for unhandled errors\n */\nconst sink = createEvent<Fail<any>>()\nsink.watch((payload) => console.error(payload.error))\n\n/**\n * Main `persist` function\n */\nexport function persist<State, Err = Error>(\n config: Partial<\n (ConfigAdapter | ConfigAdapterFactory<any>) &\n ConfigPersist &\n ConfigStore<State, Err> &\n ConfigSourceTarget<State, Err>\n >\n): Subscription {\n const {\n adapter: adapterOrFactory,\n store,\n source = store,\n target = store,\n clock = source,\n done,\n fail = sink,\n finally: anyway,\n pickup,\n context,\n key: keyName,\n keyPrefix = '',\n contract,\n } = config\n\n if (!adapterOrFactory) {\n throw Error('Adapter is not defined')\n }\n if (!source) {\n throw Error('Store or source is not defined')\n }\n if (!target) {\n throw Error('Target is not defined')\n }\n if (!keyName && source.shortName === (source as any).id) {\n throw Error('Key or name is not defined')\n }\n if (source === target && !is.store(source)) {\n throw Error('Source must be different from target')\n }\n\n // get default value from store, if given\n // this is used in adapter factory\n if ((config as any).def === undefined && is.store(source)) {\n ;(config as any).def = source.defaultState\n }\n\n const adapter =\n 'factory' in adapterOrFactory ? adapterOrFactory(config) : adapterOrFactory\n\n const key = keyName || source.shortName\n const storage = getAreaStorage<State>(\n adapter.keyArea || adapter,\n keyPrefix + key\n )\n const region = createNode()\n const desist = () => clearNode(region)\n\n const op =\n (operation: 'get' | 'set' | 'validate') =>\n ({ status = 'fail', params, result, error }: any): any =>\n status === 'done'\n ? {\n status,\n key,\n keyPrefix,\n operation,\n value: operation === 'get' ? result : params,\n }\n : {\n status,\n key,\n keyPrefix,\n operation,\n value: typeof params === 'function' ? undefined : params, // hide internal \"box\" implementation\n error,\n }\n\n // create all auxiliary units and nodes within the region,\n // to be able to remove them all at once on unsubscription\n withRegion(region, () => {\n const ctx = createStore<[any?]>([], { serialize: 'ignore' })\n\n const value = adapter<State>(keyPrefix + key, (x) => {\n update(x)\n })\n\n const getFx = attach({\n source: ctx,\n effect: contextual(value.get),\n }) as any as Effect<void, State, Err>\n\n const setFx = attach({\n source: ctx,\n effect: contextual(value.set),\n }) as any as Effect<State, void, Err>\n\n const validateFx = createEffect<unknown, State>(contracted(contract))\n\n const complete = createEvent<Finally<State, Err>>()\n\n const trigger = createEvent<State>()\n\n let update: (raw?: any) => any = getFx\n ctx.updates.watch(() => {\n update = scopeBind(getFx as any, { safe: true })\n })\n\n sample({\n clock, // `clock` is always defined, as long as `source` is defined\n source,\n target: trigger,\n } as any)\n\n sample({\n clock: trigger,\n source: storage,\n filter: (current, proposed) => proposed !== current,\n fn: (_, proposed) => proposed,\n target: setFx,\n })\n\n sample({\n clock: [getFx.doneData, setFx],\n filter: <T>(x?: T | undefined): x is T => x !== undefined,\n target: storage as any,\n })\n\n sample({\n clock: [getFx.doneData, storage],\n target: validateFx as any,\n })\n\n sample({\n clock: validateFx.doneData,\n filter: <T>(x?: T | undefined): x is T => x !== undefined,\n target: target as any,\n })\n\n sample({\n clock: [\n getFx.finally.map(op('get')),\n setFx.finally.map(op('set')),\n validateFx.fail.map(op('validate')),\n ],\n target: complete,\n })\n\n // effector 23 introduced \"targetable\" types - UnitTargetable, StoreWritable, EventCallable\n // so, targeting non-targetable unit is not allowed anymore.\n // soothe typescript by casting to any for a while, until we drop support for effector 22 branch\n if (anyway) {\n sample({\n clock: complete,\n target: anyway as any,\n })\n }\n\n if (done) {\n sample({\n clock: complete,\n filter: ({ status }) => status === 'done',\n fn: ({ key, keyPrefix, operation, value }): Done<State> => ({\n key,\n keyPrefix,\n operation,\n value,\n }),\n target: done as any,\n })\n }\n\n sample({\n clock: complete,\n filter: ({ status }) => status === 'fail',\n fn: ({ key, keyPrefix, operation, error, value }: any): Fail<Err> => ({\n key,\n keyPrefix,\n operation,\n error,\n value,\n }),\n target: fail as any,\n })\n\n if (context) {\n ctx.on(context, ([ref], payload) => [\n payload === undefined ? ref : payload,\n ])\n }\n\n if (pickup) {\n // pick up value from storage ONLY on `pickup` update\n sample({ clock: pickup, fn: () => undefined, target: getFx })\n ctx.on(pickup, ([ref], payload) => [\n payload === undefined ? ref : payload,\n ])\n } else {\n // kick getter to pick up initial value from storage\n getFx()\n }\n })\n\n return (desist.unsubscribe = desist)\n}\n"],"names":["areas","Map","contextual","fn","ref","value","sink","createEvent","persist","config","adapter","adapterOrFactory","store","source","target","clock","done","fail","finally","anyway","pickup","context","key","keyName","keyPrefix","contract","Error","shortName","id","is","undefined","def","defaultState","storage","keyArea","area","get","set","createStore","serialize","getAreaStorage","region","createNode","desist","clearNode","op","operation","status","params","result","error","withRegion","ctx","x","update","getFx","attach","effect","setFx","validateFx","createEffect","raw","isData","getErrorMessages","contracted","complete","trigger","updates","watch","scopeBind","safe","sample","filter","current","proposed","_","doneData","map","on","payload","unsubscribe","console"],"mappings":"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"}
|
package/core/package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"
|
|
4
|
+
"types": "index.d.ts",
|
|
5
5
|
"module": "index.js",
|
|
6
|
+
"main": "index.cjs",
|
|
6
7
|
"react-native": "index.js",
|
|
7
|
-
"
|
|
8
|
+
"exports": {
|
|
9
|
+
"./package.json": "./package.json",
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./index.d.ts",
|
|
13
|
+
"default": "./index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./index.d.cts",
|
|
17
|
+
"default": "./index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
8
21
|
}
|
package/index.d.cts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Unit, Subscription, Store, Event, Effect } from 'effector';
|
|
2
|
+
export { AsyncStorageConfig, asyncStorage } from './async-storage';
|
|
3
|
+
export { BroadcastConfig, broadcast } from './broadcast';
|
|
4
|
+
export { LocalStorageConfig, local } from './local';
|
|
5
|
+
export { LogConfig, log } from './log';
|
|
6
|
+
export { MemoryConfig, memory } from './memory';
|
|
7
|
+
export { NilConfig, nil } from './nil';
|
|
8
|
+
export { QueryConfig, query } from './query';
|
|
9
|
+
export { SessionStorageConfig, session } from './session';
|
|
10
|
+
export { StorageConfig, storage } from './storage';
|
|
11
|
+
export { async, either, farcached } from './tools';
|
|
12
|
+
|
|
13
|
+
interface StorageAdapter {
|
|
14
|
+
<State>(key: string, update: (raw?: any) => void): {
|
|
15
|
+
get(raw?: any, ctx?: any): State | Promise<State | undefined> | undefined;
|
|
16
|
+
set(value: State, ctx?: any): void;
|
|
17
|
+
};
|
|
18
|
+
keyArea?: any;
|
|
19
|
+
noop?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface StorageAdapterFactory<AdapterConfig> {
|
|
22
|
+
(config?: AdapterConfig): StorageAdapter;
|
|
23
|
+
factory: true;
|
|
24
|
+
}
|
|
25
|
+
type Contract<Data> = ((raw: unknown) => raw is Data) | {
|
|
26
|
+
isData: (raw: unknown) => raw is Data;
|
|
27
|
+
getErrorMessages: (raw: unknown) => string[];
|
|
28
|
+
};
|
|
29
|
+
type Done<State> = {
|
|
30
|
+
key: string;
|
|
31
|
+
keyPrefix: string;
|
|
32
|
+
operation: 'set' | 'get';
|
|
33
|
+
value: State;
|
|
34
|
+
};
|
|
35
|
+
type Fail<Err> = {
|
|
36
|
+
key: string;
|
|
37
|
+
keyPrefix: string;
|
|
38
|
+
operation: 'set' | 'get';
|
|
39
|
+
error: Err;
|
|
40
|
+
value?: any;
|
|
41
|
+
};
|
|
42
|
+
type Finally<State, Err> = (Done<State> & {
|
|
43
|
+
status: 'done';
|
|
44
|
+
}) | (Fail<Err> & {
|
|
45
|
+
status: 'fail';
|
|
46
|
+
});
|
|
47
|
+
interface ConfigPersist {
|
|
48
|
+
pickup?: Unit<any>;
|
|
49
|
+
context?: Unit<any>;
|
|
50
|
+
keyPrefix?: string;
|
|
51
|
+
contract?: Contract<any>;
|
|
52
|
+
}
|
|
53
|
+
interface ConfigAdapter {
|
|
54
|
+
adapter: StorageAdapter;
|
|
55
|
+
}
|
|
56
|
+
interface ConfigAdapterFactory<AdapterConfig> {
|
|
57
|
+
adapter: StorageAdapterFactory<AdapterConfig>;
|
|
58
|
+
}
|
|
59
|
+
interface ConfigCommon<State, Err = Error> {
|
|
60
|
+
clock?: Unit<any>;
|
|
61
|
+
done?: Unit<Done<State>>;
|
|
62
|
+
fail?: Unit<Fail<Err>>;
|
|
63
|
+
finally?: Unit<Finally<State, Err>>;
|
|
64
|
+
pickup?: Unit<any>;
|
|
65
|
+
context?: Unit<any>;
|
|
66
|
+
key?: string;
|
|
67
|
+
keyPrefix?: string;
|
|
68
|
+
contract?: Contract<State | undefined>;
|
|
69
|
+
}
|
|
70
|
+
interface ConfigJustStore<State> {
|
|
71
|
+
store: Store<State>;
|
|
72
|
+
}
|
|
73
|
+
interface ConfigJustSourceTarget<State> {
|
|
74
|
+
source: Store<State> | Event<State> | Effect<State, any, any>;
|
|
75
|
+
target: Store<State> | Event<State> | Effect<State, any, any>;
|
|
76
|
+
}
|
|
77
|
+
interface ConfigStore<State, Err = Error> extends ConfigCommon<State, Err>, ConfigJustStore<State> {
|
|
78
|
+
}
|
|
79
|
+
interface ConfigSourceTarget<State, Err = Error> extends ConfigCommon<State, Err>, ConfigJustSourceTarget<State> {
|
|
80
|
+
}
|
|
81
|
+
interface Persist {
|
|
82
|
+
<State, Err = Error>(config: ConfigAdapter & ConfigSourceTarget<State, Err>): Subscription;
|
|
83
|
+
<State, Err = Error>(config: ConfigAdapter & ConfigStore<State, Err>): Subscription;
|
|
84
|
+
<AdapterConfig, State, Err = Error>(config: ConfigAdapterFactory<AdapterConfig> & ConfigSourceTarget<State, Err> & AdapterConfig): Subscription;
|
|
85
|
+
<AdapterConfig, State, Err = Error>(config: ConfigAdapterFactory<AdapterConfig> & ConfigStore<State, Err> & AdapterConfig): Subscription;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Creates custom `persist`
|
|
90
|
+
*/
|
|
91
|
+
declare function createPersist(defaults?: ConfigPersist): Persist;
|
|
92
|
+
/**
|
|
93
|
+
* Default `persist`
|
|
94
|
+
*/
|
|
95
|
+
declare const persist: Persist;
|
|
96
|
+
|
|
97
|
+
export { type ConfigPersist, type ConfigSourceTarget, type ConfigStore, type Contract, type Done, type Fail, type Finally, type Persist, type StorageAdapter, type StorageAdapterFactory, createPersist, persist };
|