solid-new-bucket 0.0.1-d → 0.0.1
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/app/index.tsx +12 -0
- package/index.html +16 -0
- package/package.json +2 -9
- package/src/arrayHelpers.ts +48 -0
- package/src/buckets.ts +182 -0
- package/src/checks.ts +57 -0
- package/src/conditionals.ts +35 -0
- package/src/converters.ts +27 -0
- package/src/functions.d.ts +23 -0
- package/src/generators.ts +24 -0
- package/src/global.d.ts +30 -0
- package/src/index.ts +14 -0
- package/src/others.ts +28 -0
- package/src/wrappers.ts +28 -0
- package/tsconfig.json +17 -0
- package/vite.config.ts +20 -0
- package/dist/index.d.mts +0 -125
- package/dist/index.d.ts +0 -125
- package/dist/index.js +0 -371
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -323
- package/dist/index.mjs.map +0 -1
package/app/index.tsx
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* @refresh reload */
|
|
2
|
+
import { render } from 'solid-js/web';
|
|
3
|
+
|
|
4
|
+
const root = document.getElementById('root');
|
|
5
|
+
|
|
6
|
+
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
'Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?',
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
render(() => 'app', root!);
|
package/index.html
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="theme-color" content="#000000" />
|
|
7
|
+
<link rel="shortcut icon" type="image/ico" href="/app/assets/favicon.ico" />
|
|
8
|
+
<title>Solid App</title>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
|
|
14
|
+
<script src="/app/index.tsx" type="module"></script>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solid-new-bucket",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.1",
|
|
4
4
|
"description": "Better Signal API for SolidJS",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "vite",
|
|
7
7
|
"dev": "vite",
|
|
8
|
-
"build": "
|
|
8
|
+
"build": "vite build",
|
|
9
9
|
"serve": "vite preview"
|
|
10
10
|
},
|
|
11
11
|
"license": "GNU",
|
|
12
|
-
"main": "./dist/index.js",
|
|
13
|
-
"module": "./dist/index.mjs",
|
|
14
|
-
"types": "./dist/index.d.ts",
|
|
15
|
-
"files": [
|
|
16
|
-
"dist"
|
|
17
|
-
],
|
|
18
12
|
"devDependencies": {
|
|
19
13
|
"solid-devtools": "^0.27.3",
|
|
20
|
-
"tsup": "^8.1.0",
|
|
21
14
|
"typescript": "^5.1.3",
|
|
22
15
|
"vite": "^4.3.9",
|
|
23
16
|
"vite-plugin-solid": "^2.7.0"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Filter out and remove elements from array.
|
|
4
|
+
* @param arr array
|
|
5
|
+
* @param filter filter
|
|
6
|
+
* @returns new array
|
|
7
|
+
*/
|
|
8
|
+
export function removeElementsFromArray<T>(arr: T[], filter: (t: T) => boolean): T[] {
|
|
9
|
+
const idx: number[] = [];
|
|
10
|
+
arr.forEach((t, i) => {
|
|
11
|
+
if (filter(t)) {
|
|
12
|
+
idx.push(i);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return idx.map(i => arr.splice(i, 1)[0]);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Copy range or array.
|
|
20
|
+
* @param arr array
|
|
21
|
+
* @param start start pos
|
|
22
|
+
* @param end end pos
|
|
23
|
+
* @returns sub range of array
|
|
24
|
+
*/
|
|
25
|
+
export function copyOfRange<T>(arr: T[], start: number, end: number): T[] {
|
|
26
|
+
const r: T[] = [];
|
|
27
|
+
start = Math.max(0, start);
|
|
28
|
+
end = Math.min(arr.length, end);
|
|
29
|
+
for (let i = start; i < end; i++) {
|
|
30
|
+
r.push(arr[i]);
|
|
31
|
+
}
|
|
32
|
+
return r;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Find first element in array which passes test.
|
|
37
|
+
* @param arr array
|
|
38
|
+
* @param test test
|
|
39
|
+
* @returns index
|
|
40
|
+
*/
|
|
41
|
+
export function indexOf<T>(arr: T[], test: Func<T, boolean>) {
|
|
42
|
+
for (let i = 0; i < arr.length; i++) {
|
|
43
|
+
if (test(arr[i])) {
|
|
44
|
+
return i;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return -1;
|
|
48
|
+
}
|
package/src/buckets.ts
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { createSignal, Accessor, createMemo, SignalOptions, splitProps } from "solid-js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stamped Bucket help to trigger rerendering after updating object without recreate new object.
|
|
5
|
+
* @returns StampedBucket<T>
|
|
6
|
+
*/
|
|
7
|
+
export function stampedBucket<T>(value: T, options?: {
|
|
8
|
+
beforeUpdate?: (value: T) => void;
|
|
9
|
+
afterUpdate?: (value: T) => void;
|
|
10
|
+
localStorageName?: string;
|
|
11
|
+
}): StampedBucket<T> {
|
|
12
|
+
// load from local storage
|
|
13
|
+
if (options?.localStorageName) {
|
|
14
|
+
const raw = localStorage.getItem(options.localStorageName);
|
|
15
|
+
if (raw) {
|
|
16
|
+
value = JSON.parse(raw);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const [timestamp, setTimestamp] = createSignal(new Date().getTime());
|
|
21
|
+
const v: Accessor<StampedData<T>> = createMemo(() => {
|
|
22
|
+
return {
|
|
23
|
+
timestamp: timestamp(),
|
|
24
|
+
data: value,
|
|
25
|
+
markChanged() {
|
|
26
|
+
setTimestamp(new Date().getTime());
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
const setV = (newValue?: T) => {
|
|
31
|
+
if (newValue) {
|
|
32
|
+
value = newValue
|
|
33
|
+
}
|
|
34
|
+
setTimestamp(new Date().getTime())
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const call = function(updater?: (v: T) => void) {
|
|
38
|
+
if (updater) {
|
|
39
|
+
options?.beforeUpdate?.(value)
|
|
40
|
+
|
|
41
|
+
updater(value)
|
|
42
|
+
|
|
43
|
+
// save to local storage
|
|
44
|
+
if (options?.localStorageName) {
|
|
45
|
+
localStorage.setItem(options.localStorageName, value ? JSON.stringify(value) : "")
|
|
46
|
+
}
|
|
47
|
+
setV();
|
|
48
|
+
|
|
49
|
+
options?.afterUpdate?.(value)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// add mapper function
|
|
53
|
+
(call as any).map = <O>(mapper: (v: T) => O) => {
|
|
54
|
+
return mapper(v().data);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// add markChanged function
|
|
58
|
+
(call as any).markChanged = () => {
|
|
59
|
+
setTimestamp(new Date().getTime())
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
(call as any).reset = (v: T) => {
|
|
63
|
+
setV(v)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return v().data
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return call as any
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getFieldOfObject(o: any, paths: ObjectIndex[]) {
|
|
73
|
+
for (let i = 0; i < paths.length - 1; i++) {
|
|
74
|
+
o = o[paths[i]];
|
|
75
|
+
if (!o) {
|
|
76
|
+
throw new Error(`cannot find ${paths.join('.')} in ${o}`)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return o[paths[paths.length - 1]]
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function setFieldOfObject(o: any, newValue: any, paths: ObjectIndex[]) {
|
|
83
|
+
for (let i = 0; i < paths.length - 1; i++) {
|
|
84
|
+
o = o[paths[i]];
|
|
85
|
+
if (!o) {
|
|
86
|
+
throw new Error(`cannot find ${paths.join('.')} in ${o}`)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
o[paths[paths.length - 1]] = newValue
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function asBucket<O, FieldType, DecadeType>(s: StampedBucket<O>, path: ObjectIndex[], mapper?: Mapper<FieldType, DecadeType>): Bucket<FieldType> {
|
|
93
|
+
const getField = (data: O) => {
|
|
94
|
+
let v = getFieldOfObject(data, path)
|
|
95
|
+
return mapper ? mapper.from?.(v) : v
|
|
96
|
+
}
|
|
97
|
+
const setField = (data: O, v: any) => {
|
|
98
|
+
if (mapper) {
|
|
99
|
+
v = mapper.to?.(v)
|
|
100
|
+
}
|
|
101
|
+
setFieldOfObject(data, v, path)
|
|
102
|
+
}
|
|
103
|
+
return (t) => {
|
|
104
|
+
if (t != undefined) {
|
|
105
|
+
s(data => {
|
|
106
|
+
if (typeof(t) === "function") {
|
|
107
|
+
const oldValue = getField(data)
|
|
108
|
+
// @ts-ignore
|
|
109
|
+
setField(data, t(oldValue))
|
|
110
|
+
} else {
|
|
111
|
+
setField(data, t)
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
return getField(s())
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function asAccessor<T, K extends (keyof T)>(v: T | Accessor<T>, k: K): Accessor<T[K]> {
|
|
121
|
+
return () => {
|
|
122
|
+
if (typeof(v) === "function") {
|
|
123
|
+
return (v as Function)()[k]
|
|
124
|
+
}
|
|
125
|
+
return v[k]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Create a bucket to track data.
|
|
131
|
+
* @param value value or Accessor of value
|
|
132
|
+
* @param options options
|
|
133
|
+
* @returns Bucket<T>
|
|
134
|
+
*/
|
|
135
|
+
export function bucket<T>(value: T | Accessor<T>, options?: {
|
|
136
|
+
useValueAsAccessor?: boolean
|
|
137
|
+
beforeUpdate?: (newValue: T) => void
|
|
138
|
+
afterUpdate?: (newValue: T) => void
|
|
139
|
+
localStorageName?: string;
|
|
140
|
+
} & SignalOptions<T>): Bucket<T> {
|
|
141
|
+
if (options?.useValueAsAccessor && typeof(value) === "function") {
|
|
142
|
+
const [_, others] = splitProps(options, ["useValueAsAccessor"])
|
|
143
|
+
const memo = createMemo(() => bucket<T>((value as any)(), others))
|
|
144
|
+
return (t) => {
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
return memo()(t)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const [local, others] = options && splitProps(options, ["beforeUpdate", "afterUpdate", "localStorageName"]) || [];
|
|
151
|
+
|
|
152
|
+
// load from local storage
|
|
153
|
+
if (local?.localStorageName) {
|
|
154
|
+
const raw = localStorage.getItem(local.localStorageName);
|
|
155
|
+
if (raw) {
|
|
156
|
+
value = JSON.parse(raw);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// @ts-ignore
|
|
161
|
+
const [v, setV] = createSignal<T>(value, others)
|
|
162
|
+
|
|
163
|
+
return (t) => {
|
|
164
|
+
if (t !== undefined) {
|
|
165
|
+
const newValue = setV((prev) => {
|
|
166
|
+
local?.beforeUpdate?.(prev);
|
|
167
|
+
if (typeof(t) === "function") {
|
|
168
|
+
return (t as Function)(prev);
|
|
169
|
+
} else {
|
|
170
|
+
return t;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
// save to local storage
|
|
174
|
+
if (local?.localStorageName) {
|
|
175
|
+
localStorage.setItem(local.localStorageName, t ? JSON.stringify(t) : "");
|
|
176
|
+
}
|
|
177
|
+
local?.afterUpdate?.(newValue);
|
|
178
|
+
return newValue;
|
|
179
|
+
}
|
|
180
|
+
return v()
|
|
181
|
+
};
|
|
182
|
+
}
|
package/src/checks.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Check if array or string is not empty.
|
|
4
|
+
* @param v array of any, string or undefined
|
|
5
|
+
* @returns true if target is not empty
|
|
6
|
+
*/
|
|
7
|
+
export function isNotEmpty<T>(v?: T[]): boolean
|
|
8
|
+
export function isNotEmpty(v?: string): boolean
|
|
9
|
+
export function isNotEmpty(v: any) {
|
|
10
|
+
if (!v) return false
|
|
11
|
+
if (typeof(v) === "string") {
|
|
12
|
+
return v.length > 0
|
|
13
|
+
}
|
|
14
|
+
if (typeof(v) === "object") {
|
|
15
|
+
if (Array.isArray(v)) {
|
|
16
|
+
return v.length > 0
|
|
17
|
+
}
|
|
18
|
+
return Object.keys(v).length > 0
|
|
19
|
+
}
|
|
20
|
+
return false
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Check if value is number.
|
|
25
|
+
* @param v any
|
|
26
|
+
* @returns true if value is number
|
|
27
|
+
*/
|
|
28
|
+
export function isNumber(v: any) {
|
|
29
|
+
return typeof(v) === "number";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Compare two date string.
|
|
34
|
+
* @param a date 1
|
|
35
|
+
* @param b date 2
|
|
36
|
+
* @returns true if a is later than b
|
|
37
|
+
*/
|
|
38
|
+
export function compareDateString(a: string, b: string): number {
|
|
39
|
+
return Date.parse(a) - Date.parse(b);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check whether there is an element in b exists in a as well.
|
|
44
|
+
* @param a array 1
|
|
45
|
+
* @param b array 2
|
|
46
|
+
* @returns boolean
|
|
47
|
+
*/
|
|
48
|
+
export function containsAny(a: any[], b: any[]) {
|
|
49
|
+
for (let i of a) {
|
|
50
|
+
for (let j of b) {
|
|
51
|
+
if (i === j) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Invoke function or return value if condition is true.
|
|
4
|
+
* @param condition any
|
|
5
|
+
* @param value function to be invoked or value to be return
|
|
6
|
+
* @param defaultValue fallback value, optional
|
|
7
|
+
*/
|
|
8
|
+
export function conditional<T>(condition: any, value: () => void): void;
|
|
9
|
+
export function conditional<T>(condition: any, value: T, defaultValue?: T): T;
|
|
10
|
+
export function conditional<T>(condition: any, value: Supplier<T>, defaultValue?: T): T;
|
|
11
|
+
export function conditional(condition: any, value: any, defaultValue?: any) {
|
|
12
|
+
if (typeof(value) === "function") {
|
|
13
|
+
if (condition) {
|
|
14
|
+
const r = value()
|
|
15
|
+
if (r) {
|
|
16
|
+
return r
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return defaultValue
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof(value === "string")) {
|
|
23
|
+
return condition ? value : (defaultValue || '')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (typeof(value) === "number") {
|
|
27
|
+
return condition ? value : (defaultValue || 0)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (condition) {
|
|
31
|
+
return value
|
|
32
|
+
} else if (defaultValue !== undefined && defaultValue !== null) {
|
|
33
|
+
return defaultValue
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { wrapDateNumber } from "./wrappers";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parse and format timestamp from number to string.
|
|
5
|
+
* @param timestamp time
|
|
6
|
+
* @param showTime show only date if false
|
|
7
|
+
* @param showMilliseconds show ms if true
|
|
8
|
+
* @returns formatted string
|
|
9
|
+
*/
|
|
10
|
+
export function parseTimestamp(timestamp: number, showTime?: boolean, showMilliseconds?: boolean) {
|
|
11
|
+
const date = new Date(timestamp);
|
|
12
|
+
// TODO: toLocaleString
|
|
13
|
+
// return date.toLocaleString(undefined, {
|
|
14
|
+
// });
|
|
15
|
+
let r = `${wrapDateNumber(date.getFullYear())}-${wrapDateNumber(date.getMonth() + 1)}-${wrapDateNumber(date.getDate())}`;
|
|
16
|
+
if (showTime) {
|
|
17
|
+
r += ` ${wrapDateNumber(date.getHours())}:${wrapDateNumber(date.getMinutes())}:${wrapDateNumber(date.getSeconds())}`;
|
|
18
|
+
}
|
|
19
|
+
if (showMilliseconds) {
|
|
20
|
+
r += `.${wrapDateNumber(date.getMilliseconds(), 3)}`;
|
|
21
|
+
};
|
|
22
|
+
return r;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function toCapital(v: string) {
|
|
26
|
+
return v.charAt(0).toUpperCase() + v.substring(1);
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
export {}
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
|
|
6
|
+
type Pair<K, V> = [key: K, value: V]
|
|
7
|
+
|
|
8
|
+
type Consumer<T> = (v: T) => void
|
|
9
|
+
|
|
10
|
+
type BiConsumer<A, B> = (a: A, b: B) => void
|
|
11
|
+
|
|
12
|
+
type TriConsumer<A, B, C> = (a: A, b: B, c: C) => void
|
|
13
|
+
|
|
14
|
+
type Func<T, R> = (v: T) => R
|
|
15
|
+
|
|
16
|
+
type BiFunc<A, B, R> = (a: A, b: B) => R
|
|
17
|
+
|
|
18
|
+
type Callback = (...args: any) => any
|
|
19
|
+
|
|
20
|
+
type Supplier<T> = () => T
|
|
21
|
+
|
|
22
|
+
type Comparator<T> = (a: T, b: T) => -1 | 0 | 1
|
|
23
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Genereate a sequence.
|
|
4
|
+
* @param start start
|
|
5
|
+
* @param end end
|
|
6
|
+
* @param step step
|
|
7
|
+
* @returns array
|
|
8
|
+
*/
|
|
9
|
+
export function sequence(start: number, end: number, step: number = 1) {
|
|
10
|
+
const r = [];
|
|
11
|
+
for (let i = start; i < end; i += step) {
|
|
12
|
+
r.push(i);
|
|
13
|
+
}
|
|
14
|
+
return r;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Generate a array of size.
|
|
19
|
+
* @param size size
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
export function iterate(size: number) {
|
|
23
|
+
return Array.from(Array(size).keys())
|
|
24
|
+
}
|
package/src/global.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
export { }
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
|
|
6
|
+
interface Mapper<A, B> {
|
|
7
|
+
to?(a: A): B;
|
|
8
|
+
from?(b: B): A;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Bucket<T> = {
|
|
12
|
+
// (v?: T): T;
|
|
13
|
+
// (v: (prev: T) => T): T;
|
|
14
|
+
<U extends T>(v?: T): U;
|
|
15
|
+
<U extends T>(v: (prev: T) => U): U;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface StampedBucketAction<T> {
|
|
19
|
+
map<O>(call: (v: T) => O): O
|
|
20
|
+
markChanged(): void
|
|
21
|
+
reset(v: T): void
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type StampedBucket<T> = ((updater?: Consumer<T>) => T) & StampedBucketAction<T>;
|
|
25
|
+
|
|
26
|
+
interface StampedData<T> {
|
|
27
|
+
data: T
|
|
28
|
+
timestamp: number
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
export * from "./arrayHelpers"
|
|
3
|
+
export * from "./buckets"
|
|
4
|
+
export * from "./checks"
|
|
5
|
+
export * from "./converters"
|
|
6
|
+
export * from "./generators"
|
|
7
|
+
export * from "./others"
|
|
8
|
+
export * from "./wrappers"
|
|
9
|
+
export * from "./conditionals"
|
|
10
|
+
|
|
11
|
+
declare global {
|
|
12
|
+
|
|
13
|
+
type ObjectIndex = string | number
|
|
14
|
+
}
|
package/src/others.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Context, useContext } from "solid-js";
|
|
2
|
+
|
|
3
|
+
export function useCtx<T>(c: Context<T>): T {
|
|
4
|
+
const context = useContext(c);
|
|
5
|
+
if (!context) {
|
|
6
|
+
throw new Error("cannot find a " + JSON.stringify(c))
|
|
7
|
+
}
|
|
8
|
+
return context;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function names(...v: (string | undefined)[]) {
|
|
12
|
+
return v.filter((name) => Boolean(name)).join(' ');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function clone(obj: any) {
|
|
16
|
+
const type = typeof(obj);
|
|
17
|
+
switch (type) {
|
|
18
|
+
case 'object': {
|
|
19
|
+
let r: any = Array.isArray(obj) ? [] : {};
|
|
20
|
+
for (let key of Object.keys(obj)) {
|
|
21
|
+
r[key] = clone(obj[key]);
|
|
22
|
+
}
|
|
23
|
+
return r;
|
|
24
|
+
}
|
|
25
|
+
default:
|
|
26
|
+
return obj;
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/wrappers.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export function wrapDateNumber(v: number, bits: number = 2) {
|
|
4
|
+
if (v == 0) {
|
|
5
|
+
return '0'.repeat(bits);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let n = v;
|
|
9
|
+
while (n > 0) {
|
|
10
|
+
n = Math.floor(n / 10);
|
|
11
|
+
bits--;
|
|
12
|
+
}
|
|
13
|
+
return bits > 0 ? '0'.repeat(bits) + v : v;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function wrapString(v: any): string {
|
|
17
|
+
if (typeof(v) === "string") {
|
|
18
|
+
return v;
|
|
19
|
+
}
|
|
20
|
+
return v?.toString() || "";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function wrapNumber(v: any) {
|
|
24
|
+
if (typeof(v) === "number") {
|
|
25
|
+
return v;
|
|
26
|
+
}
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"strict": true,
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
"allowSyntheticDefaultImports": true,
|
|
8
|
+
"strictPropertyInitialization": false,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"jsx": "preserve",
|
|
11
|
+
"jsxImportSource": "solid-js",
|
|
12
|
+
"types": ["vite/client"],
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"isolatedModules": true,
|
|
15
|
+
"resolveJsonModule": true
|
|
16
|
+
}
|
|
17
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import solidPlugin from 'vite-plugin-solid';
|
|
3
|
+
// import devtools from 'solid-devtools/vite';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [
|
|
7
|
+
/*
|
|
8
|
+
Uncomment the following line to enable solid-devtools.
|
|
9
|
+
For more info see https://github.com/thetarnav/solid-devtools/tree/main/packages/extension#readme
|
|
10
|
+
*/
|
|
11
|
+
// devtools(),
|
|
12
|
+
solidPlugin(),
|
|
13
|
+
],
|
|
14
|
+
server: {
|
|
15
|
+
port: 3000,
|
|
16
|
+
},
|
|
17
|
+
build: {
|
|
18
|
+
target: 'esnext',
|
|
19
|
+
},
|
|
20
|
+
});
|