@vope/utils 1.6.0-bate.2 → 1.6.0-bate.4

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.
Files changed (76) hide show
  1. package/dist/clamp.d.ts +4 -0
  2. package/dist/clamp.mjs +11 -0
  3. package/dist/classnames.d.ts +7 -0
  4. package/dist/classnames.mjs +17 -0
  5. package/dist/compare/version.d.ts +5 -0
  6. package/dist/compare/version.mjs +15 -0
  7. package/dist/compare/weak-equal.d.ts +4 -0
  8. package/dist/compare/weak-equal.mjs +33 -0
  9. package/dist/convert/json.d.ts +12 -0
  10. package/dist/convert/json.mjs +7 -0
  11. package/dist/convert/object.d.ts +12 -0
  12. package/dist/convert/object.mjs +7 -0
  13. package/dist/convert/strings.d.ts +6 -0
  14. package/dist/convert/strings.mjs +7 -0
  15. package/dist/desens.d.ts +40 -0
  16. package/dist/desens.mjs +51 -0
  17. package/dist/encoding.d.ts +9 -0
  18. package/dist/encoding.mjs +56 -0
  19. package/dist/index.d.ts +34 -0
  20. package/dist/index.js +1265 -0
  21. package/dist/index.mjs +73 -0
  22. package/dist/input-regex.d.ts +12 -0
  23. package/dist/input-regex.mjs +8 -0
  24. package/dist/is/class.d.ts +4 -0
  25. package/dist/is/class.mjs +22 -0
  26. package/dist/is/empty.d.ts +4 -0
  27. package/dist/is/empty.mjs +5 -0
  28. package/dist/is/key.d.ts +4 -0
  29. package/dist/is/key.mjs +4 -0
  30. package/dist/is/null.d.ts +4 -0
  31. package/dist/is/null.mjs +4 -0
  32. package/dist/load/image.d.ts +5 -0
  33. package/dist/load/image.mjs +11 -0
  34. package/dist/memory/basic.d.ts +79 -0
  35. package/dist/memory/basic.mjs +167 -0
  36. package/dist/memory/list.d.ts +8 -0
  37. package/dist/memory/list.mjs +12 -0
  38. package/dist/memory/power.d.ts +8 -0
  39. package/dist/memory/power.mjs +13 -0
  40. package/dist/memory/simple.d.ts +60 -0
  41. package/dist/memory/simple.mjs +94 -0
  42. package/dist/neo4j-anchors.d.ts +50 -0
  43. package/dist/neo4j-anchors.mjs +169 -0
  44. package/dist/neo4j.d.ts +82 -0
  45. package/dist/neo4j.mjs +161 -0
  46. package/dist/once.d.ts +6 -0
  47. package/dist/once.mjs +8 -0
  48. package/dist/parse/num.d.ts +8 -0
  49. package/dist/parse/num.mjs +31 -0
  50. package/dist/power/decon.d.ts +9 -0
  51. package/dist/power/decon.mjs +22 -0
  52. package/dist/rotate/angle.d.ts +8 -0
  53. package/dist/rotate/angle.mjs +5 -0
  54. package/dist/rotate/rad.d.ts +8 -0
  55. package/dist/rotate/rad.mjs +11 -0
  56. package/dist/serialize/url-params.d.ts +43 -0
  57. package/dist/serialize/url-params.mjs +53 -0
  58. package/dist/storage/offline.d.ts +51 -0
  59. package/dist/style/css.d.ts +9 -0
  60. package/dist/style/css.mjs +25 -0
  61. package/dist/subscriber.d.ts +11 -0
  62. package/dist/subscriber.mjs +64 -0
  63. package/dist/table/flex.d.ts +43 -0
  64. package/dist/table/flex.mjs +96 -0
  65. package/dist/union.d.ts +34 -0
  66. package/dist/union.mjs +47 -0
  67. package/dist/url/join.d.ts +4 -0
  68. package/dist/url/join.mjs +9 -0
  69. package/dist/url/params.d.ts +8 -0
  70. package/dist/url/params.mjs +8 -0
  71. package/dist/wait.d.ts +4 -0
  72. package/dist/wait.mjs +4 -0
  73. package/package.json +3 -4
  74. package/sub_storage/offline.d.ts +51 -0
  75. package/sub_storage/offline.js +255 -0
  76. package/sub_storage/offline.mjs +223 -0
@@ -0,0 +1,169 @@
1
+ import { rotateRad } from "./rotate/rad";
2
+ class Neo4jAhchors {
3
+ constructor(neo4j, config) {
4
+ this.neo4j = neo4j;
5
+ this.config = Object.assign({}, config);
6
+ }
7
+ config;
8
+ #anchors = {};
9
+ getDir(start, end) {
10
+ const { neo4j } = this;
11
+ return neo4j.dirKey({
12
+ [neo4j.sourceField]: start,
13
+ [neo4j.targetField]: end
14
+ });
15
+ }
16
+ /**
17
+ * 设置多边间隔弧长
18
+ */
19
+ setRaidx(value) {
20
+ this.config.radOffsetRaidx = value;
21
+ }
22
+ /**
23
+ * 当图数据准备好后调用
24
+ */
25
+ read() {
26
+ const { neo4j } = this;
27
+ const { nodeField, edgeField, sourceField, targetField } = neo4j;
28
+ const anchors = {};
29
+ neo4j.nodes.forEach((node) => {
30
+ const nodeId = node[nodeField];
31
+ let count = 0;
32
+ [
33
+ neo4j.sources.get(nodeId),
34
+ neo4j.targets.get(nodeId)
35
+ ].forEach((list, i) => {
36
+ if (!list) return;
37
+ let diffCount = 0;
38
+ let sameCount = 0;
39
+ list.forEach((edge) => {
40
+ const edgeId = edge[edgeField];
41
+ if (edge[sourceField] !== edge[targetField]) {
42
+ const anchor = anchors[edgeId] || (anchors[edgeId] = {});
43
+ anchor[i ? "target" : "source"] = count + diffCount++;
44
+ } else if (edgeId in anchors === false) {
45
+ anchors[edgeId] = {
46
+ source: sameCount,
47
+ target: sameCount++
48
+ };
49
+ }
50
+ });
51
+ count += diffCount;
52
+ });
53
+ });
54
+ this.#anchors = anchors;
55
+ }
56
+ calcPoints(edge, index, total, type) {
57
+ const { neo4j, config: { getBox, radOffsetRaidx = 0.3125 } } = this;
58
+ const source = getBox(edge[neo4j.sourceField]);
59
+ const target = getBox(edge[neo4j.targetField]);
60
+ const rad = Math.atan2(
61
+ (source.centerY - target.centerY) * type,
62
+ (source.centerX - target.centerX) * type
63
+ );
64
+ let point = rotateRad([0.5, 0], rad);
65
+ if (total !== 1) {
66
+ point = rotateRad(point, radOffsetRaidx * (total / 2 - 0.5 - index));
67
+ }
68
+ const [x, y] = point;
69
+ return [x + 0.5, 0.5 - y];
70
+ }
71
+ /**
72
+ * 获取指定节点上出入边连接点的坐标
73
+ */
74
+ getPoints(id) {
75
+ const { neo4j } = this;
76
+ const { dirs, edgeField, sourceField, targetField } = neo4j;
77
+ const anchors = this.#anchors;
78
+ const points = [];
79
+ const caches = {};
80
+ neo4j.sources.get(id)?.forEach((edge) => {
81
+ const source = edge[sourceField];
82
+ const target = edge[targetField];
83
+ const direct = this.getDir(source, target);
84
+ const invert = this.getDir(target, source);
85
+ if (direct in caches) return;
86
+ const directs = dirs.get(direct) || [];
87
+ const inverts = dirs.get(invert) || [];
88
+ const directsLength = directs.length;
89
+ const invertsLength = inverts.length;
90
+ const total = directsLength + invertsLength;
91
+ directs.forEach((data, index) => {
92
+ points[anchors[data[edgeField]].source] = this.calcPoints(data, directsLength - 1 - index, total, -1);
93
+ });
94
+ caches[direct] = direct;
95
+ });
96
+ neo4j.targets.get(id)?.forEach((edge) => {
97
+ const source = edge[sourceField];
98
+ const target = edge[targetField];
99
+ const direct = this.getDir(source, target);
100
+ const invert = this.getDir(target, source);
101
+ if (direct in caches) return;
102
+ const directs = neo4j.dirs.get(direct) || [];
103
+ const inverts = neo4j.dirs.get(invert) || [];
104
+ const directsLength = directs.length;
105
+ const invertsLength = inverts.length;
106
+ const total = directsLength + invertsLength;
107
+ directs.forEach((data, index) => {
108
+ points[anchors[data[edgeField]].target] = this.calcPoints(data, invertsLength + index, total, 1);
109
+ });
110
+ caches[direct] = direct;
111
+ });
112
+ return points;
113
+ }
114
+ /**
115
+ * 查找边连接点的位置
116
+ */
117
+ findAnchor(id) {
118
+ const anchor = this.#anchors[id];
119
+ if (!anchor) return null;
120
+ return {
121
+ source: anchor.source || 0,
122
+ target: anchor.target || 0
123
+ };
124
+ }
125
+ /**
126
+ * 获取指定边控制点距离两端点连线的距离(可理解为控制边的弯曲程度)
127
+ * @description 返回值是一个相对值,需要乘以一个基数值(基数值应为负值,如-30)
128
+ */
129
+ getOffset(id) {
130
+ const { neo4j } = this;
131
+ const edge = neo4j.edges.get(id);
132
+ if (!edge) return -1;
133
+ const { dirs, edgeField, sourceField, targetField } = neo4j;
134
+ const source = edge[sourceField];
135
+ const target = edge[targetField];
136
+ const directs = dirs.get(this.getDir(source, target)) || [];
137
+ const inverts = dirs.get(this.getDir(target, source)) || [];
138
+ let count = 0;
139
+ let index = 0;
140
+ [directs, inverts].some((list) => {
141
+ const result = list.some((data, i) => {
142
+ if (data[edgeField] === id) {
143
+ index = i + count;
144
+ return true;
145
+ }
146
+ });
147
+ count += list.length;
148
+ return result;
149
+ });
150
+ const directsSize = directs.length;
151
+ const invertsSize = inverts.length;
152
+ const total = directsSize + invertsSize;
153
+ if (total === 1) return -1;
154
+ if (directsSize === 0 || invertsSize === 0) {
155
+ return total / 2 - index - 0.5;
156
+ } else {
157
+ return Math.abs(directsSize - invertsSize) * (directsSize >= invertsSize ? 1 : -1) / 2 - index - 0.5;
158
+ }
159
+ }
160
+ /**
161
+ * 清理数据
162
+ */
163
+ clear() {
164
+ this.#anchors = {};
165
+ }
166
+ }
167
+ export {
168
+ Neo4jAhchors as default
169
+ };
@@ -0,0 +1,82 @@
1
+ import { Equal } from '@type-challenges/utils';
2
+ import { GetGivenProps } from '@vope/types';
3
+ import { MemoryList } from './memory/list';
4
+ import { MemorySimple } from './memory/simple';
5
+ interface Config<INode extends object, IEdge extends object> {
6
+ /**
7
+ * 点主键字段
8
+ */
9
+ nid: Extract<GetGivenProps<INode, string>, string>;
10
+ /**
11
+ * 边主键字段
12
+ */
13
+ eid: Extract<GetGivenProps<IEdge, string>, string>;
14
+ /**
15
+ * (边)出点字段
16
+ */
17
+ sourceKey: Extract<GetGivenProps<IEdge, string>, string>;
18
+ /**
19
+ * (边)入点字段
20
+ */
21
+ targetKey: Extract<GetGivenProps<IEdge, string>, string>;
22
+ /**
23
+ * (边)方向键
24
+ */
25
+ dir?(edge: IEdge): string;
26
+ }
27
+ /**
28
+ * 图管理
29
+ */
30
+ export default class Neo4j<INode extends object, IEdge extends object> {
31
+ #private;
32
+ get nodeField(): keyof INode;
33
+ get edgeField(): keyof IEdge;
34
+ get sourceField(): keyof IEdge;
35
+ get targetField(): keyof IEdge;
36
+ get dirKey(): (edge: IEdge) => string;
37
+ /**
38
+ * 点视图
39
+ */
40
+ nodes: Shield<MemorySimple<INode, string>>;
41
+ /**
42
+ * 边视图
43
+ */
44
+ edges: Shield<MemorySimple<IEdge, string>>;
45
+ /**
46
+ * (边)出点视图
47
+ */
48
+ sources: Shield<MemoryList<IEdge, string>>;
49
+ /**
50
+ * (边)入点视图
51
+ */
52
+ targets: Shield<MemoryList<IEdge, string>>;
53
+ /**
54
+ * (边)方向视图
55
+ */
56
+ dirs: Shield<MemoryList<IEdge, string>>;
57
+ constructor(nodeList: INode[], edgeList: IEdge[], { nid, eid, sourceKey, targetKey, dir, }: Config<INode, IEdge>);
58
+ /**
59
+ * 点操作
60
+ */
61
+ node(type: 'add', value: INode): void;
62
+ node(type: 'delete', value: string): IEdge[];
63
+ /**
64
+ * 边操作
65
+ */
66
+ edge(type: 'add', value: IEdge): void;
67
+ edge(type: 'delete', value: string): boolean;
68
+ /**
69
+ * 清理图管理数据
70
+ */
71
+ clear(): void;
72
+ }
73
+ declare const shield_keys: {
74
+ push: number;
75
+ clear: number;
76
+ delete: number;
77
+ deleteType: number;
78
+ };
79
+ type Shield<T> = {
80
+ [P in Exclude<keyof T, keyof typeof shield_keys>]: T[P] extends (...args: infer A) => infer B ? Equal<[B], [T]> extends true ? (...args: A) => Shield<T> : T[P] : T[P];
81
+ };
82
+ export {};
package/dist/neo4j.mjs ADDED
@@ -0,0 +1,161 @@
1
+ import { hash8strings } from "./convert/strings";
2
+ import { MemoryList } from "./memory/list";
3
+ import { MemorySimple } from "./memory/simple";
4
+ class Neo4j {
5
+ #nPrimaryKey;
6
+ #ePrimaryKey;
7
+ #sourceKey;
8
+ #targetKey;
9
+ #dirKey;
10
+ #nodes;
11
+ #edges;
12
+ #sources;
13
+ #targets;
14
+ #dirs;
15
+ get nodeField() {
16
+ return this.#nPrimaryKey;
17
+ }
18
+ get edgeField() {
19
+ return this.#ePrimaryKey;
20
+ }
21
+ get sourceField() {
22
+ return this.#sourceKey;
23
+ }
24
+ get targetField() {
25
+ return this.#targetKey;
26
+ }
27
+ get dirKey() {
28
+ return this.#dirKey;
29
+ }
30
+ /**
31
+ * 点视图
32
+ */
33
+ nodes;
34
+ /**
35
+ * 边视图
36
+ */
37
+ edges;
38
+ /**
39
+ * (边)出点视图
40
+ */
41
+ sources;
42
+ /**
43
+ * (边)入点视图
44
+ */
45
+ targets;
46
+ /**
47
+ * (边)方向视图
48
+ */
49
+ dirs;
50
+ constructor(nodeList, edgeList, {
51
+ nid,
52
+ eid,
53
+ sourceKey,
54
+ targetKey,
55
+ dir = (edge) => edge[sourceKey] + "|" + edge[targetKey]
56
+ }) {
57
+ shield(this, "nodes", this.#nodes = new MemorySimple(this.#nPrimaryKey = nid));
58
+ shield(this, "edges", this.#edges = new MemorySimple(this.#ePrimaryKey = eid));
59
+ shield(this, "sources", this.#sources = new MemoryList(this.#sourceKey = sourceKey));
60
+ shield(this, "targets", this.#targets = new MemoryList(this.#targetKey = targetKey));
61
+ shield(this, "dirs", this.#dirs = new MemoryList(this.#dirKey = dir));
62
+ nodeList.forEach((node) => this.node("add", node));
63
+ edgeList.forEach((edge) => this.edge("add", edge));
64
+ }
65
+ node(type, value) {
66
+ const nodes = this.#nodes;
67
+ if (type === "add") {
68
+ nodes.push(value);
69
+ } else if (type === "delete") {
70
+ const node = nodes.get(value);
71
+ if (!node) return [];
72
+ nodes.delete(node);
73
+ const id = node[this.#nPrimaryKey];
74
+ const sourceKey = this.#sourceKey;
75
+ const targetKey = this.#targetKey;
76
+ const edges = this.#edges;
77
+ const sources = this.#sources;
78
+ const targets = this.#targets;
79
+ const dirs = this.#dirs;
80
+ const list = [];
81
+ sources.get(id)?.reduce((_, edge) => {
82
+ edges.delete(edge);
83
+ targets.delete(edge);
84
+ edge[sourceKey] === edge[targetKey] || dirs.delete(edge);
85
+ list.push(edge);
86
+ return true;
87
+ }, false) && sources.deleteType(id);
88
+ targets.get(id)?.reduce((_, edge) => {
89
+ edges.delete(edge);
90
+ sources.delete(edge);
91
+ edge[sourceKey] === edge[targetKey] || dirs.delete(edge);
92
+ list.push(edge);
93
+ return true;
94
+ }, false) && targets.deleteType(id);
95
+ return list;
96
+ }
97
+ }
98
+ edge(type, value) {
99
+ const sourceKey = this.#sourceKey;
100
+ const targetKey = this.#targetKey;
101
+ const edges = this.#edges;
102
+ const sources = this.#sources;
103
+ const targets = this.#targets;
104
+ const dirs = this.#dirs;
105
+ if (type === "add") {
106
+ const edge = value;
107
+ edges.push(edge);
108
+ sources.push(edge);
109
+ targets.push(edge);
110
+ edge[sourceKey] === edge[targetKey] || dirs.push(edge);
111
+ } else if (type === "delete") {
112
+ const edge = edges.get(value);
113
+ if (!edge) return false;
114
+ edges.delete(edge);
115
+ sources.delete(edge);
116
+ targets.delete(edge);
117
+ edge[sourceKey] === edge[targetKey] || dirs.delete(edge);
118
+ return true;
119
+ }
120
+ }
121
+ /**
122
+ * 清理图管理数据
123
+ */
124
+ clear() {
125
+ this.#nodes.clear();
126
+ this.#edges.clear();
127
+ this.#sources.clear();
128
+ this.#targets.clear();
129
+ this.#dirs.clear();
130
+ }
131
+ }
132
+ const shield_keys = hash8strings([
133
+ "push",
134
+ "delete",
135
+ "deleteType",
136
+ "clear"
137
+ ]);
138
+ const shield = (obj, key, origin) => {
139
+ const proxy = new Proxy({}, {
140
+ get(target, p) {
141
+ if (p in shield_keys) return;
142
+ const value = origin[p];
143
+ if (typeof value === "function") {
144
+ return function(...args) {
145
+ const result = origin[p](...args);
146
+ return result === origin ? proxy : result;
147
+ };
148
+ } else {
149
+ return value;
150
+ }
151
+ }
152
+ });
153
+ Object.defineProperty(obj, key, {
154
+ get() {
155
+ return proxy;
156
+ }
157
+ });
158
+ };
159
+ export {
160
+ Neo4j as default
161
+ };
package/dist/once.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 缓存函数返回值
3
+ * @param callback 运行返回值的函数
4
+ * @param thisArg 绑定到运行函数的this对象
5
+ */
6
+ export declare const once: <T extends (...args: any) => any>(func: T, thisArg?: any) => (...list: Parameters<T>) => ReturnType<T>;
package/dist/once.mjs ADDED
@@ -0,0 +1,8 @@
1
+ const once = (func, thisArg) => {
2
+ let local;
3
+ let inited = false;
4
+ return (...list) => inited ? local : (inited = true, local = func.apply(thisArg, list));
5
+ };
6
+ export {
7
+ once
8
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 解析一个字符串并返回一个数字
3
+ * @description 1、number最多支持16位小数
4
+ * @description 2、最终值为bigint则会把小数部分舍去
5
+ * @description 3、支持科学计数法形式的字符串
6
+ * @description 4、无法正确解析的值则会返回NaN
7
+ */
8
+ export declare const parseNum: (num: number | bigint | string) => number | bigint;
@@ -0,0 +1,31 @@
1
+ import { isNumber } from "lodash-es";
2
+ const pow = Math.floor(Math.log10(Number.MAX_SAFE_INTEGER));
3
+ const re_num = /^([-+]?)0*(\d+)(?:(n)|(?:\.(\d+))?(?:[Ee]([-+]?)(\d+))?)$/;
4
+ const parseNum = (num) => {
5
+ if (isNumber(num) || typeof num === "bigint") return num;
6
+ const match = num.match(re_num);
7
+ if (!match) return Number.NaN;
8
+ const [, valueSymbol, integer, bigint, decimal, powSymbol, powValue] = match;
9
+ if (bigint === "n") return BigInt(valueSymbol + integer);
10
+ const powSize = integer.length - 1 + (powValue ? powSymbol === "-" ? -powValue : +powValue : 0);
11
+ if (powSize < pow || powSize === pow && +integer.slice(0, -1) < Number.MAX_SAFE_INTEGER / 10) return +num;
12
+ try {
13
+ const bigValue = BigInt(integer.slice(0, powSize + 1).padEnd(powSize + 1, "0"));
14
+ let smallValue;
15
+ if (decimal && powValue && powSymbol !== "-") {
16
+ const powNum = +powValue;
17
+ const effectDecimal = decimal.slice(0, Math.min(pow, powNum));
18
+ const tinyValue = decimal.length > pow && powNum > pow ? BigInt(+decimal.slice(pow, powNum)) * BigInt(10 ** Math.max(powNum - decimal.length, 0)) : BigInt(0);
19
+ smallValue = BigInt(effectDecimal) * BigInt(10 ** (powNum - effectDecimal.length)) + tinyValue;
20
+ } else {
21
+ smallValue = BigInt(0);
22
+ }
23
+ const value = bigValue + smallValue;
24
+ return valueSymbol === "-" ? value * BigInt(-1) : value;
25
+ } catch {
26
+ return Number.NaN;
27
+ }
28
+ };
29
+ export {
30
+ parseNum
31
+ };
@@ -0,0 +1,9 @@
1
+ type Sort = 'asc' | 'desc';
2
+ /**
3
+ * 解构多个2的正整数幂(两两不相等)之和
4
+ * @param sum 幂和
5
+ * @param sort 排序方式(默认降序)
6
+ * @description sum > 2**53则会因为精度问题计算报错
7
+ */
8
+ export declare const deconPowersSum: (sum: number, sort?: Sort) => number[];
9
+ export {};
@@ -0,0 +1,22 @@
1
+ const ERROR_MESSAGE = {
2
+ INT: "\u53C2\u6570\u5FC5\u987B\u662F\u6574\u6570",
3
+ MIN: "\u591A\u4E2A2\u7684\u6B63\u6574\u6570\u5E42(\u4E24\u4E24\u4E0D\u76F8\u7B49)\u4E4B\u548C\u5FC5\u5B9A\u5927\u4E8E\u7B49\u4E8E1"
4
+ };
5
+ const deconPowersSum = (sum, sort) => {
6
+ if (sum < 1) {
7
+ throw new Error(ERROR_MESSAGE.MIN);
8
+ } else if (sum !== Math.floor(sum)) {
9
+ throw new Error(ERROR_MESSAGE.INT);
10
+ }
11
+ const list = [];
12
+ let cache = sum;
13
+ while (cache) {
14
+ const power = Math.log2(cache) ^ 0;
15
+ list.push(power);
16
+ cache -= Math.pow(2, power);
17
+ }
18
+ return sort === "asc" ? list.reverse() : list;
19
+ };
20
+ export {
21
+ deconPowersSum
22
+ };
@@ -0,0 +1,8 @@
1
+ import { Point2Tuple } from '@vope/types';
2
+ /**
3
+ * 返回点被旋转指定角度后新的位置
4
+ * @param from 旋转点
5
+ * @param angle 旋转角度
6
+ * @param visit 旋转原点
7
+ */
8
+ export declare const rotateAngle: (from: Point2Tuple, angle: number, visit?: Point2Tuple) => Point2Tuple;
@@ -0,0 +1,5 @@
1
+ import { rotateRad } from "./rad";
2
+ const rotateAngle = (from, angle, visit) => rotateRad(from, angle / 180 * Math.PI, visit);
3
+ export {
4
+ rotateAngle
5
+ };
@@ -0,0 +1,8 @@
1
+ import { Point2Tuple } from '@vope/types';
2
+ /**
3
+ * 返回点被旋转指定弧度后新的位置
4
+ * @param from 旋转点
5
+ * @param rad 旋转弧度
6
+ * @param visit 旋转原点
7
+ */
8
+ export declare const rotateRad: (from: Point2Tuple, rad: number, visit?: Point2Tuple) => Point2Tuple;
@@ -0,0 +1,11 @@
1
+ const rotateRad = (from, rad, visit = [0, 0]) => {
2
+ const x = from[0] - visit[0];
3
+ const y = from[1] - visit[1];
4
+ return [
5
+ x * Math.cos(rad) + y * Math.sin(rad) + visit[0],
6
+ y * Math.cos(rad) - x * Math.sin(rad) + visit[1]
7
+ ];
8
+ };
9
+ export {
10
+ rotateRad
11
+ };
@@ -0,0 +1,43 @@
1
+ import { Equal } from '@type-challenges/utils';
2
+ import { UnionToTuple } from '@vope/types';
3
+ type NativeMap = {
4
+ string: string;
5
+ boolean: boolean;
6
+ number: number;
7
+ bigint: bigint;
8
+ date: Date;
9
+ regexp: RegExp;
10
+ null: null;
11
+ };
12
+ type NativeValue = keyof NativeMap;
13
+ interface AccessorValue<T = any> {
14
+ cube(text: string): T;
15
+ flat(value: T): string;
16
+ }
17
+ type NativeUnion = UnionToTuple<{
18
+ [P in NativeValue]: [NativeMap[P], P];
19
+ }[NativeValue]>;
20
+ type Signal<T, U extends any[] = NativeUnion> = U extends [infer A1, ...infer A2] ? A1 extends [infer V, infer K] ? Equal<T, V> extends true ? K : Signal<T, A2> : Signal<T, A2> : never;
21
+ /**
22
+ * 转换套件类型
23
+ */
24
+ export type Serializes<T extends object> = {
25
+ [P in keyof T & string]: Signal<T[P]> | AccessorValue<T[P]>;
26
+ };
27
+ type Cube<T> = [T] extends [NativeValue] ? NativeMap[T] : [T] extends [AccessorValue<infer B>] ? B : never;
28
+ type Cubes<T extends object, S extends Serializes<T>> = {
29
+ [P in Extract<keyof T, keyof S> & string]: Cube<S[P]>;
30
+ };
31
+ /**
32
+ * 将URL查询参数转换成(复杂)对象
33
+ * @param text URL查询参数字符串
34
+ * @param serializes 转换套件
35
+ */
36
+ export declare const cubeURLParams: <T extends object, S extends Serializes<T>>(text: string, serializes: S) => Cubes<T, S>;
37
+ /**
38
+ * 将(复杂)对象转换成URL查询参数
39
+ * @param data 数据
40
+ * @param serializes 转换套件
41
+ */
42
+ export declare const flatURLParams: <T extends object, S extends Serializes<T>>(data: T, serializes: S) => string;
43
+ export {};
@@ -0,0 +1,53 @@
1
+ import { isString } from "lodash-es";
2
+ import { isKey } from "../is/key";
3
+ const cubes = {
4
+ string: (text) => text,
5
+ boolean: (text) => text === "true",
6
+ number: (text) => Number(text),
7
+ bigint: (text) => BigInt(text),
8
+ date: (text) => new Date(text),
9
+ regexp: (text) => new RegExp(text),
10
+ null: () => null
11
+ };
12
+ const flats = {
13
+ string: (data) => flatEncode(data),
14
+ boolean: (data) => `${data}`,
15
+ number: (data) => `${data}`,
16
+ bigint: (data) => `${data}`,
17
+ date: (data) => data.toJSON(),
18
+ regexp: (data) => flatEncode(data.source),
19
+ null: () => "null"
20
+ };
21
+ const cubeURLParams = (text, serializes) => {
22
+ const params = new URLSearchParams(text);
23
+ const result = {};
24
+ for (const [key, value] of params) {
25
+ const serialize = serializes[key];
26
+ if (!serialize) continue;
27
+ if (isString(serialize) && isKey(serialize, cubes)) {
28
+ result[key] = cubes[serialize](value);
29
+ } else {
30
+ result[key] = serialize.cube(value);
31
+ }
32
+ }
33
+ return result;
34
+ };
35
+ const re_flat = /\+/g;
36
+ const flatEncode = (text) => text.replace(re_flat, () => "%2B");
37
+ const flatURLParams = (data, serializes) => {
38
+ const params = new URLSearchParams();
39
+ for (const key in data) {
40
+ const value = data[key];
41
+ const serialize = serializes[key];
42
+ if (!serialize) continue;
43
+ params.append(
44
+ key,
45
+ isString(serialize) && isKey(serialize, flats) ? flats[serialize](value) : serialize.flat(value)
46
+ );
47
+ }
48
+ return params.toString();
49
+ };
50
+ export {
51
+ cubeURLParams,
52
+ flatURLParams
53
+ };
@@ -0,0 +1,51 @@
1
+ export interface ICrypto<From, To> {
2
+ encrypt(plain: From): To | Promise<To>;
3
+ decrypt(cipher: To): From | Promise<From>;
4
+ }
5
+ interface Options<From, To> {
6
+ /** 存储名称 */
7
+ name: string;
8
+ /** 存储认证 */
9
+ token?: string;
10
+ /** 存储期限 */
11
+ expire?: number;
12
+ /** 存储加密 */
13
+ crypto: ICrypto<From, To>;
14
+ }
15
+ /**
16
+ * 离线存储
17
+ */
18
+ export declare class OfflineStorage<From, To> {
19
+ #private;
20
+ get size(): number;
21
+ get mounted(): boolean;
22
+ constructor({ name, expire: newExpire, token: newToken, crypto, }: Options<From, To>);
23
+ ready(): Promise<this>;
24
+ /**
25
+ * 校验存储是否过期
26
+ */
27
+ validateExpire(): boolean;
28
+ /**
29
+ * 校验
30
+ */
31
+ validate(callback: (error?: Error) => void, expireMessage?: string): void;
32
+ /**
33
+ * 插入数据
34
+ */
35
+ push(data: From): Promise<number>;
36
+ /**
37
+ * 修改数据
38
+ */
39
+ update(index: number, data: From): Promise<boolean>;
40
+ /**
41
+ * 获取数据
42
+ */
43
+ get(index: number): Promise<From | null>;
44
+ /**
45
+ * 清理存储
46
+ */
47
+ clear(): Promise<void>;
48
+ static default<T>(options: string | Omit<Options<T, T>, 'crypto'>): OfflineStorage<T, T>;
49
+ static clear(token?: string, callback?: (name: string) => boolean): Promise<void>;
50
+ }
51
+ export {};