react-state-bucket 1.2.7 → 1.2.9

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/index.d.ts CHANGED
@@ -1,23 +1,37 @@
1
1
  import * as xanv from 'xanv';
2
- import Bucket, { InitialBucketData, BucketOptions } from './Bucket.js';
2
+ import { XVInstanceType } from 'xanv';
3
3
 
4
- declare const createBucket: <IT extends InitialBucketData>(initial: IT, option?: BucketOptions) => () => Bucket<IT>;
4
+ type StoreType = "memory" | "session" | "local" | "url" | "cookie";
5
+ type BucketOptions = {
6
+ store?: StoreType;
7
+ data_key?: string;
8
+ onChange?: (key: string, value: any) => void;
9
+ };
10
+ type InitialBucketData = {
11
+ [key: string]: XVInstanceType;
12
+ };
13
+ declare const createBucket: <T extends InitialBucketData>(initial: T, option?: BucketOptions) => {
14
+ (): Record<keyof T, any>;
15
+ validate(): boolean;
16
+ errors(): Record<string, string>;
17
+ };
5
18
  declare const xv: {
6
19
  any: () => xanv.XVAny<any>;
7
- array: (type: xanv.XVInstanceType, length?: number) => xanv.XVArray<any[]>;
20
+ array: (type: XVInstanceType, length?: number) => xanv.XVArray<any[]>;
8
21
  boolean: () => xanv.XVBoolean;
9
22
  date: () => xanv.XVDate<Date>;
10
23
  enum: (values: xanv.XVEnumValues) => xanv.XVEnum<string | number>;
11
24
  file: () => xanv.XVFile<File | Blob>;
12
- map: (key: xanv.XVInstanceType, value: xanv.XVInstanceType) => xanv.XVMap<any, any>;
25
+ map: (key: XVInstanceType, value: XVInstanceType) => xanv.XVMap<any, any>;
13
26
  number: (length?: number) => xanv.XVNumber<number>;
14
27
  object: (arg?: xanv.XVObjectType) => xanv.XVObject<Record<any, any>>;
15
- record: (key: xanv.XVInstanceType, value: xanv.XVInstanceType) => xanv.XVRecord<string, any>;
16
- set: (type: xanv.XVInstanceType) => xanv.XVSet<unknown>;
28
+ record: (key: XVInstanceType, value: XVInstanceType) => xanv.XVRecord<string, any>;
29
+ set: (type: XVInstanceType) => xanv.XVSet<unknown>;
17
30
  string: (length?: number) => xanv.XVString<string>;
18
- tuple: (type: xanv.XVInstanceType[]) => xanv.XVTuple<any[]>;
19
- union: (type: xanv.XVInstanceType[]) => xanv.XVUnion<any>;
31
+ tuple: (type: XVInstanceType[]) => xanv.XVTuple<any[]>;
32
+ union: (type: XVInstanceType[]) => xanv.XVUnion<any>;
20
33
  json: () => xanv.XVJson;
21
34
  };
22
35
 
23
36
  export { createBucket, xv };
37
+ export type { BucketOptions, InitialBucketData, StoreType };
package/index.js CHANGED
@@ -1,15 +1,139 @@
1
- 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var react=require('react'),xanv=require('xanv'),Bucket=require('./Bucket.js');const createBucket = (initial, option) => {
2
- const bucket = new Bucket.default(initial, option);
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var react=require('react'),xanv=require('xanv'),youid=require('youid'),Cookie=require('./Cookie.js');const createBucket = (initial, option) => {
2
+ const hooks = new Map();
3
+ const state = {};
4
+ let data_key = (option === null || option === void 0 ? void 0 : option.data_key) || '';
5
+ if (!(option === null || option === void 0 ? void 0 : option.data_key)) {
6
+ let data_key = '';
7
+ for (let key in initial) {
8
+ const field = initial[key];
9
+ data_key += key + ':' + JSON.stringify(field.meta) + ';';
10
+ }
11
+ data_key = youid(data_key);
12
+ }
13
+ option = Object.assign(Object.assign({ store: "memory" }, option), { data_key });
14
+ // set state prototype for validation
15
+ for (let key in initial) {
16
+ try {
17
+ state[key] = initial[key].parse(undefined);
18
+ }
19
+ catch (error) { }
20
+ }
21
+ if (typeof window !== 'undefined') {
22
+ if (option.store === 'session' || option.store === 'local') {
23
+ let storage = option.store === "session" ? sessionStorage : localStorage;
24
+ const value = storage.getItem(data_key);
25
+ let data = {};
26
+ if (value) {
27
+ data = JSON.parse(value);
28
+ }
29
+ for (let key in initial) {
30
+ try {
31
+ state[key] = initial[key].parse(data[key]);
32
+ }
33
+ catch (error) {
34
+ state[key] = data[key];
35
+ }
36
+ }
37
+ }
38
+ else if (option.store === 'url') {
39
+ let url = new URL(window.location.href);
40
+ const value = url.searchParams.get(data_key);
41
+ let data = {};
42
+ if (value) {
43
+ data = JSON.parse(decodeURIComponent(value));
44
+ }
45
+ for (let key in initial) {
46
+ try {
47
+ state[key] = initial[key].parse(data[key]);
48
+ }
49
+ catch (error) {
50
+ state[key] = data[key];
51
+ }
52
+ }
53
+ }
54
+ else if (option.store === 'cookie') {
55
+ const cookieData = Cookie.getCookie(data_key);
56
+ let data = {};
57
+ if (cookieData) {
58
+ data = JSON.parse(cookieData);
59
+ }
60
+ for (let key in initial) {
61
+ try {
62
+ state[key] = initial[key].parse(data[key]);
63
+ }
64
+ catch (error) {
65
+ state[key] = data[key];
66
+ }
67
+ }
68
+ }
69
+ else {
70
+ for (let key in initial) {
71
+ try {
72
+ state[key] = initial[key].parse(undefined);
73
+ }
74
+ catch (error) {
75
+ }
76
+ }
77
+ }
78
+ }
3
79
  const useBucket = () => {
4
80
  const id = "rsb_" + react.useId();
5
81
  const [, setState] = react.useState(0);
6
82
  react.useEffect(() => {
7
- bucket.subscribe(id, () => setState(Math.random()));
83
+ hooks.set(id, () => setState(Math.random()));
8
84
  return () => {
9
- bucket.unsubscribe(id);
85
+ hooks.delete(id);
10
86
  };
11
87
  }, [id]);
12
- return bucket;
88
+ return new Proxy(state, {
89
+ get: (target, prop) => target[prop],
90
+ set: (target, prop, value) => {
91
+ if (!(prop in initial)) {
92
+ throw new Error(`Property ${String(prop)} is not defined in the bucket.`);
93
+ }
94
+ target[prop] = value;
95
+ hooks.forEach((hook) => hook());
96
+ if (typeof window !== 'undefined') {
97
+ value = JSON.stringify(value);
98
+ if (option.store === 'session' || option.store === 'local') {
99
+ let storage = option.store === "session" ? sessionStorage : localStorage;
100
+ storage.setItem(data_key, JSON.stringify(state));
101
+ }
102
+ else if (option.store === 'url') {
103
+ let url = new URL(window.location.href);
104
+ url.searchParams.set(data_key, encodeURIComponent(JSON.stringify(state)));
105
+ window.history.replaceState({}, '', url.toString());
106
+ }
107
+ else if (option.store === 'cookie') {
108
+ Cookie.setCookie(data_key, JSON.stringify(state));
109
+ }
110
+ }
111
+ return true;
112
+ }
113
+ });
114
+ };
115
+ useBucket.validate = () => {
116
+ try {
117
+ for (let k in initial) {
118
+ initial[k].parse(state[k]);
119
+ }
120
+ }
121
+ catch (error) {
122
+ return false;
123
+ }
124
+ return true;
125
+ };
126
+ useBucket.errors = () => {
127
+ const errors = {};
128
+ for (let k in initial) {
129
+ try {
130
+ initial[k].parse(state[k]);
131
+ }
132
+ catch (error) {
133
+ errors[k] = error.message;
134
+ }
135
+ }
136
+ return errors;
13
137
  };
14
138
  return useBucket;
15
139
  };
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { useEffect, useId, useState } from \"react\"\nimport { xv as XV } from \"xanv\"\nimport Bucket, { BucketOptions, InitialBucketData } from \"./Bucket\"\n\nexport const createBucket = <IT extends InitialBucketData>(initial: IT, option?: BucketOptions) => {\n const bucket = new Bucket(initial, option)\n const useBucket = () => {\n const id = \"rsb_\" + useId()\n const [, setState] = useState(0)\n\n useEffect(() => {\n bucket.subscribe(id, () => setState(Math.random()))\n return () => {\n bucket.unsubscribe(id)\n }\n }, [id])\n\n return bucket\n }\n return useBucket\n}\n\nexport const xv = XV"],"names":["Bucket","useId","useState","useEffect","XV"],"mappings":"0JAIa,YAAY,GAAG,CAA+B,OAAW,EAAE,MAAsB,KAAI;IAChG,MAAM,MAAM,GAAG,IAAIA,cAAM,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1C,MAAM,SAAS,GAAG,MAAK;AACrB,QAAA,MAAM,EAAE,GAAG,MAAM,GAAGC,WAAK,EAAE;QAC3B,MAAM,GAAG,QAAQ,CAAC,GAAGC,cAAQ,CAAC,CAAC,CAAC;QAEhCC,eAAS,CAAC,MAAK;AACb,YAAA,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AACnD,YAAA,OAAO,MAAK;AACV,gBAAA,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;AACxB,YAAA,CAAC;AACH,QAAA,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAER,QAAA,OAAO,MAAM;AACf,IAAA,CAAC;AACD,IAAA,OAAO,SAAS;AAClB;AAEO,MAAM,EAAE,GAAGC"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { useEffect, useId, useState } from \"react\"\nimport { xv as XV, XVInstanceType } from \"xanv\"\nimport youid from \"youid\";\nimport { getCookie, setCookie } from \"./Cookie\";\n\nexport type StoreType = \"memory\" | \"session\" | \"local\" | \"url\" | \"cookie\"\nexport type BucketOptions = {\n store?: StoreType;\n data_key?: string;\n onChange?: (key: string, value: any) => void\n}\n\nexport type InitialBucketData = {\n [key: string]: XVInstanceType\n}\n\nexport const createBucket = <T extends InitialBucketData>(initial: T, option?: BucketOptions) => {\n const hooks = new Map<string, Function>()\n const state: Record<keyof T, T[keyof T]> = {} as any\n\n let data_key = option?.data_key || ''\n if (!option?.data_key) {\n let data_key = ''\n for (let key in initial) {\n const field = initial[key]\n data_key += key + ':' + JSON.stringify(field.meta) + ';'\n }\n data_key = youid(data_key)\n }\n\n option = {\n store: \"memory\",\n ...option,\n data_key,\n }\n // set state prototype for validation\n\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(undefined)\n } catch (error) { }\n }\n\n if (typeof window !== 'undefined') {\n if (option.store === 'session' || option.store === 'local') {\n let storage = option.store === \"session\" ? sessionStorage : localStorage\n const value = storage.getItem(data_key)\n let data: any = {}\n if (value) {\n data = JSON.parse(value)\n }\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(data[key])\n } catch (error) {\n state[key] = data[key]\n }\n }\n } else if (option.store === 'url') {\n let url = new URL(window.location.href)\n const value = url.searchParams.get(data_key)\n let data: any = {}\n if (value) {\n data = JSON.parse(decodeURIComponent(value))\n }\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(data[key])\n } catch (error) {\n state[key] = data[key]\n }\n }\n } else if (option.store === 'cookie') {\n const cookieData = getCookie(data_key)\n let data: any = {}\n if (cookieData) {\n data = JSON.parse(cookieData)\n }\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(data[key])\n } catch (error) {\n state[key] = data[key]\n }\n }\n } else {\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(undefined)\n } catch (error) {\n }\n }\n }\n }\n\n const useBucket = () => {\n const id = \"rsb_\" + useId()\n const [, setState] = useState(0)\n\n useEffect(() => {\n hooks.set(id, () => setState(Math.random()))\n return () => {\n hooks.delete(id)\n }\n }, [id])\n\n return new Proxy(state, {\n get: (target: any, prop: string) => target[prop],\n set: (target, prop: string, value) => {\n if (!(prop in initial)) {\n throw new Error(`Property ${String(prop)} is not defined in the bucket.`)\n }\n (target as any)[prop as keyof T] = value;\n hooks.forEach((hook) => hook());\n if (typeof window !== 'undefined') {\n value = JSON.stringify(value) as any\n if (option.store === 'session' || option.store === 'local') {\n let storage = option.store === \"session\" ? sessionStorage : localStorage\n storage.setItem(data_key, JSON.stringify(state))\n } else if (option.store === 'url') {\n let url = new URL(window.location.href)\n url.searchParams.set(data_key, encodeURIComponent(JSON.stringify(state)))\n window.history.replaceState({}, '', url.toString())\n } else if (option.store === 'cookie') {\n setCookie(data_key, JSON.stringify(state))\n }\n }\n return true;\n }\n }) as Record<keyof T, any>\n }\n\n useBucket.validate = () => {\n try {\n for (let k in initial) {\n initial[k].parse(state[k])\n }\n } catch (error) {\n return false\n }\n return true\n }\n\n useBucket.errors = () => {\n const errors: Record<string, string> = {}\n for (let k in initial) {\n try {\n initial[k].parse(state[k])\n } catch (error: any) {\n errors[k] = error.message\n }\n }\n return errors\n }\n\n return useBucket\n}\n\nexport const xv = XV"],"names":["getCookie","useId","useState","useEffect","setCookie","XV"],"mappings":"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"}
package/index.mjs CHANGED
@@ -1,15 +1,139 @@
1
- import {useId,useState,useEffect}from'react';import {xv as xv$1}from'xanv';import Bucket from'./Bucket.mjs';const createBucket = (initial, option) => {
2
- const bucket = new Bucket(initial, option);
1
+ import {useId,useState,useEffect}from'react';import {xv as xv$1}from'xanv';import youid from'youid';import {getCookie,setCookie}from'./Cookie.mjs';const createBucket = (initial, option) => {
2
+ const hooks = new Map();
3
+ const state = {};
4
+ let data_key = (option === null || option === void 0 ? void 0 : option.data_key) || '';
5
+ if (!(option === null || option === void 0 ? void 0 : option.data_key)) {
6
+ let data_key = '';
7
+ for (let key in initial) {
8
+ const field = initial[key];
9
+ data_key += key + ':' + JSON.stringify(field.meta) + ';';
10
+ }
11
+ data_key = youid(data_key);
12
+ }
13
+ option = Object.assign(Object.assign({ store: "memory" }, option), { data_key });
14
+ // set state prototype for validation
15
+ for (let key in initial) {
16
+ try {
17
+ state[key] = initial[key].parse(undefined);
18
+ }
19
+ catch (error) { }
20
+ }
21
+ if (typeof window !== 'undefined') {
22
+ if (option.store === 'session' || option.store === 'local') {
23
+ let storage = option.store === "session" ? sessionStorage : localStorage;
24
+ const value = storage.getItem(data_key);
25
+ let data = {};
26
+ if (value) {
27
+ data = JSON.parse(value);
28
+ }
29
+ for (let key in initial) {
30
+ try {
31
+ state[key] = initial[key].parse(data[key]);
32
+ }
33
+ catch (error) {
34
+ state[key] = data[key];
35
+ }
36
+ }
37
+ }
38
+ else if (option.store === 'url') {
39
+ let url = new URL(window.location.href);
40
+ const value = url.searchParams.get(data_key);
41
+ let data = {};
42
+ if (value) {
43
+ data = JSON.parse(decodeURIComponent(value));
44
+ }
45
+ for (let key in initial) {
46
+ try {
47
+ state[key] = initial[key].parse(data[key]);
48
+ }
49
+ catch (error) {
50
+ state[key] = data[key];
51
+ }
52
+ }
53
+ }
54
+ else if (option.store === 'cookie') {
55
+ const cookieData = getCookie(data_key);
56
+ let data = {};
57
+ if (cookieData) {
58
+ data = JSON.parse(cookieData);
59
+ }
60
+ for (let key in initial) {
61
+ try {
62
+ state[key] = initial[key].parse(data[key]);
63
+ }
64
+ catch (error) {
65
+ state[key] = data[key];
66
+ }
67
+ }
68
+ }
69
+ else {
70
+ for (let key in initial) {
71
+ try {
72
+ state[key] = initial[key].parse(undefined);
73
+ }
74
+ catch (error) {
75
+ }
76
+ }
77
+ }
78
+ }
3
79
  const useBucket = () => {
4
80
  const id = "rsb_" + useId();
5
81
  const [, setState] = useState(0);
6
82
  useEffect(() => {
7
- bucket.subscribe(id, () => setState(Math.random()));
83
+ hooks.set(id, () => setState(Math.random()));
8
84
  return () => {
9
- bucket.unsubscribe(id);
85
+ hooks.delete(id);
10
86
  };
11
87
  }, [id]);
12
- return bucket;
88
+ return new Proxy(state, {
89
+ get: (target, prop) => target[prop],
90
+ set: (target, prop, value) => {
91
+ if (!(prop in initial)) {
92
+ throw new Error(`Property ${String(prop)} is not defined in the bucket.`);
93
+ }
94
+ target[prop] = value;
95
+ hooks.forEach((hook) => hook());
96
+ if (typeof window !== 'undefined') {
97
+ value = JSON.stringify(value);
98
+ if (option.store === 'session' || option.store === 'local') {
99
+ let storage = option.store === "session" ? sessionStorage : localStorage;
100
+ storage.setItem(data_key, JSON.stringify(state));
101
+ }
102
+ else if (option.store === 'url') {
103
+ let url = new URL(window.location.href);
104
+ url.searchParams.set(data_key, encodeURIComponent(JSON.stringify(state)));
105
+ window.history.replaceState({}, '', url.toString());
106
+ }
107
+ else if (option.store === 'cookie') {
108
+ setCookie(data_key, JSON.stringify(state));
109
+ }
110
+ }
111
+ return true;
112
+ }
113
+ });
114
+ };
115
+ useBucket.validate = () => {
116
+ try {
117
+ for (let k in initial) {
118
+ initial[k].parse(state[k]);
119
+ }
120
+ }
121
+ catch (error) {
122
+ return false;
123
+ }
124
+ return true;
125
+ };
126
+ useBucket.errors = () => {
127
+ const errors = {};
128
+ for (let k in initial) {
129
+ try {
130
+ initial[k].parse(state[k]);
131
+ }
132
+ catch (error) {
133
+ errors[k] = error.message;
134
+ }
135
+ }
136
+ return errors;
13
137
  };
14
138
  return useBucket;
15
139
  };
package/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { useEffect, useId, useState } from \"react\"\nimport { xv as XV } from \"xanv\"\nimport Bucket, { BucketOptions, InitialBucketData } from \"./Bucket\"\n\nexport const createBucket = <IT extends InitialBucketData>(initial: IT, option?: BucketOptions) => {\n const bucket = new Bucket(initial, option)\n const useBucket = () => {\n const id = \"rsb_\" + useId()\n const [, setState] = useState(0)\n\n useEffect(() => {\n bucket.subscribe(id, () => setState(Math.random()))\n return () => {\n bucket.unsubscribe(id)\n }\n }, [id])\n\n return bucket\n }\n return useBucket\n}\n\nexport const xv = XV"],"names":["XV"],"mappings":"kHAIa,YAAY,GAAG,CAA+B,OAAW,EAAE,MAAsB,KAAI;IAChG,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1C,MAAM,SAAS,GAAG,MAAK;AACrB,QAAA,MAAM,EAAE,GAAG,MAAM,GAAG,KAAK,EAAE;QAC3B,MAAM,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;QAEhC,SAAS,CAAC,MAAK;AACb,YAAA,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AACnD,YAAA,OAAO,MAAK;AACV,gBAAA,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;AACxB,YAAA,CAAC;AACH,QAAA,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAER,QAAA,OAAO,MAAM;AACf,IAAA,CAAC;AACD,IAAA,OAAO,SAAS;AAClB;AAEO,MAAM,EAAE,GAAGA"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { useEffect, useId, useState } from \"react\"\nimport { xv as XV, XVInstanceType } from \"xanv\"\nimport youid from \"youid\";\nimport { getCookie, setCookie } from \"./Cookie\";\n\nexport type StoreType = \"memory\" | \"session\" | \"local\" | \"url\" | \"cookie\"\nexport type BucketOptions = {\n store?: StoreType;\n data_key?: string;\n onChange?: (key: string, value: any) => void\n}\n\nexport type InitialBucketData = {\n [key: string]: XVInstanceType\n}\n\nexport const createBucket = <T extends InitialBucketData>(initial: T, option?: BucketOptions) => {\n const hooks = new Map<string, Function>()\n const state: Record<keyof T, T[keyof T]> = {} as any\n\n let data_key = option?.data_key || ''\n if (!option?.data_key) {\n let data_key = ''\n for (let key in initial) {\n const field = initial[key]\n data_key += key + ':' + JSON.stringify(field.meta) + ';'\n }\n data_key = youid(data_key)\n }\n\n option = {\n store: \"memory\",\n ...option,\n data_key,\n }\n // set state prototype for validation\n\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(undefined)\n } catch (error) { }\n }\n\n if (typeof window !== 'undefined') {\n if (option.store === 'session' || option.store === 'local') {\n let storage = option.store === \"session\" ? sessionStorage : localStorage\n const value = storage.getItem(data_key)\n let data: any = {}\n if (value) {\n data = JSON.parse(value)\n }\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(data[key])\n } catch (error) {\n state[key] = data[key]\n }\n }\n } else if (option.store === 'url') {\n let url = new URL(window.location.href)\n const value = url.searchParams.get(data_key)\n let data: any = {}\n if (value) {\n data = JSON.parse(decodeURIComponent(value))\n }\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(data[key])\n } catch (error) {\n state[key] = data[key]\n }\n }\n } else if (option.store === 'cookie') {\n const cookieData = getCookie(data_key)\n let data: any = {}\n if (cookieData) {\n data = JSON.parse(cookieData)\n }\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(data[key])\n } catch (error) {\n state[key] = data[key]\n }\n }\n } else {\n for (let key in initial) {\n try {\n state[key] = initial[key].parse(undefined)\n } catch (error) {\n }\n }\n }\n }\n\n const useBucket = () => {\n const id = \"rsb_\" + useId()\n const [, setState] = useState(0)\n\n useEffect(() => {\n hooks.set(id, () => setState(Math.random()))\n return () => {\n hooks.delete(id)\n }\n }, [id])\n\n return new Proxy(state, {\n get: (target: any, prop: string) => target[prop],\n set: (target, prop: string, value) => {\n if (!(prop in initial)) {\n throw new Error(`Property ${String(prop)} is not defined in the bucket.`)\n }\n (target as any)[prop as keyof T] = value;\n hooks.forEach((hook) => hook());\n if (typeof window !== 'undefined') {\n value = JSON.stringify(value) as any\n if (option.store === 'session' || option.store === 'local') {\n let storage = option.store === \"session\" ? sessionStorage : localStorage\n storage.setItem(data_key, JSON.stringify(state))\n } else if (option.store === 'url') {\n let url = new URL(window.location.href)\n url.searchParams.set(data_key, encodeURIComponent(JSON.stringify(state)))\n window.history.replaceState({}, '', url.toString())\n } else if (option.store === 'cookie') {\n setCookie(data_key, JSON.stringify(state))\n }\n }\n return true;\n }\n }) as Record<keyof T, any>\n }\n\n useBucket.validate = () => {\n try {\n for (let k in initial) {\n initial[k].parse(state[k])\n }\n } catch (error) {\n return false\n }\n return true\n }\n\n useBucket.errors = () => {\n const errors: Record<string, string> = {}\n for (let k in initial) {\n try {\n initial[k].parse(state[k])\n } catch (error: any) {\n errors[k] = error.message\n }\n }\n return errors\n }\n\n return useBucket\n}\n\nexport const xv = XV"],"names":["XV"],"mappings":"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"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.2.7",
2
+ "version": "1.2.9",
3
3
  "name": "react-state-bucket",
4
4
  "author": "Naxrul Ahmed",
5
5
  "license": "MIT",
package/Bucket.d.ts DELETED
@@ -1,33 +0,0 @@
1
- import { XVInstanceType, Infer } from 'xanv';
2
-
3
- type StoreType = "memory" | "session" | "local" | "url" | "cookie";
4
- type InitialBucketData = {
5
- [key: string]: XVInstanceType;
6
- };
7
- type BucketOptions = {
8
- store?: StoreType;
9
- data_key?: string;
10
- onChange?: (key: string, value: any) => void;
11
- };
12
- declare class Bucket<IT extends InitialBucketData> {
13
- private initial;
14
- private option;
15
- private hooks;
16
- private data;
17
- readonly changes: Map<keyof IT, boolean>;
18
- private data_key;
19
- constructor(initial: IT, option?: BucketOptions);
20
- subscribe(id: string, hook: Function): void;
21
- unsubscribe(id: string): void;
22
- set<T extends keyof IT>(key: T, value: Infer<IT[T]>, dispatch?: boolean): void;
23
- get<T extends keyof IT>(key: T): Record<any, any>[T];
24
- sets(state: {
25
- [key in keyof IT]?: Infer<IT[key]>;
26
- }): void;
27
- validate(): boolean;
28
- get state(): { [key in keyof IT]: Infer<IT[key]>; };
29
- get errors(): Map<keyof IT, string>;
30
- }
31
-
32
- export { Bucket as default };
33
- export type { BucketOptions, InitialBucketData, StoreType };
package/Bucket.js DELETED
@@ -1,145 +0,0 @@
1
- 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var Cookie=require('./Cookie.js'),youid=require('youid');class Bucket {
2
- constructor(initial, option) {
3
- this.hooks = new Map();
4
- this.data = {};
5
- this.changes = new Map();
6
- this.initial = initial;
7
- this.option = Object.assign({ store: "memory" }, option);
8
- this.data_key = (option === null || option === void 0 ? void 0 : option.data_key) || '';
9
- if (!this.data_key) {
10
- let data_key = '';
11
- for (let key in initial) {
12
- const field = initial[key];
13
- data_key += key + ':' + JSON.stringify(field.meta) + ';';
14
- }
15
- this.data_key = youid(data_key);
16
- }
17
- if (typeof window !== 'undefined') {
18
- if (this.option.store === 'session' || this.option.store === 'local') {
19
- let storage = this.option.store === "session" ? sessionStorage : localStorage;
20
- const value = storage.getItem(this.data_key);
21
- let data = {};
22
- if (value) {
23
- data = JSON.parse(value);
24
- }
25
- for (let key in initial) {
26
- try {
27
- this.data[key] = initial[key].parse(data[key]);
28
- }
29
- catch (error) {
30
- this.data[key] = data[key];
31
- }
32
- }
33
- }
34
- else if (this.option.store === 'url') {
35
- let url = new URL(window.location.href);
36
- const value = url.searchParams.get(this.data_key);
37
- let data = {};
38
- if (value) {
39
- data = JSON.parse(decodeURIComponent(value));
40
- }
41
- for (let key in initial) {
42
- try {
43
- this.data[key] = initial[key].parse(data[key]);
44
- }
45
- catch (error) {
46
- this.data[key] = data[key];
47
- }
48
- }
49
- }
50
- else if (this.option.store === 'cookie') {
51
- const cookieData = Cookie.getCookie(this.data_key);
52
- let data = {};
53
- if (cookieData) {
54
- data = JSON.parse(cookieData);
55
- }
56
- for (let key in initial) {
57
- try {
58
- this.data[key] = initial[key].parse(data[key]);
59
- }
60
- catch (error) {
61
- this.data[key] = data[key];
62
- }
63
- }
64
- }
65
- }
66
- }
67
- subscribe(id, hook) {
68
- if (!id.startsWith("rsb_"))
69
- throw new Error("Invalid subscription");
70
- this.hooks.set(id, hook);
71
- }
72
- unsubscribe(id) {
73
- this.hooks.delete(id);
74
- }
75
- set(key, value, dispatch = true) {
76
- if (!(key in this.initial)) {
77
- throw new Error(`Key ${String(key)} not in Bucket initial data`);
78
- }
79
- this.data[key] = value;
80
- this.changes.set(key, true);
81
- if (this.option.onChange) {
82
- this.option.onChange(key, value);
83
- }
84
- if (typeof window !== 'undefined') {
85
- value = JSON.stringify(value);
86
- if (this.option.store === 'session' || this.option.store === 'local') {
87
- let storage = this.option.store === "session" ? sessionStorage : localStorage;
88
- storage.setItem(this.data_key, JSON.stringify(this.data));
89
- }
90
- else if (this.option.store === 'url') {
91
- let url = new URL(window.location.href);
92
- url.searchParams.set(this.data_key, encodeURIComponent(JSON.stringify(this.data)));
93
- window.history.replaceState({}, '', url.toString());
94
- }
95
- else if (this.option.store === 'cookie') {
96
- Cookie.setCookie(this.data_key, JSON.stringify(this.data));
97
- }
98
- }
99
- if (dispatch) {
100
- this.hooks.forEach(h => h());
101
- }
102
- }
103
- get(key) {
104
- if (!(key in this.initial)) {
105
- throw new Error(`Key ${String(key)} not in Bucket initial data`);
106
- }
107
- return this.data[key];
108
- }
109
- sets(state) {
110
- for (let k in state) {
111
- this.set(k, state[k], true);
112
- }
113
- this.hooks.forEach(h => h());
114
- }
115
- validate() {
116
- try {
117
- for (let k in this.initial) {
118
- this.initial[k].parse(this.get(k));
119
- }
120
- }
121
- catch (error) {
122
- return false;
123
- }
124
- return true;
125
- }
126
- get state() {
127
- const state = {};
128
- for (let k in this.initial) {
129
- state[k] = this.get(k);
130
- }
131
- return state;
132
- }
133
- get errors() {
134
- const errors = new Map();
135
- for (let k in this.initial) {
136
- try {
137
- this.initial[k].parse(this.get(k));
138
- }
139
- catch (error) {
140
- errors.set(k, error.message);
141
- }
142
- }
143
- return errors;
144
- }
145
- }exports.default=Bucket;//# sourceMappingURL=Bucket.js.map
package/Bucket.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"Bucket.js","sources":["../src/Bucket.ts"],"sourcesContent":["import { Infer, XVInstanceType } from \"xanv\"\nimport { getCookie, setCookie } from \"./Cookie\"\nimport youid from \"youid\"\nexport type StoreType = \"memory\" | \"session\" | \"local\" | \"url\" | \"cookie\"\n\nexport type InitialBucketData = {\n [key: string]: XVInstanceType\n}\n\nexport type BucketOptions = {\n store?: StoreType;\n data_key?: string;\n onChange?: (key: string, value: any) => void\n}\n\n\nclass Bucket<IT extends InitialBucketData> {\n private initial: IT\n private option: BucketOptions\n private hooks: Map<string, Function> = new Map()\n private data: Record<any, any> = {}\n readonly changes: Map<keyof IT, boolean> = new Map()\n private data_key: string\n\n constructor(initial: IT, option?: BucketOptions) {\n this.initial = initial\n this.option = { store: \"memory\", ...option }\n this.data_key = option?.data_key || ''\n if (!this.data_key) {\n let data_key = ''\n for (let key in initial) {\n const field = initial[key]\n data_key += key + ':' + JSON.stringify(field.meta) + ';'\n }\n this.data_key = youid(data_key)\n }\n\n\n if (typeof window !== 'undefined') {\n if (this.option.store === 'session' || this.option.store === 'local') {\n let storage = this.option.store === \"session\" ? sessionStorage : localStorage\n const value = storage.getItem(this.data_key)\n let data: any = {}\n if (value) {\n data = JSON.parse(value)\n }\n for (let key in initial) {\n try {\n this.data[key] = initial[key].parse(data[key])\n } catch (error) {\n this.data[key] = data[key]\n }\n }\n } else if (this.option.store === 'url') {\n let url = new URL(window.location.href)\n const value = url.searchParams.get(this.data_key)\n let data: any = {}\n if (value) {\n data = JSON.parse(decodeURIComponent(value))\n }\n for (let key in initial) {\n try {\n this.data[key] = initial[key].parse(data[key])\n } catch (error) {\n this.data[key] = data[key]\n }\n }\n } else if (this.option.store === 'cookie') {\n const cookieData = getCookie(this.data_key)\n let data: any = {}\n if (cookieData) {\n data = JSON.parse(cookieData)\n }\n for (let key in initial) {\n try {\n this.data[key] = initial[key].parse(data[key])\n } catch (error) {\n this.data[key] = data[key]\n }\n }\n }\n }\n }\n\n subscribe(id: string, hook: Function) {\n if (!id.startsWith(\"rsb_\")) throw new Error(\"Invalid subscription\")\n this.hooks.set(id, hook)\n }\n\n unsubscribe(id: string) {\n this.hooks.delete(id)\n }\n\n set<T extends keyof IT>(key: T, value: Infer<IT[T]>, dispatch = true) {\n if (!(key in this.initial)) {\n throw new Error(`Key ${String(key)} not in Bucket initial data`)\n }\n this.data[key] = value\n this.changes.set(key as string, true)\n if (this.option.onChange) {\n this.option.onChange(key as string, value)\n }\n\n if (typeof window !== 'undefined') {\n value = JSON.stringify(value) as any\n if (this.option.store === 'session' || this.option.store === 'local') {\n let storage = this.option.store === \"session\" ? sessionStorage : localStorage\n storage.setItem(this.data_key, JSON.stringify(this.data))\n } else if (this.option.store === 'url') {\n let url = new URL(window.location.href)\n url.searchParams.set(this.data_key, encodeURIComponent(JSON.stringify(this.data)))\n window.history.replaceState({}, '', url.toString())\n } else if (this.option.store === 'cookie') {\n setCookie(this.data_key, JSON.stringify(this.data))\n }\n }\n\n if (dispatch) {\n this.hooks.forEach(h => h())\n }\n }\n\n get<T extends keyof IT>(key: T) {\n if (!(key in this.initial)) {\n throw new Error(`Key ${String(key)} not in Bucket initial data`)\n }\n return this.data[key]\n }\n\n sets(state: { [key in keyof IT]?: Infer<IT[key]> }) {\n for (let k in state) {\n this.set(k as keyof IT, state[k as keyof IT]!, true)\n }\n this.hooks.forEach(h => h())\n }\n\n validate() {\n try {\n for (let k in this.initial) {\n this.initial[k].parse(this.get(k as keyof IT))\n }\n } catch (error) {\n return false\n }\n return true\n }\n\n get state() {\n const state: { [key in keyof IT]: Infer<IT[key]> } = {} as any\n for (let k in this.initial) {\n state[k] = this.get(k as keyof IT)\n }\n return state\n }\n\n get errors() {\n const errors = new Map<keyof IT, string>()\n for (let k in this.initial) {\n try {\n this.initial[k].parse(this.get(k as keyof IT))\n } catch (error: any) {\n errors.set(k, error.message)\n }\n }\n return errors\n }\n\n}\n\nexport default Bucket"],"names":["getCookie","setCookie"],"mappings":"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"}
package/Bucket.mjs DELETED
@@ -1,145 +0,0 @@
1
- import {getCookie,setCookie}from'./Cookie.mjs';import youid from'youid';class Bucket {
2
- constructor(initial, option) {
3
- this.hooks = new Map();
4
- this.data = {};
5
- this.changes = new Map();
6
- this.initial = initial;
7
- this.option = Object.assign({ store: "memory" }, option);
8
- this.data_key = (option === null || option === void 0 ? void 0 : option.data_key) || '';
9
- if (!this.data_key) {
10
- let data_key = '';
11
- for (let key in initial) {
12
- const field = initial[key];
13
- data_key += key + ':' + JSON.stringify(field.meta) + ';';
14
- }
15
- this.data_key = youid(data_key);
16
- }
17
- if (typeof window !== 'undefined') {
18
- if (this.option.store === 'session' || this.option.store === 'local') {
19
- let storage = this.option.store === "session" ? sessionStorage : localStorage;
20
- const value = storage.getItem(this.data_key);
21
- let data = {};
22
- if (value) {
23
- data = JSON.parse(value);
24
- }
25
- for (let key in initial) {
26
- try {
27
- this.data[key] = initial[key].parse(data[key]);
28
- }
29
- catch (error) {
30
- this.data[key] = data[key];
31
- }
32
- }
33
- }
34
- else if (this.option.store === 'url') {
35
- let url = new URL(window.location.href);
36
- const value = url.searchParams.get(this.data_key);
37
- let data = {};
38
- if (value) {
39
- data = JSON.parse(decodeURIComponent(value));
40
- }
41
- for (let key in initial) {
42
- try {
43
- this.data[key] = initial[key].parse(data[key]);
44
- }
45
- catch (error) {
46
- this.data[key] = data[key];
47
- }
48
- }
49
- }
50
- else if (this.option.store === 'cookie') {
51
- const cookieData = getCookie(this.data_key);
52
- let data = {};
53
- if (cookieData) {
54
- data = JSON.parse(cookieData);
55
- }
56
- for (let key in initial) {
57
- try {
58
- this.data[key] = initial[key].parse(data[key]);
59
- }
60
- catch (error) {
61
- this.data[key] = data[key];
62
- }
63
- }
64
- }
65
- }
66
- }
67
- subscribe(id, hook) {
68
- if (!id.startsWith("rsb_"))
69
- throw new Error("Invalid subscription");
70
- this.hooks.set(id, hook);
71
- }
72
- unsubscribe(id) {
73
- this.hooks.delete(id);
74
- }
75
- set(key, value, dispatch = true) {
76
- if (!(key in this.initial)) {
77
- throw new Error(`Key ${String(key)} not in Bucket initial data`);
78
- }
79
- this.data[key] = value;
80
- this.changes.set(key, true);
81
- if (this.option.onChange) {
82
- this.option.onChange(key, value);
83
- }
84
- if (typeof window !== 'undefined') {
85
- value = JSON.stringify(value);
86
- if (this.option.store === 'session' || this.option.store === 'local') {
87
- let storage = this.option.store === "session" ? sessionStorage : localStorage;
88
- storage.setItem(this.data_key, JSON.stringify(this.data));
89
- }
90
- else if (this.option.store === 'url') {
91
- let url = new URL(window.location.href);
92
- url.searchParams.set(this.data_key, encodeURIComponent(JSON.stringify(this.data)));
93
- window.history.replaceState({}, '', url.toString());
94
- }
95
- else if (this.option.store === 'cookie') {
96
- setCookie(this.data_key, JSON.stringify(this.data));
97
- }
98
- }
99
- if (dispatch) {
100
- this.hooks.forEach(h => h());
101
- }
102
- }
103
- get(key) {
104
- if (!(key in this.initial)) {
105
- throw new Error(`Key ${String(key)} not in Bucket initial data`);
106
- }
107
- return this.data[key];
108
- }
109
- sets(state) {
110
- for (let k in state) {
111
- this.set(k, state[k], true);
112
- }
113
- this.hooks.forEach(h => h());
114
- }
115
- validate() {
116
- try {
117
- for (let k in this.initial) {
118
- this.initial[k].parse(this.get(k));
119
- }
120
- }
121
- catch (error) {
122
- return false;
123
- }
124
- return true;
125
- }
126
- get state() {
127
- const state = {};
128
- for (let k in this.initial) {
129
- state[k] = this.get(k);
130
- }
131
- return state;
132
- }
133
- get errors() {
134
- const errors = new Map();
135
- for (let k in this.initial) {
136
- try {
137
- this.initial[k].parse(this.get(k));
138
- }
139
- catch (error) {
140
- errors.set(k, error.message);
141
- }
142
- }
143
- return errors;
144
- }
145
- }export{Bucket as default};//# sourceMappingURL=Bucket.mjs.map
package/Bucket.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"Bucket.mjs","sources":["../src/Bucket.ts"],"sourcesContent":["import { Infer, XVInstanceType } from \"xanv\"\nimport { getCookie, setCookie } from \"./Cookie\"\nimport youid from \"youid\"\nexport type StoreType = \"memory\" | \"session\" | \"local\" | \"url\" | \"cookie\"\n\nexport type InitialBucketData = {\n [key: string]: XVInstanceType\n}\n\nexport type BucketOptions = {\n store?: StoreType;\n data_key?: string;\n onChange?: (key: string, value: any) => void\n}\n\n\nclass Bucket<IT extends InitialBucketData> {\n private initial: IT\n private option: BucketOptions\n private hooks: Map<string, Function> = new Map()\n private data: Record<any, any> = {}\n readonly changes: Map<keyof IT, boolean> = new Map()\n private data_key: string\n\n constructor(initial: IT, option?: BucketOptions) {\n this.initial = initial\n this.option = { store: \"memory\", ...option }\n this.data_key = option?.data_key || ''\n if (!this.data_key) {\n let data_key = ''\n for (let key in initial) {\n const field = initial[key]\n data_key += key + ':' + JSON.stringify(field.meta) + ';'\n }\n this.data_key = youid(data_key)\n }\n\n\n if (typeof window !== 'undefined') {\n if (this.option.store === 'session' || this.option.store === 'local') {\n let storage = this.option.store === \"session\" ? sessionStorage : localStorage\n const value = storage.getItem(this.data_key)\n let data: any = {}\n if (value) {\n data = JSON.parse(value)\n }\n for (let key in initial) {\n try {\n this.data[key] = initial[key].parse(data[key])\n } catch (error) {\n this.data[key] = data[key]\n }\n }\n } else if (this.option.store === 'url') {\n let url = new URL(window.location.href)\n const value = url.searchParams.get(this.data_key)\n let data: any = {}\n if (value) {\n data = JSON.parse(decodeURIComponent(value))\n }\n for (let key in initial) {\n try {\n this.data[key] = initial[key].parse(data[key])\n } catch (error) {\n this.data[key] = data[key]\n }\n }\n } else if (this.option.store === 'cookie') {\n const cookieData = getCookie(this.data_key)\n let data: any = {}\n if (cookieData) {\n data = JSON.parse(cookieData)\n }\n for (let key in initial) {\n try {\n this.data[key] = initial[key].parse(data[key])\n } catch (error) {\n this.data[key] = data[key]\n }\n }\n }\n }\n }\n\n subscribe(id: string, hook: Function) {\n if (!id.startsWith(\"rsb_\")) throw new Error(\"Invalid subscription\")\n this.hooks.set(id, hook)\n }\n\n unsubscribe(id: string) {\n this.hooks.delete(id)\n }\n\n set<T extends keyof IT>(key: T, value: Infer<IT[T]>, dispatch = true) {\n if (!(key in this.initial)) {\n throw new Error(`Key ${String(key)} not in Bucket initial data`)\n }\n this.data[key] = value\n this.changes.set(key as string, true)\n if (this.option.onChange) {\n this.option.onChange(key as string, value)\n }\n\n if (typeof window !== 'undefined') {\n value = JSON.stringify(value) as any\n if (this.option.store === 'session' || this.option.store === 'local') {\n let storage = this.option.store === \"session\" ? sessionStorage : localStorage\n storage.setItem(this.data_key, JSON.stringify(this.data))\n } else if (this.option.store === 'url') {\n let url = new URL(window.location.href)\n url.searchParams.set(this.data_key, encodeURIComponent(JSON.stringify(this.data)))\n window.history.replaceState({}, '', url.toString())\n } else if (this.option.store === 'cookie') {\n setCookie(this.data_key, JSON.stringify(this.data))\n }\n }\n\n if (dispatch) {\n this.hooks.forEach(h => h())\n }\n }\n\n get<T extends keyof IT>(key: T) {\n if (!(key in this.initial)) {\n throw new Error(`Key ${String(key)} not in Bucket initial data`)\n }\n return this.data[key]\n }\n\n sets(state: { [key in keyof IT]?: Infer<IT[key]> }) {\n for (let k in state) {\n this.set(k as keyof IT, state[k as keyof IT]!, true)\n }\n this.hooks.forEach(h => h())\n }\n\n validate() {\n try {\n for (let k in this.initial) {\n this.initial[k].parse(this.get(k as keyof IT))\n }\n } catch (error) {\n return false\n }\n return true\n }\n\n get state() {\n const state: { [key in keyof IT]: Infer<IT[key]> } = {} as any\n for (let k in this.initial) {\n state[k] = this.get(k as keyof IT)\n }\n return state\n }\n\n get errors() {\n const errors = new Map<keyof IT, string>()\n for (let k in this.initial) {\n try {\n this.initial[k].parse(this.get(k as keyof IT))\n } catch (error: any) {\n errors.set(k, error.message)\n }\n }\n return errors\n }\n\n}\n\nexport default Bucket"],"names":[],"mappings":"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"}