solid-new-bucket 0.0.4-g → 0.0.4-h

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 CHANGED
@@ -1,9 +1,12 @@
1
1
  # solid-new-bucket
2
- SolidJS Signal Utils
3
2
 
4
- ## Usage
3
+ [中文文档](#中文文档)
5
4
 
6
- ### Bucket
5
+ SolidJS Signal Utils Lib.
6
+
7
+ ### Usage
8
+
9
+ #### Bucket
7
10
 
8
11
  Create a bucket to track data:
9
12
  ```
@@ -70,22 +73,156 @@ console.log(value())
70
73
  // expected to be: 'new data'
71
74
  ```
72
75
 
73
- ### StampedBucket
76
+ #### StampedBucket
74
77
 
75
78
  StampedBucket helps to track changes on Object, Array and other complex types.
76
79
 
77
- Create a StampedBucket:
80
+ Create, update and access:
81
+ ```
82
+ const v = stampedBucket(new Set())
83
+ v(content => {
84
+ content.add(1)
85
+ })
86
+ console.log(v())
87
+ // expected to be: Set(1) { 1 }
88
+ ```
89
+
90
+ Replace content:
91
+ ```
92
+ const v = stampedBucket([1,2,3])
93
+ console.log(v())
94
+ // expected to be: [1, 2, 3]
95
+
96
+ const newSet = new Set()
97
+ newSet.add(-1)
98
+
99
+ v.reset(newSet)
100
+ console.log(v())
101
+ // expected to be: Set(1) { -1 }
78
102
  ```
79
- const set = stampedBucket(new Set())
103
+
104
+ If state is updated outside stampedBucket, we can mark state is changed to let solidjs trigger calculation on update:
80
105
  ```
106
+ const arr = [1,2]
107
+ const v = stampedBucket(arr)
81
108
 
82
- Update and access:
109
+ // update the array directly
110
+ arr.push(3)
111
+ v.markChanged()
83
112
  ```
84
- set(content => {
113
+
114
+ StampedBucket supports update listener and localStorage sync as well as Bucket.
115
+
116
+ ---
117
+
118
+ ## 中文文档
119
+
120
+ SolidJS状态管理API。
121
+
122
+ ### 用法
123
+
124
+ #### Bucket
125
+
126
+ 创建一个 bucket 来管理数据:
127
+ ```
128
+ import { bucket } from 'solid-new-bucket'
129
+
130
+ const value = bucket('test data')
131
+ ```
132
+
133
+ 访问 bucket:
134
+ ```
135
+ function myComponent() {
136
+ const value = bucket('test data')
137
+
138
+ return (
139
+ <div>
140
+ This is {value()}
141
+ </div>
142
+ )
143
+ }
144
+ ```
145
+
146
+ 更新 bucket 内容:
147
+ ```
148
+ const value = bucket('test data')
149
+ // 直接穿参更新
150
+ value('new data')
151
+ console.log(value())
152
+ // 期望输出: 'new data'
153
+
154
+ // 传入更新函数
155
+ value(prevValue => 'updated: ' + prevValue)
156
+ console.log(value())
157
+ // 期望输出: 'updated: test data'
158
+ ```
159
+
160
+ 配置 bucket 自动保存数据到浏览器本地存储:
161
+ ```
162
+ const value = bucket(new Date(), {
163
+ localStorageName: 'user.loginAt'
164
+ })
165
+ ```
166
+
167
+ 配置更新监听回调:
168
+ ```
169
+ const value = bucket(1, {
170
+ beforeUpdate(newValue) {
171
+ console.log('即将更新为:', newValue)
172
+ },
173
+ afterUpdate(newValue) {
174
+ console.log('当前值:', newValue)
175
+ }
176
+ })
177
+ ```
178
+
179
+ 将 accessor 和 Bucket 串联:
180
+ ```
181
+ const [upstream, updateUpstream] = createSignal('test data')
182
+ const value = bucket(upstream, {
183
+ useValueAsAccessor: true
184
+ })
185
+ updateUpstream('new data')
186
+ console.log(value())
187
+ // 期望输出: 'new data'
188
+ ```
189
+
190
+ ### StampedBucket
191
+
192
+ StampedBucket 用来管理对象、数组或者其他复杂类型的状态。
193
+
194
+ 创建、更新和访问:
195
+ ```
196
+ const v = stampedBucket(new Set())
197
+ v(content => {
85
198
  content.add(1)
86
199
  })
87
- console.log(set())
88
- // expected to be: Set(1) { 1 }
200
+ console.log(v())
201
+ // 期望输出: Set(1) { 1 }
202
+ ```
203
+
204
+ 替换对象:
205
+ ```
206
+ const v = stampedBucket([1,2,3])
207
+ console.log(v())
208
+ // 期望输出: [1, 2, 3]
209
+
210
+ const newSet = new Set()
211
+ newSet.add(-1)
212
+
213
+ v.reset(newSet)
214
+ console.log(v())
215
+ // 期望输出: Set(1) { -1 }
216
+ ```
217
+
218
+ 如果没有通过 stampedBucket 去更新状态,可以标记状态已更新让 solidjs 重新渲染:
219
+ ```
220
+ const arr = [1,2]
221
+ const v = stampedBucket(arr)
222
+
223
+ // 直接更新数组
224
+ arr.push(3)
225
+ v.markChanged()
89
226
  ```
90
227
 
91
- StampedBucket supports update listener and localStorage sync as well as Bucket.
228
+ StampedBucket 也支持更新监听回调和本地存储同步。
package/dist/index.d.mts CHANGED
@@ -133,13 +133,32 @@ interface Mapper<A, B> {
133
133
  from?(b: B): A;
134
134
  }
135
135
  type Bucket<T> = {
136
+ /**
137
+ * Update.
138
+ * @param v: value
139
+ */
136
140
  <U extends T>(v?: T): U;
141
+ /**
142
+ * Update with updater.
143
+ * @param v: updater
144
+ */
137
145
  <U extends T>(v: (prev: T) => U): U;
138
146
  };
139
147
  type StampedBucket<T> = ((updater?: Consumer<T>) => T) & StampedBucketAction<T>;
140
148
  interface StampedBucketAction<T> {
149
+ /**
150
+ * Provide mapper to map content to needed type.
151
+ * @param call mapper
152
+ */
141
153
  map<O>(call: (v: T) => O): O;
154
+ /**
155
+ * Mark content is changed.
156
+ */
142
157
  markChanged(): void;
158
+ /**
159
+ * Set content to.
160
+ * @param v
161
+ */
143
162
  reset(v: T): void;
144
163
  }
145
164
  interface StampedData<T> {
package/dist/index.d.ts CHANGED
@@ -133,13 +133,32 @@ interface Mapper<A, B> {
133
133
  from?(b: B): A;
134
134
  }
135
135
  type Bucket<T> = {
136
+ /**
137
+ * Update.
138
+ * @param v: value
139
+ */
136
140
  <U extends T>(v?: T): U;
141
+ /**
142
+ * Update with updater.
143
+ * @param v: updater
144
+ */
137
145
  <U extends T>(v: (prev: T) => U): U;
138
146
  };
139
147
  type StampedBucket<T> = ((updater?: Consumer<T>) => T) & StampedBucketAction<T>;
140
148
  interface StampedBucketAction<T> {
149
+ /**
150
+ * Provide mapper to map content to needed type.
151
+ * @param call mapper
152
+ */
141
153
  map<O>(call: (v: T) => O): O;
154
+ /**
155
+ * Mark content is changed.
156
+ */
142
157
  markChanged(): void;
158
+ /**
159
+ * Set content to.
160
+ * @param v
161
+ */
143
162
  reset(v: T): void;
144
163
  }
145
164
  interface StampedData<T> {
package/dist/index.js CHANGED
@@ -79,16 +79,20 @@ function stampedBucket(value, options) {
79
79
  if (options?.localStorageName) {
80
80
  const raw = localStorage.getItem(options.localStorageName);
81
81
  if (raw) {
82
- value = JSON.parse(raw);
82
+ if (raw === "undefined") {
83
+ value = void 0;
84
+ } else {
85
+ value = JSON.parse(raw);
86
+ }
83
87
  }
84
88
  }
85
- const [timestamp, setTimestamp] = (0, import_solid_js.createSignal)((/* @__PURE__ */ new Date()).getTime());
89
+ const [timestamp, setTimestamp] = (0, import_solid_js.createSignal)(performance.now());
86
90
  const v = (0, import_solid_js.createMemo)(() => {
87
91
  return {
88
92
  timestamp: timestamp(),
89
93
  data: value,
90
94
  markChanged() {
91
- setTimestamp((/* @__PURE__ */ new Date()).getTime());
95
+ setTimestamp(performance.now());
92
96
  }
93
97
  };
94
98
  });
@@ -101,7 +105,7 @@ function stampedBucket(value, options) {
101
105
  options?.beforeUpdate?.(value);
102
106
  updater(value);
103
107
  if (options?.localStorageName) {
104
- localStorage.setItem(options.localStorageName, value ? JSON.stringify(value) : "");
108
+ localStorage.setItem(options.localStorageName, JSON.stringify(value));
105
109
  }
106
110
  setTimestamp((/* @__PURE__ */ new Date()).getTime());
107
111
  options?.afterUpdate?.(value);
@@ -181,12 +185,16 @@ function bucket(value, options) {
181
185
  const [local, others] = options && (0, import_solid_js.splitProps)(options, ["beforeUpdate", "afterUpdate", "localStorageName"]) || [];
182
186
  if (local?.localStorageName) {
183
187
  const raw = localStorage.getItem(local.localStorageName);
184
- if (raw) {
185
- value = JSON.parse(raw);
188
+ if (raw !== null) {
189
+ if (raw === "undefined") {
190
+ value = void 0;
191
+ } else {
192
+ value = JSON.parse(raw);
193
+ }
186
194
  }
187
195
  }
188
196
  const [v, setV] = (0, import_solid_js.createSignal)(value, others);
189
- return (t) => {
197
+ const b = function(t) {
190
198
  if (t !== void 0) {
191
199
  const newValue = setV((prev) => {
192
200
  local?.beforeUpdate?.(prev);
@@ -197,13 +205,19 @@ function bucket(value, options) {
197
205
  }
198
206
  });
199
207
  if (local?.localStorageName) {
200
- localStorage.setItem(local.localStorageName, t ? JSON.stringify(t) : "");
208
+ localStorage.setItem(local.localStorageName, JSON.stringify(newValue));
201
209
  }
202
210
  local?.afterUpdate?.(newValue);
203
211
  return newValue;
204
212
  }
205
213
  return v();
206
214
  };
215
+ Object.defineProperty(b, "value", {
216
+ get: function() {
217
+ return (0, import_solid_js.untrack)(v);
218
+ }
219
+ });
220
+ return b;
207
221
  }
208
222
 
209
223
  // src/checks.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/arrayHelpers.ts","../src/buckets.ts","../src/checks.ts","../src/wrappers.ts","../src/converters.ts","../src/generators.ts","../src/others.ts","../src/conditionals.ts"],"sourcesContent":["\nexport * from \"./arrayHelpers\"\nexport * from \"./buckets\"\nexport * from \"./checks\"\nexport * from \"./converters\"\nexport * from \"./generators\"\nexport * from \"./others\"\nexport * from \"./wrappers\"\nexport * from \"./conditionals\"\n \nexport type Pair<K, V> = [key: K, value: V]\n\nexport type Consumer<T> = (v: T) => void\n\nexport type BiConsumer<A, B> = (a: A, b: B) => void\n\nexport type TriConsumer<A, B, C> = (a: A, b: B, c: C) => void\n\nexport type Func<T, R> = (v: T) => R\n\nexport type BiFunc<A, B, R> = (a: A, b: B) => R\n\nexport type Callback = (...args: any) => any\n\nexport type Supplier<T> = () => T\n \nexport type Comparator<T> = (a: T, b: T) => -1 | 0 | 1\n\nexport type ObjectIndex = string | number\n\nexport interface Mapper<A, B> {\n to?(a: A): B;\n from?(b: B): A;\n}\n\nexport type Bucket<T> = {\n // (v?: T): T;\n // (v: (prev: T) => T): T;\n <U extends T>(v?: T): U;\n <U extends T>(v: (prev: T) => U): U;\n}\n\nexport type StampedBucket<T> = ((updater?: Consumer<T>) => T) & StampedBucketAction<T>;\n\ninterface StampedBucketAction<T> {\n map<O>(call: (v: T) => O): O\n markChanged(): void\n reset(v: T): void\n}\n\nexport interface StampedData<T> {\n data: T\n timestamp: number\n}","import { Func } from \".\";\n\n/**\n * Filter out and remove elements from array.\n * @param arr array\n * @param filter filter\n * @returns new array\n */\nexport function removeElementsFromArray<T>(arr: T[], filter: (t: T) => boolean): T[] {\n const idx: number[] = [];\n arr.forEach((t, i) => {\n if (filter(t)) {\n idx.push(i);\n }\n });\n return idx.map(i => arr.splice(i, 1)[0]);\n}\n\n/**\n * Copy range or array.\n * @param arr array\n * @param start start pos\n * @param end end pos\n * @returns sub range of array\n */\nexport function copyOfRange<T>(arr: T[], start: number, end: number): T[] {\n const r: T[] = [];\n start = Math.max(0, start);\n end = Math.min(arr.length, end);\n for (let i = start; i < end; i++) {\n r.push(arr[i]);\n }\n return r;\n}\n\n/**\n * Find first element in array which passes test.\n * @param arr array\n * @param test test\n * @returns index\n */\nexport function indexOf<T>(arr: T[], test: Func<T, boolean>) {\n for (let i = 0; i < arr.length; i++) {\n if (test(arr[i])) {\n return i;\n }\n }\n return -1;\n}\n","import { createSignal, Accessor, createMemo, SignalOptions, splitProps } from \"solid-js\"\nimport { Bucket, Mapper, ObjectIndex, StampedBucket, StampedData } from \".\";\n\n\n/**\n * Stamped Bucket help to trigger rerendering after updating object without recreate new object.\n * @returns StampedBucket<T>\n */\nexport function stampedBucket<T>(value: T, options?: {\n beforeUpdate?: (value: T) => void;\n afterUpdate?: (value: T) => void;\n localStorageName?: string;\n}): StampedBucket<T> {\n // load from local storage\n if (options?.localStorageName) {\n const raw = localStorage.getItem(options.localStorageName);\n if (raw) {\n value = JSON.parse(raw);\n }\n }\n\n const [timestamp, setTimestamp] = createSignal(new Date().getTime());\n const v: Accessor<StampedData<T>> = createMemo(() => {\n return {\n timestamp: timestamp(),\n data: value,\n markChanged() {\n setTimestamp(new Date().getTime());\n }\n };\n });\n const setV = (newValue: T) => {\n value = newValue;\n setTimestamp(new Date().getTime());\n };\n\n const call = function(updater?: (v: T) => void) {\n if (updater) {\n options?.beforeUpdate?.(value)\n\n updater(value)\n\n // save to local storage\n if (options?.localStorageName) {\n localStorage.setItem(options.localStorageName, value ? JSON.stringify(value) : \"\")\n }\n\n // mark changed\n setTimestamp(new Date().getTime());\n \n options?.afterUpdate?.(value)\n }\n\n return v().data\n }\n\n call.map = <O>(mapper: (v: T) => O) => {\n return mapper(v().data);\n };\n\n call.markChanged = () => {\n setTimestamp(new Date().getTime())\n };\n\n call.reset = (v: T) => {\n setV(v)\n };\n\n return call\n}\n\nfunction getFieldOfObject(o: any, paths: ObjectIndex[]) {\n for (let i = 0; i < paths.length - 1; i++) {\n o = o[paths[i]];\n if (!o) {\n throw new Error(`cannot find ${paths.join('.')} in ${o}`)\n }\n }\n return o[paths[paths.length - 1]]\n}\n\nfunction setFieldOfObject(o: any, newValue: any, paths: ObjectIndex[]) {\n for (let i = 0; i < paths.length - 1; i++) {\n o = o[paths[i]];\n if (!o) {\n throw new Error(`cannot find ${paths.join('.')} in ${o}`)\n }\n }\n o[paths[paths.length - 1]] = newValue\n}\n\nexport function asBucket<O, FieldType, DecadeType>(s: StampedBucket<O>, path: ObjectIndex[], mapper?: Mapper<FieldType, DecadeType>): Bucket<FieldType> {\n const getField = (data: O) => {\n let v = getFieldOfObject(data, path)\n return mapper ? mapper.from?.(v) : v\n }\n const setField = (data: O, v: any) => {\n if (mapper) {\n v = mapper.to?.(v)\n }\n setFieldOfObject(data, v, path)\n }\n return (t) => {\n if (t != undefined) {\n s(data => {\n if (typeof(t) === \"function\") {\n const oldValue = getField(data)\n // @ts-ignore\n setField(data, t(oldValue))\n } else {\n setField(data, t)\n }\n })\n\n }\n return getField(s())\n }\n}\n\nexport function asAccessor<T, K extends (keyof T)>(v: T | Accessor<T>, k: K): Accessor<T[K]> {\n return () => {\n if (typeof(v) === \"function\") {\n return (v as Function)()[k]\n }\n return v[k]\n }\n}\n\n/**\n * Create a bucket to track data.\n * @param value value or Accessor of value\n * @param options options\n * @returns Bucket<T>\n */\nexport function bucket<T>(value: T | Accessor<T>, options?: {\n useValueAsAccessor?: boolean\n beforeUpdate?: (newValue: T) => void\n afterUpdate?: (newValue: T) => void\n localStorageName?: string;\n} & SignalOptions<T>): Bucket<T> {\n if (options?.useValueAsAccessor && typeof(value) === \"function\") {\n const [_, others] = splitProps(options, [\"useValueAsAccessor\"])\n const memo = createMemo(() => bucket<T>((value as any)(), others))\n return (t) => {\n // @ts-ignore\n return memo()(t)\n }\n }\n \n const [local, others] = options && splitProps(options, [\"beforeUpdate\", \"afterUpdate\", \"localStorageName\"]) || [];\n\n // load from local storage\n if (local?.localStorageName) {\n const raw = localStorage.getItem(local.localStorageName);\n if (raw) {\n value = JSON.parse(raw);\n }\n }\n\n // @ts-ignore\n const [v, setV] = createSignal<T>(value, others)\n\n return (t) => {\n if (t !== undefined) {\n const newValue = setV((prev) => {\n local?.beforeUpdate?.(prev);\n if (typeof(t) === \"function\") {\n return (t as Function)(prev);\n } else {\n return t;\n }\n });\n // save to local storage\n if (local?.localStorageName) {\n localStorage.setItem(local.localStorageName, t ? JSON.stringify(t) : \"\");\n }\n local?.afterUpdate?.(newValue);\n return newValue;\n }\n return v()\n };\n}\n","\n/**\n * Check if array or string is not empty.\n * @param v array of any, string or undefined\n * @returns true if target is not empty\n */\nexport function isNotEmpty<T>(v?: T[]): boolean\nexport function isNotEmpty(v?: string): boolean\nexport function isNotEmpty(v: any) {\n if (!v) return false\n if (typeof(v) === \"string\") {\n return v.length > 0\n }\n if (typeof(v) === \"object\") {\n if (Array.isArray(v)) {\n return v.length > 0\n }\n return Object.keys(v).length > 0\n }\n return false\n}\n\n/**\n * Check if value is number.\n * @param v any\n * @returns true if value is number\n */\nexport function isNumber(v: any) {\n return typeof(v) === \"number\";\n}\n\n/**\n * Compare two date string.\n * @param a date 1\n * @param b date 2\n * @returns true if a is later than b\n */\nexport function compareDateString(a: string, b: string): number {\n return Date.parse(a) - Date.parse(b);\n}\n\n/**\n * Check whether there is an element in b exists in a as well.\n * @param a array 1\n * @param b array 2\n * @returns boolean\n */\nexport function containsAny(a: any[], b: any[]) {\n for (let i of a) {\n for (let j of b) {\n if (i === j) {\n return true;\n }\n }\n }\n return false;\n}\n","\n\nexport function wrapDateNumber(v: number, bits: number = 2) {\n if (v == 0) {\n return '0'.repeat(bits);\n }\n \n let n = v;\n while (n > 0) {\n n = Math.floor(n / 10);\n bits--;\n }\n return bits > 0 ? '0'.repeat(bits) + v : v;\n}\n\nexport function wrapString(v: any): string {\n if (typeof(v) === \"string\") {\n return v;\n }\n return v?.toString() || \"\";\n}\n\nexport function wrapNumber(v: any) {\n if (typeof(v) === \"number\") {\n return v;\n }\n return 0;\n}\n","import { wrapDateNumber } from \"./wrappers\";\n\n/**\n * Parse and format timestamp from number to string.\n * @param timestamp time\n * @param showTime show only date if false\n * @param showMilliseconds show ms if true\n * @returns formatted string\n */\nexport function parseTimestamp(timestamp: number, showTime?: boolean, showMilliseconds?: boolean) {\n const date = new Date(timestamp);\n // TODO: toLocaleString\n // return date.toLocaleString(undefined, {\n // });\n let r = `${wrapDateNumber(date.getFullYear())}-${wrapDateNumber(date.getMonth() + 1)}-${wrapDateNumber(date.getDate())}`;\n if (showTime) {\n r += ` ${wrapDateNumber(date.getHours())}:${wrapDateNumber(date.getMinutes())}:${wrapDateNumber(date.getSeconds())}`;\n }\n if (showMilliseconds) {\n r += `.${wrapDateNumber(date.getMilliseconds(), 3)}`;\n };\n return r;\n}\n\nexport function toCapital(v: string) {\n return v.charAt(0).toUpperCase() + v.substring(1);\n}","\n/**\n * Genereate a sequence.\n * @param start start\n * @param end end\n * @param step step\n * @returns array\n */\nexport function sequence(start: number, end: number, step: number = 1) {\n const r = [];\n for (let i = start; i < end; i += step) {\n r.push(i);\n }\n return r;\n}\n\n/**\n * Generate a array of size.\n * @param size size\n * @returns \n */\nexport function iterate(size: number) {\n return Array.from(Array(size).keys())\n}","import { Context, useContext } from \"solid-js\";\n\nexport function useCtx<T>(c: Context<T>): T {\n const context = useContext(c);\n if (!context) {\n throw new Error(\"cannot find a \" + JSON.stringify(c))\n }\n return context;\n}\n\nexport function names(...v: (string | undefined)[]) {\n return v.filter((name) => Boolean(name)).join(' ');\n}\n\nexport function clone(obj: any) {\n const type = typeof(obj);\n switch (type) {\n case 'object': {\n let r: any = Array.isArray(obj) ? [] : {};\n for (let key of Object.keys(obj)) {\n r[key] = clone(obj[key]);\n }\n return r;\n }\n default:\n return obj;\n }\n}\n","import { Supplier } from \".\"\n\n/**\n * Invoke function or return value if condition is true.\n * @param condition any\n * @param value function to be invoked or value to be return\n * @param defaultValue fallback value, optional\n */\nexport function conditional<T>(condition: any, value: () => void): void;\nexport function conditional<T>(condition: any, value: T, defaultValue?: T): T;\nexport function conditional<T>(condition: any, value: Supplier<T>, defaultValue?: T): T;\nexport function conditional(condition: any, value: any, defaultValue?: any) {\n if (typeof(value) === \"function\") {\n if (condition) {\n const r = value()\n if (r) {\n return r\n }\n }\n return defaultValue\n }\n\n if (typeof(value === \"string\")) {\n return condition ? value : (defaultValue || '')\n }\n\n if (typeof(value) === \"number\") {\n return condition ? value : (defaultValue || 0)\n }\n\n if (condition) {\n return value\n } else if (defaultValue !== undefined && defaultValue !== null) {\n return defaultValue\n }\n}\n"],"mappings":"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","names":["v","others","import_solid_js"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/arrayHelpers.ts","../src/buckets.ts","../src/checks.ts","../src/wrappers.ts","../src/converters.ts","../src/generators.ts","../src/others.ts","../src/conditionals.ts"],"sourcesContent":["\nexport * from \"./arrayHelpers\"\nexport * from \"./buckets\"\nexport * from \"./checks\"\nexport * from \"./converters\"\nexport * from \"./generators\"\nexport * from \"./others\"\nexport * from \"./wrappers\"\nexport * from \"./conditionals\"\n \nexport type Pair<K, V> = [key: K, value: V]\n\nexport type Consumer<T> = (v: T) => void\n\nexport type BiConsumer<A, B> = (a: A, b: B) => void\n\nexport type TriConsumer<A, B, C> = (a: A, b: B, c: C) => void\n\nexport type Func<T, R> = (v: T) => R\n\nexport type BiFunc<A, B, R> = (a: A, b: B) => R\n\nexport type Callback = (...args: any) => any\n\nexport type Supplier<T> = () => T\n \nexport type Comparator<T> = (a: T, b: T) => -1 | 0 | 1\n\nexport type ObjectIndex = string | number\n\nexport interface Mapper<A, B> {\n to?(a: A): B;\n from?(b: B): A;\n}\n\nexport type Bucket<T> = {\n // (v?: T): T;\n // (v: (prev: T) => T): T;\n /**\n * Update.\n * @param v: value\n */\n <U extends T>(v?: T): U;\n\n /**\n * Update with updater.\n * @param v: updater\n */\n <U extends T>(v: (prev: T) => U): U;\n}\n\nexport type StampedBucket<T> = ((updater?: Consumer<T>) => T) & StampedBucketAction<T>;\n\ninterface StampedBucketAction<T> {\n /**\n * Provide mapper to map content to needed type.\n * @param call mapper\n */\n map<O>(call: (v: T) => O): O\n\n /**\n * Mark content is changed.\n */\n markChanged(): void\n\n /**\n * Set content to.\n * @param v \n */\n reset(v: T): void\n}\n\nexport interface StampedData<T> {\n data: T\n timestamp: number\n}","import { Func } from \".\";\n\n/**\n * Filter out and remove elements from array.\n * @param arr array\n * @param filter filter\n * @returns new array\n */\nexport function removeElementsFromArray<T>(arr: T[], filter: (t: T) => boolean): T[] {\n const idx: number[] = [];\n arr.forEach((t, i) => {\n if (filter(t)) {\n idx.push(i);\n }\n });\n return idx.map(i => arr.splice(i, 1)[0]);\n}\n\n/**\n * Copy range or array.\n * @param arr array\n * @param start start pos\n * @param end end pos\n * @returns sub range of array\n */\nexport function copyOfRange<T>(arr: T[], start: number, end: number): T[] {\n const r: T[] = [];\n start = Math.max(0, start);\n end = Math.min(arr.length, end);\n for (let i = start; i < end; i++) {\n r.push(arr[i]);\n }\n return r;\n}\n\n/**\n * Find first element in array which passes test.\n * @param arr array\n * @param test test\n * @returns index\n */\nexport function indexOf<T>(arr: T[], test: Func<T, boolean>) {\n for (let i = 0; i < arr.length; i++) {\n if (test(arr[i])) {\n return i;\n }\n }\n return -1;\n}\n","import { createSignal, Accessor, createMemo, SignalOptions, splitProps, untrack } from \"solid-js\"\nimport { Bucket, Mapper, ObjectIndex, StampedBucket, StampedData } from \".\";\n\n\n/**\n * Stamped Bucket help to trigger rerendering after updating object without recreate new object.\n * @returns StampedBucket<T>\n */\nexport function stampedBucket<T>(value: T, options?: {\n beforeUpdate?: (value: T) => void;\n afterUpdate?: (value: T) => void;\n localStorageName?: string;\n}): StampedBucket<T> {\n // load from local storage\n if (options?.localStorageName) {\n const raw = localStorage.getItem(options.localStorageName);\n if (raw) {\n if (raw === 'undefined') {\n value = undefined as any;\n } else {\n value = JSON.parse(raw);\n }\n }\n }\n\n const [timestamp, setTimestamp] = createSignal(performance.now());\n const v: Accessor<StampedData<T>> = createMemo(() => {\n return {\n timestamp: timestamp(),\n data: value,\n markChanged() {\n setTimestamp(performance.now());\n }\n };\n });\n const setV = (newValue: T) => {\n value = newValue;\n setTimestamp(new Date().getTime());\n };\n\n const call = function(updater?: (v: T) => void) {\n if (updater) {\n options?.beforeUpdate?.(value)\n\n updater(value)\n\n // save to local storage\n if (options?.localStorageName) {\n localStorage.setItem(options.localStorageName, JSON.stringify(value));\n }\n\n // mark changed\n setTimestamp(new Date().getTime());\n \n options?.afterUpdate?.(value)\n }\n\n return v().data\n }\n\n call.map = <O>(mapper: (v: T) => O) => {\n return mapper(v().data);\n };\n\n call.markChanged = () => {\n setTimestamp(new Date().getTime())\n };\n\n call.reset = (v: T) => {\n setV(v)\n };\n\n return call\n}\n\nfunction getFieldOfObject(o: any, paths: ObjectIndex[]) {\n for (let i = 0; i < paths.length - 1; i++) {\n o = o[paths[i]];\n if (!o) {\n throw new Error(`cannot find ${paths.join('.')} in ${o}`)\n }\n }\n return o[paths[paths.length - 1]]\n}\n\nfunction setFieldOfObject(o: any, newValue: any, paths: ObjectIndex[]) {\n for (let i = 0; i < paths.length - 1; i++) {\n o = o[paths[i]];\n if (!o) {\n throw new Error(`cannot find ${paths.join('.')} in ${o}`)\n }\n }\n o[paths[paths.length - 1]] = newValue\n}\n\nexport function asBucket<O, FieldType, DecadeType>(s: StampedBucket<O>, path: ObjectIndex[], mapper?: Mapper<FieldType, DecadeType>): Bucket<FieldType> {\n const getField = (data: O) => {\n let v = getFieldOfObject(data, path)\n return mapper ? mapper.from?.(v) : v\n }\n const setField = (data: O, v: any) => {\n if (mapper) {\n v = mapper.to?.(v)\n }\n setFieldOfObject(data, v, path)\n }\n return (t) => {\n if (t != undefined) {\n s(data => {\n if (typeof(t) === \"function\") {\n const oldValue = getField(data)\n // @ts-ignore\n setField(data, t(oldValue))\n } else {\n setField(data, t)\n }\n })\n\n }\n return getField(s())\n }\n}\n\nexport function asAccessor<T, K extends (keyof T)>(v: T | Accessor<T>, k: K): Accessor<T[K]> {\n return () => {\n if (typeof(v) === \"function\") {\n return (v as Function)()[k]\n }\n return v[k]\n }\n}\n\n/**\n * Create a bucket to track data.\n * @param value value or Accessor of value\n * @param options options\n * @returns Bucket<T>\n */\nexport function bucket<T>(value: T | Accessor<T>, options?: {\n useValueAsAccessor?: boolean\n beforeUpdate?: (newValue: T) => void\n afterUpdate?: (newValue: T) => void\n localStorageName?: string;\n} & SignalOptions<T>): Bucket<T> {\n if (options?.useValueAsAccessor && typeof(value) === \"function\") {\n const [_, others] = splitProps(options, [\"useValueAsAccessor\"])\n const memo = createMemo(() => bucket<T>((value as any)(), others))\n return (t) => {\n // @ts-ignore\n return memo()(t)\n }\n }\n \n const [local, others] = options && splitProps(options, [\"beforeUpdate\", \"afterUpdate\", \"localStorageName\"]) || [];\n\n // load from local storage\n if (local?.localStorageName) {\n const raw = localStorage.getItem(local.localStorageName);\n if (raw !== null) {\n if (raw === 'undefined') {\n value = undefined as any;\n } else {\n value = JSON.parse(raw);\n }\n }\n }\n\n // @ts-ignore\n const [v, setV] = createSignal<T>(value, others)\n\n const b = function(t) {\n if (t !== undefined) {\n const newValue = setV((prev) => {\n local?.beforeUpdate?.(prev);\n if (typeof(t) === \"function\") {\n return (t as Function)(prev);\n } else {\n return t;\n }\n });\n // save to local storage\n if (local?.localStorageName) {\n localStorage.setItem(local.localStorageName, JSON.stringify(newValue));\n }\n local?.afterUpdate?.(newValue);\n return newValue;\n }\n return v()\n } as Bucket<T>;\n\n Object.defineProperty(b, 'value', {\n get: function() {\n return untrack(v);\n },\n });\n\n return b;\n}\n","\n/**\n * Check if array or string is not empty.\n * @param v array of any, string or undefined\n * @returns true if target is not empty\n */\nexport function isNotEmpty<T>(v?: T[]): boolean\nexport function isNotEmpty(v?: string): boolean\nexport function isNotEmpty(v: any) {\n if (!v) return false\n if (typeof(v) === \"string\") {\n return v.length > 0\n }\n if (typeof(v) === \"object\") {\n if (Array.isArray(v)) {\n return v.length > 0\n }\n return Object.keys(v).length > 0\n }\n return false\n}\n\n/**\n * Check if value is number.\n * @param v any\n * @returns true if value is number\n */\nexport function isNumber(v: any) {\n return typeof(v) === \"number\";\n}\n\n/**\n * Compare two date string.\n * @param a date 1\n * @param b date 2\n * @returns true if a is later than b\n */\nexport function compareDateString(a: string, b: string): number {\n return Date.parse(a) - Date.parse(b);\n}\n\n/**\n * Check whether there is an element in b exists in a as well.\n * @param a array 1\n * @param b array 2\n * @returns boolean\n */\nexport function containsAny(a: any[], b: any[]) {\n for (let i of a) {\n for (let j of b) {\n if (i === j) {\n return true;\n }\n }\n }\n return false;\n}\n","\n\nexport function wrapDateNumber(v: number, bits: number = 2) {\n if (v == 0) {\n return '0'.repeat(bits);\n }\n \n let n = v;\n while (n > 0) {\n n = Math.floor(n / 10);\n bits--;\n }\n return bits > 0 ? '0'.repeat(bits) + v : v;\n}\n\nexport function wrapString(v: any): string {\n if (typeof(v) === \"string\") {\n return v;\n }\n return v?.toString() || \"\";\n}\n\nexport function wrapNumber(v: any) {\n if (typeof(v) === \"number\") {\n return v;\n }\n return 0;\n}\n","import { wrapDateNumber } from \"./wrappers\";\n\n/**\n * Parse and format timestamp from number to string.\n * @param timestamp time\n * @param showTime show only date if false\n * @param showMilliseconds show ms if true\n * @returns formatted string\n */\nexport function parseTimestamp(timestamp: number, showTime?: boolean, showMilliseconds?: boolean) {\n const date = new Date(timestamp);\n // TODO: toLocaleString\n // return date.toLocaleString(undefined, {\n // });\n let r = `${wrapDateNumber(date.getFullYear())}-${wrapDateNumber(date.getMonth() + 1)}-${wrapDateNumber(date.getDate())}`;\n if (showTime) {\n r += ` ${wrapDateNumber(date.getHours())}:${wrapDateNumber(date.getMinutes())}:${wrapDateNumber(date.getSeconds())}`;\n }\n if (showMilliseconds) {\n r += `.${wrapDateNumber(date.getMilliseconds(), 3)}`;\n };\n return r;\n}\n\nexport function toCapital(v: string) {\n return v.charAt(0).toUpperCase() + v.substring(1);\n}","\n/**\n * Genereate a sequence.\n * @param start start\n * @param end end\n * @param step step\n * @returns array\n */\nexport function sequence(start: number, end: number, step: number = 1) {\n const r = [];\n for (let i = start; i < end; i += step) {\n r.push(i);\n }\n return r;\n}\n\n/**\n * Generate a array of size.\n * @param size size\n * @returns \n */\nexport function iterate(size: number) {\n return Array.from(Array(size).keys())\n}","import { Context, useContext } from \"solid-js\";\n\nexport function useCtx<T>(c: Context<T>): T {\n const context = useContext(c);\n if (!context) {\n throw new Error(\"cannot find a \" + JSON.stringify(c))\n }\n return context;\n}\n\nexport function names(...v: (string | undefined)[]) {\n return v.filter((name) => Boolean(name)).join(' ');\n}\n\nexport function clone(obj: any) {\n const type = typeof(obj);\n switch (type) {\n case 'object': {\n let r: any = Array.isArray(obj) ? [] : {};\n for (let key of Object.keys(obj)) {\n r[key] = clone(obj[key]);\n }\n return r;\n }\n default:\n return obj;\n }\n}\n","import { Supplier } from \".\"\n\n/**\n * Invoke function or return value if condition is true.\n * @param condition any\n * @param value function to be invoked or value to be return\n * @param defaultValue fallback value, optional\n */\nexport function conditional<T>(condition: any, value: () => void): void;\nexport function conditional<T>(condition: any, value: T, defaultValue?: T): T;\nexport function conditional<T>(condition: any, value: Supplier<T>, defaultValue?: T): T;\nexport function conditional(condition: any, value: any, defaultValue?: any) {\n if (typeof(value) === \"function\") {\n if (condition) {\n const r = value()\n if (r) {\n return r\n }\n }\n return defaultValue\n }\n\n if (typeof(value === \"string\")) {\n return condition ? value : (defaultValue || '')\n }\n\n if (typeof(value) === \"number\") {\n return condition ? value : (defaultValue || 0)\n }\n\n if (condition) {\n return value\n } else if (defaultValue !== undefined && defaultValue !== null) {\n return defaultValue\n }\n}\n"],"mappings":"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","names":["v","others","import_solid_js"]}
package/dist/index.mjs CHANGED
@@ -27,21 +27,25 @@ function indexOf(arr, test) {
27
27
  }
28
28
 
29
29
  // src/buckets.ts
30
- import { createSignal, createMemo, splitProps } from "solid-js";
30
+ import { createSignal, createMemo, splitProps, untrack } from "solid-js";
31
31
  function stampedBucket(value, options) {
32
32
  if (options?.localStorageName) {
33
33
  const raw = localStorage.getItem(options.localStorageName);
34
34
  if (raw) {
35
- value = JSON.parse(raw);
35
+ if (raw === "undefined") {
36
+ value = void 0;
37
+ } else {
38
+ value = JSON.parse(raw);
39
+ }
36
40
  }
37
41
  }
38
- const [timestamp, setTimestamp] = createSignal((/* @__PURE__ */ new Date()).getTime());
42
+ const [timestamp, setTimestamp] = createSignal(performance.now());
39
43
  const v = createMemo(() => {
40
44
  return {
41
45
  timestamp: timestamp(),
42
46
  data: value,
43
47
  markChanged() {
44
- setTimestamp((/* @__PURE__ */ new Date()).getTime());
48
+ setTimestamp(performance.now());
45
49
  }
46
50
  };
47
51
  });
@@ -54,7 +58,7 @@ function stampedBucket(value, options) {
54
58
  options?.beforeUpdate?.(value);
55
59
  updater(value);
56
60
  if (options?.localStorageName) {
57
- localStorage.setItem(options.localStorageName, value ? JSON.stringify(value) : "");
61
+ localStorage.setItem(options.localStorageName, JSON.stringify(value));
58
62
  }
59
63
  setTimestamp((/* @__PURE__ */ new Date()).getTime());
60
64
  options?.afterUpdate?.(value);
@@ -134,12 +138,16 @@ function bucket(value, options) {
134
138
  const [local, others] = options && splitProps(options, ["beforeUpdate", "afterUpdate", "localStorageName"]) || [];
135
139
  if (local?.localStorageName) {
136
140
  const raw = localStorage.getItem(local.localStorageName);
137
- if (raw) {
138
- value = JSON.parse(raw);
141
+ if (raw !== null) {
142
+ if (raw === "undefined") {
143
+ value = void 0;
144
+ } else {
145
+ value = JSON.parse(raw);
146
+ }
139
147
  }
140
148
  }
141
149
  const [v, setV] = createSignal(value, others);
142
- return (t) => {
150
+ const b = function(t) {
143
151
  if (t !== void 0) {
144
152
  const newValue = setV((prev) => {
145
153
  local?.beforeUpdate?.(prev);
@@ -150,13 +158,19 @@ function bucket(value, options) {
150
158
  }
151
159
  });
152
160
  if (local?.localStorageName) {
153
- localStorage.setItem(local.localStorageName, t ? JSON.stringify(t) : "");
161
+ localStorage.setItem(local.localStorageName, JSON.stringify(newValue));
154
162
  }
155
163
  local?.afterUpdate?.(newValue);
156
164
  return newValue;
157
165
  }
158
166
  return v();
159
167
  };
168
+ Object.defineProperty(b, "value", {
169
+ get: function() {
170
+ return untrack(v);
171
+ }
172
+ });
173
+ return b;
160
174
  }
161
175
 
162
176
  // src/checks.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/arrayHelpers.ts","../src/buckets.ts","../src/checks.ts","../src/wrappers.ts","../src/converters.ts","../src/generators.ts","../src/others.ts","../src/conditionals.ts"],"sourcesContent":["import { Func } from \".\";\n\n/**\n * Filter out and remove elements from array.\n * @param arr array\n * @param filter filter\n * @returns new array\n */\nexport function removeElementsFromArray<T>(arr: T[], filter: (t: T) => boolean): T[] {\n const idx: number[] = [];\n arr.forEach((t, i) => {\n if (filter(t)) {\n idx.push(i);\n }\n });\n return idx.map(i => arr.splice(i, 1)[0]);\n}\n\n/**\n * Copy range or array.\n * @param arr array\n * @param start start pos\n * @param end end pos\n * @returns sub range of array\n */\nexport function copyOfRange<T>(arr: T[], start: number, end: number): T[] {\n const r: T[] = [];\n start = Math.max(0, start);\n end = Math.min(arr.length, end);\n for (let i = start; i < end; i++) {\n r.push(arr[i]);\n }\n return r;\n}\n\n/**\n * Find first element in array which passes test.\n * @param arr array\n * @param test test\n * @returns index\n */\nexport function indexOf<T>(arr: T[], test: Func<T, boolean>) {\n for (let i = 0; i < arr.length; i++) {\n if (test(arr[i])) {\n return i;\n }\n }\n return -1;\n}\n","import { createSignal, Accessor, createMemo, SignalOptions, splitProps } from \"solid-js\"\nimport { Bucket, Mapper, ObjectIndex, StampedBucket, StampedData } from \".\";\n\n\n/**\n * Stamped Bucket help to trigger rerendering after updating object without recreate new object.\n * @returns StampedBucket<T>\n */\nexport function stampedBucket<T>(value: T, options?: {\n beforeUpdate?: (value: T) => void;\n afterUpdate?: (value: T) => void;\n localStorageName?: string;\n}): StampedBucket<T> {\n // load from local storage\n if (options?.localStorageName) {\n const raw = localStorage.getItem(options.localStorageName);\n if (raw) {\n value = JSON.parse(raw);\n }\n }\n\n const [timestamp, setTimestamp] = createSignal(new Date().getTime());\n const v: Accessor<StampedData<T>> = createMemo(() => {\n return {\n timestamp: timestamp(),\n data: value,\n markChanged() {\n setTimestamp(new Date().getTime());\n }\n };\n });\n const setV = (newValue: T) => {\n value = newValue;\n setTimestamp(new Date().getTime());\n };\n\n const call = function(updater?: (v: T) => void) {\n if (updater) {\n options?.beforeUpdate?.(value)\n\n updater(value)\n\n // save to local storage\n if (options?.localStorageName) {\n localStorage.setItem(options.localStorageName, value ? JSON.stringify(value) : \"\")\n }\n\n // mark changed\n setTimestamp(new Date().getTime());\n \n options?.afterUpdate?.(value)\n }\n\n return v().data\n }\n\n call.map = <O>(mapper: (v: T) => O) => {\n return mapper(v().data);\n };\n\n call.markChanged = () => {\n setTimestamp(new Date().getTime())\n };\n\n call.reset = (v: T) => {\n setV(v)\n };\n\n return call\n}\n\nfunction getFieldOfObject(o: any, paths: ObjectIndex[]) {\n for (let i = 0; i < paths.length - 1; i++) {\n o = o[paths[i]];\n if (!o) {\n throw new Error(`cannot find ${paths.join('.')} in ${o}`)\n }\n }\n return o[paths[paths.length - 1]]\n}\n\nfunction setFieldOfObject(o: any, newValue: any, paths: ObjectIndex[]) {\n for (let i = 0; i < paths.length - 1; i++) {\n o = o[paths[i]];\n if (!o) {\n throw new Error(`cannot find ${paths.join('.')} in ${o}`)\n }\n }\n o[paths[paths.length - 1]] = newValue\n}\n\nexport function asBucket<O, FieldType, DecadeType>(s: StampedBucket<O>, path: ObjectIndex[], mapper?: Mapper<FieldType, DecadeType>): Bucket<FieldType> {\n const getField = (data: O) => {\n let v = getFieldOfObject(data, path)\n return mapper ? mapper.from?.(v) : v\n }\n const setField = (data: O, v: any) => {\n if (mapper) {\n v = mapper.to?.(v)\n }\n setFieldOfObject(data, v, path)\n }\n return (t) => {\n if (t != undefined) {\n s(data => {\n if (typeof(t) === \"function\") {\n const oldValue = getField(data)\n // @ts-ignore\n setField(data, t(oldValue))\n } else {\n setField(data, t)\n }\n })\n\n }\n return getField(s())\n }\n}\n\nexport function asAccessor<T, K extends (keyof T)>(v: T | Accessor<T>, k: K): Accessor<T[K]> {\n return () => {\n if (typeof(v) === \"function\") {\n return (v as Function)()[k]\n }\n return v[k]\n }\n}\n\n/**\n * Create a bucket to track data.\n * @param value value or Accessor of value\n * @param options options\n * @returns Bucket<T>\n */\nexport function bucket<T>(value: T | Accessor<T>, options?: {\n useValueAsAccessor?: boolean\n beforeUpdate?: (newValue: T) => void\n afterUpdate?: (newValue: T) => void\n localStorageName?: string;\n} & SignalOptions<T>): Bucket<T> {\n if (options?.useValueAsAccessor && typeof(value) === \"function\") {\n const [_, others] = splitProps(options, [\"useValueAsAccessor\"])\n const memo = createMemo(() => bucket<T>((value as any)(), others))\n return (t) => {\n // @ts-ignore\n return memo()(t)\n }\n }\n \n const [local, others] = options && splitProps(options, [\"beforeUpdate\", \"afterUpdate\", \"localStorageName\"]) || [];\n\n // load from local storage\n if (local?.localStorageName) {\n const raw = localStorage.getItem(local.localStorageName);\n if (raw) {\n value = JSON.parse(raw);\n }\n }\n\n // @ts-ignore\n const [v, setV] = createSignal<T>(value, others)\n\n return (t) => {\n if (t !== undefined) {\n const newValue = setV((prev) => {\n local?.beforeUpdate?.(prev);\n if (typeof(t) === \"function\") {\n return (t as Function)(prev);\n } else {\n return t;\n }\n });\n // save to local storage\n if (local?.localStorageName) {\n localStorage.setItem(local.localStorageName, t ? JSON.stringify(t) : \"\");\n }\n local?.afterUpdate?.(newValue);\n return newValue;\n }\n return v()\n };\n}\n","\n/**\n * Check if array or string is not empty.\n * @param v array of any, string or undefined\n * @returns true if target is not empty\n */\nexport function isNotEmpty<T>(v?: T[]): boolean\nexport function isNotEmpty(v?: string): boolean\nexport function isNotEmpty(v: any) {\n if (!v) return false\n if (typeof(v) === \"string\") {\n return v.length > 0\n }\n if (typeof(v) === \"object\") {\n if (Array.isArray(v)) {\n return v.length > 0\n }\n return Object.keys(v).length > 0\n }\n return false\n}\n\n/**\n * Check if value is number.\n * @param v any\n * @returns true if value is number\n */\nexport function isNumber(v: any) {\n return typeof(v) === \"number\";\n}\n\n/**\n * Compare two date string.\n * @param a date 1\n * @param b date 2\n * @returns true if a is later than b\n */\nexport function compareDateString(a: string, b: string): number {\n return Date.parse(a) - Date.parse(b);\n}\n\n/**\n * Check whether there is an element in b exists in a as well.\n * @param a array 1\n * @param b array 2\n * @returns boolean\n */\nexport function containsAny(a: any[], b: any[]) {\n for (let i of a) {\n for (let j of b) {\n if (i === j) {\n return true;\n }\n }\n }\n return false;\n}\n","\n\nexport function wrapDateNumber(v: number, bits: number = 2) {\n if (v == 0) {\n return '0'.repeat(bits);\n }\n \n let n = v;\n while (n > 0) {\n n = Math.floor(n / 10);\n bits--;\n }\n return bits > 0 ? '0'.repeat(bits) + v : v;\n}\n\nexport function wrapString(v: any): string {\n if (typeof(v) === \"string\") {\n return v;\n }\n return v?.toString() || \"\";\n}\n\nexport function wrapNumber(v: any) {\n if (typeof(v) === \"number\") {\n return v;\n }\n return 0;\n}\n","import { wrapDateNumber } from \"./wrappers\";\n\n/**\n * Parse and format timestamp from number to string.\n * @param timestamp time\n * @param showTime show only date if false\n * @param showMilliseconds show ms if true\n * @returns formatted string\n */\nexport function parseTimestamp(timestamp: number, showTime?: boolean, showMilliseconds?: boolean) {\n const date = new Date(timestamp);\n // TODO: toLocaleString\n // return date.toLocaleString(undefined, {\n // });\n let r = `${wrapDateNumber(date.getFullYear())}-${wrapDateNumber(date.getMonth() + 1)}-${wrapDateNumber(date.getDate())}`;\n if (showTime) {\n r += ` ${wrapDateNumber(date.getHours())}:${wrapDateNumber(date.getMinutes())}:${wrapDateNumber(date.getSeconds())}`;\n }\n if (showMilliseconds) {\n r += `.${wrapDateNumber(date.getMilliseconds(), 3)}`;\n };\n return r;\n}\n\nexport function toCapital(v: string) {\n return v.charAt(0).toUpperCase() + v.substring(1);\n}","\n/**\n * Genereate a sequence.\n * @param start start\n * @param end end\n * @param step step\n * @returns array\n */\nexport function sequence(start: number, end: number, step: number = 1) {\n const r = [];\n for (let i = start; i < end; i += step) {\n r.push(i);\n }\n return r;\n}\n\n/**\n * Generate a array of size.\n * @param size size\n * @returns \n */\nexport function iterate(size: number) {\n return Array.from(Array(size).keys())\n}","import { Context, useContext } from \"solid-js\";\n\nexport function useCtx<T>(c: Context<T>): T {\n const context = useContext(c);\n if (!context) {\n throw new Error(\"cannot find a \" + JSON.stringify(c))\n }\n return context;\n}\n\nexport function names(...v: (string | undefined)[]) {\n return v.filter((name) => Boolean(name)).join(' ');\n}\n\nexport function clone(obj: any) {\n const type = typeof(obj);\n switch (type) {\n case 'object': {\n let r: any = Array.isArray(obj) ? [] : {};\n for (let key of Object.keys(obj)) {\n r[key] = clone(obj[key]);\n }\n return r;\n }\n default:\n return obj;\n }\n}\n","import { Supplier } from \".\"\n\n/**\n * Invoke function or return value if condition is true.\n * @param condition any\n * @param value function to be invoked or value to be return\n * @param defaultValue fallback value, optional\n */\nexport function conditional<T>(condition: any, value: () => void): void;\nexport function conditional<T>(condition: any, value: T, defaultValue?: T): T;\nexport function conditional<T>(condition: any, value: Supplier<T>, defaultValue?: T): T;\nexport function conditional(condition: any, value: any, defaultValue?: any) {\n if (typeof(value) === \"function\") {\n if (condition) {\n const r = value()\n if (r) {\n return r\n }\n }\n return defaultValue\n }\n\n if (typeof(value === \"string\")) {\n return condition ? value : (defaultValue || '')\n }\n\n if (typeof(value) === \"number\") {\n return condition ? value : (defaultValue || 0)\n }\n\n if (condition) {\n return value\n } else if (defaultValue !== undefined && defaultValue !== null) {\n return defaultValue\n }\n}\n"],"mappings":"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","names":["v","others"]}
1
+ {"version":3,"sources":["../src/arrayHelpers.ts","../src/buckets.ts","../src/checks.ts","../src/wrappers.ts","../src/converters.ts","../src/generators.ts","../src/others.ts","../src/conditionals.ts"],"sourcesContent":["import { Func } from \".\";\n\n/**\n * Filter out and remove elements from array.\n * @param arr array\n * @param filter filter\n * @returns new array\n */\nexport function removeElementsFromArray<T>(arr: T[], filter: (t: T) => boolean): T[] {\n const idx: number[] = [];\n arr.forEach((t, i) => {\n if (filter(t)) {\n idx.push(i);\n }\n });\n return idx.map(i => arr.splice(i, 1)[0]);\n}\n\n/**\n * Copy range or array.\n * @param arr array\n * @param start start pos\n * @param end end pos\n * @returns sub range of array\n */\nexport function copyOfRange<T>(arr: T[], start: number, end: number): T[] {\n const r: T[] = [];\n start = Math.max(0, start);\n end = Math.min(arr.length, end);\n for (let i = start; i < end; i++) {\n r.push(arr[i]);\n }\n return r;\n}\n\n/**\n * Find first element in array which passes test.\n * @param arr array\n * @param test test\n * @returns index\n */\nexport function indexOf<T>(arr: T[], test: Func<T, boolean>) {\n for (let i = 0; i < arr.length; i++) {\n if (test(arr[i])) {\n return i;\n }\n }\n return -1;\n}\n","import { createSignal, Accessor, createMemo, SignalOptions, splitProps, untrack } from \"solid-js\"\nimport { Bucket, Mapper, ObjectIndex, StampedBucket, StampedData } from \".\";\n\n\n/**\n * Stamped Bucket help to trigger rerendering after updating object without recreate new object.\n * @returns StampedBucket<T>\n */\nexport function stampedBucket<T>(value: T, options?: {\n beforeUpdate?: (value: T) => void;\n afterUpdate?: (value: T) => void;\n localStorageName?: string;\n}): StampedBucket<T> {\n // load from local storage\n if (options?.localStorageName) {\n const raw = localStorage.getItem(options.localStorageName);\n if (raw) {\n if (raw === 'undefined') {\n value = undefined as any;\n } else {\n value = JSON.parse(raw);\n }\n }\n }\n\n const [timestamp, setTimestamp] = createSignal(performance.now());\n const v: Accessor<StampedData<T>> = createMemo(() => {\n return {\n timestamp: timestamp(),\n data: value,\n markChanged() {\n setTimestamp(performance.now());\n }\n };\n });\n const setV = (newValue: T) => {\n value = newValue;\n setTimestamp(new Date().getTime());\n };\n\n const call = function(updater?: (v: T) => void) {\n if (updater) {\n options?.beforeUpdate?.(value)\n\n updater(value)\n\n // save to local storage\n if (options?.localStorageName) {\n localStorage.setItem(options.localStorageName, JSON.stringify(value));\n }\n\n // mark changed\n setTimestamp(new Date().getTime());\n \n options?.afterUpdate?.(value)\n }\n\n return v().data\n }\n\n call.map = <O>(mapper: (v: T) => O) => {\n return mapper(v().data);\n };\n\n call.markChanged = () => {\n setTimestamp(new Date().getTime())\n };\n\n call.reset = (v: T) => {\n setV(v)\n };\n\n return call\n}\n\nfunction getFieldOfObject(o: any, paths: ObjectIndex[]) {\n for (let i = 0; i < paths.length - 1; i++) {\n o = o[paths[i]];\n if (!o) {\n throw new Error(`cannot find ${paths.join('.')} in ${o}`)\n }\n }\n return o[paths[paths.length - 1]]\n}\n\nfunction setFieldOfObject(o: any, newValue: any, paths: ObjectIndex[]) {\n for (let i = 0; i < paths.length - 1; i++) {\n o = o[paths[i]];\n if (!o) {\n throw new Error(`cannot find ${paths.join('.')} in ${o}`)\n }\n }\n o[paths[paths.length - 1]] = newValue\n}\n\nexport function asBucket<O, FieldType, DecadeType>(s: StampedBucket<O>, path: ObjectIndex[], mapper?: Mapper<FieldType, DecadeType>): Bucket<FieldType> {\n const getField = (data: O) => {\n let v = getFieldOfObject(data, path)\n return mapper ? mapper.from?.(v) : v\n }\n const setField = (data: O, v: any) => {\n if (mapper) {\n v = mapper.to?.(v)\n }\n setFieldOfObject(data, v, path)\n }\n return (t) => {\n if (t != undefined) {\n s(data => {\n if (typeof(t) === \"function\") {\n const oldValue = getField(data)\n // @ts-ignore\n setField(data, t(oldValue))\n } else {\n setField(data, t)\n }\n })\n\n }\n return getField(s())\n }\n}\n\nexport function asAccessor<T, K extends (keyof T)>(v: T | Accessor<T>, k: K): Accessor<T[K]> {\n return () => {\n if (typeof(v) === \"function\") {\n return (v as Function)()[k]\n }\n return v[k]\n }\n}\n\n/**\n * Create a bucket to track data.\n * @param value value or Accessor of value\n * @param options options\n * @returns Bucket<T>\n */\nexport function bucket<T>(value: T | Accessor<T>, options?: {\n useValueAsAccessor?: boolean\n beforeUpdate?: (newValue: T) => void\n afterUpdate?: (newValue: T) => void\n localStorageName?: string;\n} & SignalOptions<T>): Bucket<T> {\n if (options?.useValueAsAccessor && typeof(value) === \"function\") {\n const [_, others] = splitProps(options, [\"useValueAsAccessor\"])\n const memo = createMemo(() => bucket<T>((value as any)(), others))\n return (t) => {\n // @ts-ignore\n return memo()(t)\n }\n }\n \n const [local, others] = options && splitProps(options, [\"beforeUpdate\", \"afterUpdate\", \"localStorageName\"]) || [];\n\n // load from local storage\n if (local?.localStorageName) {\n const raw = localStorage.getItem(local.localStorageName);\n if (raw !== null) {\n if (raw === 'undefined') {\n value = undefined as any;\n } else {\n value = JSON.parse(raw);\n }\n }\n }\n\n // @ts-ignore\n const [v, setV] = createSignal<T>(value, others)\n\n const b = function(t) {\n if (t !== undefined) {\n const newValue = setV((prev) => {\n local?.beforeUpdate?.(prev);\n if (typeof(t) === \"function\") {\n return (t as Function)(prev);\n } else {\n return t;\n }\n });\n // save to local storage\n if (local?.localStorageName) {\n localStorage.setItem(local.localStorageName, JSON.stringify(newValue));\n }\n local?.afterUpdate?.(newValue);\n return newValue;\n }\n return v()\n } as Bucket<T>;\n\n Object.defineProperty(b, 'value', {\n get: function() {\n return untrack(v);\n },\n });\n\n return b;\n}\n","\n/**\n * Check if array or string is not empty.\n * @param v array of any, string or undefined\n * @returns true if target is not empty\n */\nexport function isNotEmpty<T>(v?: T[]): boolean\nexport function isNotEmpty(v?: string): boolean\nexport function isNotEmpty(v: any) {\n if (!v) return false\n if (typeof(v) === \"string\") {\n return v.length > 0\n }\n if (typeof(v) === \"object\") {\n if (Array.isArray(v)) {\n return v.length > 0\n }\n return Object.keys(v).length > 0\n }\n return false\n}\n\n/**\n * Check if value is number.\n * @param v any\n * @returns true if value is number\n */\nexport function isNumber(v: any) {\n return typeof(v) === \"number\";\n}\n\n/**\n * Compare two date string.\n * @param a date 1\n * @param b date 2\n * @returns true if a is later than b\n */\nexport function compareDateString(a: string, b: string): number {\n return Date.parse(a) - Date.parse(b);\n}\n\n/**\n * Check whether there is an element in b exists in a as well.\n * @param a array 1\n * @param b array 2\n * @returns boolean\n */\nexport function containsAny(a: any[], b: any[]) {\n for (let i of a) {\n for (let j of b) {\n if (i === j) {\n return true;\n }\n }\n }\n return false;\n}\n","\n\nexport function wrapDateNumber(v: number, bits: number = 2) {\n if (v == 0) {\n return '0'.repeat(bits);\n }\n \n let n = v;\n while (n > 0) {\n n = Math.floor(n / 10);\n bits--;\n }\n return bits > 0 ? '0'.repeat(bits) + v : v;\n}\n\nexport function wrapString(v: any): string {\n if (typeof(v) === \"string\") {\n return v;\n }\n return v?.toString() || \"\";\n}\n\nexport function wrapNumber(v: any) {\n if (typeof(v) === \"number\") {\n return v;\n }\n return 0;\n}\n","import { wrapDateNumber } from \"./wrappers\";\n\n/**\n * Parse and format timestamp from number to string.\n * @param timestamp time\n * @param showTime show only date if false\n * @param showMilliseconds show ms if true\n * @returns formatted string\n */\nexport function parseTimestamp(timestamp: number, showTime?: boolean, showMilliseconds?: boolean) {\n const date = new Date(timestamp);\n // TODO: toLocaleString\n // return date.toLocaleString(undefined, {\n // });\n let r = `${wrapDateNumber(date.getFullYear())}-${wrapDateNumber(date.getMonth() + 1)}-${wrapDateNumber(date.getDate())}`;\n if (showTime) {\n r += ` ${wrapDateNumber(date.getHours())}:${wrapDateNumber(date.getMinutes())}:${wrapDateNumber(date.getSeconds())}`;\n }\n if (showMilliseconds) {\n r += `.${wrapDateNumber(date.getMilliseconds(), 3)}`;\n };\n return r;\n}\n\nexport function toCapital(v: string) {\n return v.charAt(0).toUpperCase() + v.substring(1);\n}","\n/**\n * Genereate a sequence.\n * @param start start\n * @param end end\n * @param step step\n * @returns array\n */\nexport function sequence(start: number, end: number, step: number = 1) {\n const r = [];\n for (let i = start; i < end; i += step) {\n r.push(i);\n }\n return r;\n}\n\n/**\n * Generate a array of size.\n * @param size size\n * @returns \n */\nexport function iterate(size: number) {\n return Array.from(Array(size).keys())\n}","import { Context, useContext } from \"solid-js\";\n\nexport function useCtx<T>(c: Context<T>): T {\n const context = useContext(c);\n if (!context) {\n throw new Error(\"cannot find a \" + JSON.stringify(c))\n }\n return context;\n}\n\nexport function names(...v: (string | undefined)[]) {\n return v.filter((name) => Boolean(name)).join(' ');\n}\n\nexport function clone(obj: any) {\n const type = typeof(obj);\n switch (type) {\n case 'object': {\n let r: any = Array.isArray(obj) ? [] : {};\n for (let key of Object.keys(obj)) {\n r[key] = clone(obj[key]);\n }\n return r;\n }\n default:\n return obj;\n }\n}\n","import { Supplier } from \".\"\n\n/**\n * Invoke function or return value if condition is true.\n * @param condition any\n * @param value function to be invoked or value to be return\n * @param defaultValue fallback value, optional\n */\nexport function conditional<T>(condition: any, value: () => void): void;\nexport function conditional<T>(condition: any, value: T, defaultValue?: T): T;\nexport function conditional<T>(condition: any, value: Supplier<T>, defaultValue?: T): T;\nexport function conditional(condition: any, value: any, defaultValue?: any) {\n if (typeof(value) === \"function\") {\n if (condition) {\n const r = value()\n if (r) {\n return r\n }\n }\n return defaultValue\n }\n\n if (typeof(value === \"string\")) {\n return condition ? value : (defaultValue || '')\n }\n\n if (typeof(value) === \"number\") {\n return condition ? value : (defaultValue || 0)\n }\n\n if (condition) {\n return value\n } else if (defaultValue !== undefined && defaultValue !== null) {\n return defaultValue\n }\n}\n"],"mappings":"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","names":["v","others"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-new-bucket",
3
- "version": "0.0.4-g",
3
+ "version": "0.0.4-h",
4
4
  "description": "Better Signal API for SolidJS",
5
5
  "scripts": {
6
6
  "start": "vite",