semantic-typescript 0.3.7 → 0.4.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/dist/hash.js ADDED
@@ -0,0 +1,211 @@
1
+ import { isBigInt, isBoolean, isFunction, isHashable, isNumber, isObject, isString, isSymbol } from "./guard";
2
+ import { useTraverse } from "./hook";
3
+ import { HashableSymbol } from "./symbol";
4
+ import { typeOf } from "./utility";
5
+ ;
6
+ const masks = new Map();
7
+ masks.set("undefined", BigInt(masks.size));
8
+ masks.set("null", BigInt(masks.size));
9
+ masks.set("boolean", BigInt(masks.size));
10
+ masks.set("number", BigInt(masks.size));
11
+ masks.set("bigint", BigInt(masks.size));
12
+ masks.set("symbol", BigInt(masks.size));
13
+ masks.set("string", BigInt(masks.size));
14
+ masks.set("function", BigInt(masks.size));
15
+ masks.set("object", BigInt(masks.size));
16
+ Object.freeze(masks);
17
+ const internal = Object.freeze(Array.from(masks.keys()));
18
+ export let maskOf = (type) => {
19
+ return masks.get(type) || masks.get("object") || 0n;
20
+ };
21
+ let primitive = new Map();
22
+ let complex = new WeakMap();
23
+ const handlers = new Map();
24
+ export let register = (type, handler) => {
25
+ if (isString(type) && isFunction(handler)) {
26
+ handlers.set(type, handler);
27
+ }
28
+ };
29
+ export let unregister = (type) => {
30
+ if (isString(type) && handlers.has(type) && !internal.includes(type)) {
31
+ handlers.delete(type);
32
+ }
33
+ };
34
+ register("undefined", (value) => {
35
+ if (value === (void 0)) {
36
+ if (primitive.has(value)) {
37
+ return primitive.get(value) || 0n;
38
+ }
39
+ let mask = maskOf("undefined");
40
+ let result = (0n << 4n) | mask;
41
+ primitive.set(value, result);
42
+ return result;
43
+ }
44
+ return 0n;
45
+ });
46
+ register("null", (value) => {
47
+ if (value === null) {
48
+ if (primitive.has(value)) {
49
+ return primitive.get(value) || 0n;
50
+ }
51
+ let mask = maskOf("null");
52
+ let result = (0n << 4n) | mask;
53
+ primitive.set(value, result);
54
+ return result;
55
+ }
56
+ return 0n;
57
+ });
58
+ register("boolean", (value) => {
59
+ if (isBoolean(value)) {
60
+ if (primitive.has(value)) {
61
+ return primitive.get(value) || 0n;
62
+ }
63
+ let mask = maskOf("boolean");
64
+ let result = ((value === true ? 1n : 0n) << 4n) | mask;
65
+ primitive.set(value, result);
66
+ return result;
67
+ }
68
+ return 0n;
69
+ });
70
+ register("number", (value) => {
71
+ if (isNumber(value)) {
72
+ if (primitive.has(value)) {
73
+ return primitive.get(value) || 0n;
74
+ }
75
+ let mask = maskOf("number");
76
+ let bit = 0xffffffffffffffffn;
77
+ let buffer = new ArrayBuffer(8);
78
+ let array = new Float64Array(buffer);
79
+ array[0] = value;
80
+ let view = new BigInt64Array(buffer);
81
+ let result = ((view[0] << 4n) & bit) | mask;
82
+ primitive.set(value, result);
83
+ return result;
84
+ }
85
+ return 0n;
86
+ });
87
+ register("bigint", (value) => {
88
+ if (isBigInt(value)) {
89
+ if (primitive.has(value)) {
90
+ return primitive.get(value) || 0n;
91
+ }
92
+ let mask = maskOf("bigint");
93
+ let bit = 0xffffffffffffffffn;
94
+ let result = ((value << 4n) & bit) | mask;
95
+ primitive.set(value, result);
96
+ return result;
97
+ }
98
+ return 0n;
99
+ });
100
+ register("string", (value) => {
101
+ if (isString(value)) {
102
+ if (primitive.has(value)) {
103
+ return primitive.get(value) || 0n;
104
+ }
105
+ let mask = maskOf("string");
106
+ let bit = 0xffffffffffffffffn;
107
+ let gap = value.length < 64 ? 1 : Math.ceil(Math.log2(value.length));
108
+ let result = 0n;
109
+ for (let i = 0; i < value.length; i += gap) {
110
+ result = (((result * 33n) & bit) ^ BigInt(value.charCodeAt(i))) + BigInt(i);
111
+ }
112
+ result = (result ^ (result >> 32n)) * 0x9e3779b97f4a7c15n;
113
+ result = (((result ^ (result >> 32n)) << 4n) & bit) | mask;
114
+ primitive.set(value, result);
115
+ return result;
116
+ }
117
+ return 0n;
118
+ });
119
+ register("symbol", (value) => {
120
+ if (isSymbol(value)) {
121
+ if (primitive.has(value)) {
122
+ return primitive.get(value) || 0n;
123
+ }
124
+ let mask = maskOf("symbol");
125
+ let bit = 0xffffffffffffffffn;
126
+ let description = (value.description || "") + String(value);
127
+ let result = 0n;
128
+ let gap = description.length < 64 ? 1 : Math.ceil(Math.log2(description.length));
129
+ for (let i = 0; i < description.length; i += gap) {
130
+ result = (((result * 33n) & bit) ^ BigInt(description.charCodeAt(i))) + BigInt(i);
131
+ }
132
+ result = (result ^ (result >> 32n)) * 0x9e3779b97f4a7c15n;
133
+ result = (((result ^ (result >> 32n)) << 4n) & bit) | mask;
134
+ primitive.set(value, result);
135
+ return result;
136
+ }
137
+ return 0n;
138
+ });
139
+ register("function", (value) => {
140
+ if (isFunction(value)) {
141
+ if (primitive.has(value)) {
142
+ return primitive.get(value) || 0n;
143
+ }
144
+ let mask = maskOf("function");
145
+ let bit = 0xffffffffffffffffn;
146
+ let description = (value.name || "") + String(value);
147
+ let result = 0n;
148
+ let gap = description.length < 64 ? 1 : Math.ceil(Math.log2(description.length));
149
+ for (let i = 0; i < description.length; i += gap) {
150
+ result = (((result * 33n) & bit) ^ BigInt(description.charCodeAt(i))) + BigInt(i);
151
+ }
152
+ result = (result ^ (result >> 32n)) * 0x9e3779b97f4a7c15n;
153
+ result = (((result ^ (result >> 32n)) << 4n) & bit) | mask;
154
+ primitive.set(value, result);
155
+ return result;
156
+ }
157
+ return 0n;
158
+ });
159
+ register("object", (value) => {
160
+ if (isObject(value)) {
161
+ if (complex.has(value)) {
162
+ return complex.get(value) || 0n;
163
+ }
164
+ try {
165
+ let mask = maskOf("object");
166
+ let bit = 0xffffffffffffffffn;
167
+ let result = 0n;
168
+ useTraverse(value, (key, value, path) => {
169
+ let keyHashHandler = handlers.get(typeOf(key));
170
+ let keyHash = keyHashHandler ? keyHashHandler(key) : 0n;
171
+ let valueHashHandler = handlers.get(typeOf(value));
172
+ let valueHash = valueHashHandler ? valueHashHandler(value) : 0n;
173
+ let pathHash = 0n;
174
+ if (complex.has(path)) {
175
+ pathHash = complex.get(path) || 0n;
176
+ }
177
+ else {
178
+ for (let p of path) {
179
+ let pathHashHandler = handlers.get(typeOf(p));
180
+ pathHash = (((pathHash << 5n) - pathHash) ^ (pathHashHandler ? pathHashHandler(p) : 0n)) & bit;
181
+ }
182
+ complex.set(path, pathHash);
183
+ }
184
+ result = (((result << 13n) | (result >> 51n)) ^ (keyHash * 0x243f6a8885a308d3n) ^ (valueHash * 0x517cc1b727220a95n) ^ (pathHash * 0x9e3779b97f4a7c15n)) & bit;
185
+ return true;
186
+ });
187
+ result = (result ^ (result >> 32n)) * 0x9e3779b97f4a7c15n;
188
+ result = (((result ^ (result >> 32n)) << 4n) & bit) | mask;
189
+ complex.set(value, result);
190
+ return result;
191
+ }
192
+ catch (error) {
193
+ throw new Error("Uncaught error on hashing object.");
194
+ }
195
+ }
196
+ return 0n;
197
+ });
198
+ ;
199
+ export let useHash = (target) => {
200
+ let type = typeOf(target);
201
+ if (type === "object" && isHashable(target)) {
202
+ if (complex.has(target)) {
203
+ return complex.get(target) || 0n;
204
+ }
205
+ let hash = Reflect.get(target, HashableSymbol)();
206
+ complex.set(target, hash);
207
+ return hash;
208
+ }
209
+ let handler = handlers.get(type) || (() => 0n);
210
+ return handler(target);
211
+ };
package/dist/hook.d.ts CHANGED
@@ -1,8 +1,21 @@
1
- import { type BiPredicate, type DeepPropertyKey, type DeepPropertyValue } from "./utility";
1
+ import { type DeepPropertyKey, type DeepPropertyValue } from "./utility";
2
2
  import type { Comparator, Generator } from "./utility";
3
3
  export declare let useCompare: <T>(t1: T, t2: T) => number;
4
- export declare let useRandom: <T = number | bigint>(index: T) => T;
5
- export declare let useTraverse: <T extends object>(t: T, callback: BiPredicate<DeepPropertyKey<T>, DeepPropertyValue<T>>) => void;
4
+ export declare let Useandom: <T = number | bigint>(index: T) => T;
5
+ export type UseTraverseKey<T extends object> = DeepPropertyKey<T> & (symbol | string | number);
6
+ export type UseTraverseValue<T extends object> = DeepPropertyValue<T>;
7
+ export type UseTraversePath<T extends object> = Array<UseTraverseKey<T> & (symbol | string | number)>;
8
+ export interface UseTraverseCallback<T extends object> {
9
+ (key: UseTraverseKey<T>, value: UseTraverseValue<T>): boolean;
10
+ }
11
+ export interface UseTraversePathCallback<T extends object> {
12
+ (key: UseTraverseKey<T>, value: UseTraverseValue<T>, path: UseTraversePath<T>): boolean;
13
+ }
14
+ interface UseTraverse {
15
+ <T extends object>(t: T, callback: UseTraverseCallback<T>): void;
16
+ <T extends object>(t: T, callback: UseTraversePathCallback<T>): void;
17
+ }
18
+ export declare let useTraverse: UseTraverse;
6
19
  export declare let useGenerator: <E>(iterable: Iterable<E>) => Generator<E>;
7
20
  interface UseArrange {
8
21
  <E>(source: Iterable<E>): Generator<E>;
package/dist/hook.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useToArray } from "./collector";
2
2
  import { isBigInt, isFunction, isIterable, isNumber, isObject, isPrimitive } from "./guard";
3
- import { validate } from "./utility";
3
+ import { invalidate, validate } from "./utility";
4
4
  export let useCompare = (t1, t2) => {
5
5
  if (t1 === t2 || Object.is(t1, t2)) {
6
6
  return 0;
@@ -16,7 +16,10 @@ export let useCompare = (t1, t2) => {
16
16
  case "boolean":
17
17
  return t1 === t2 ? 0 : (t1 ? 1 : -1);
18
18
  case "symbol":
19
- return Object.prototype.toString.call(t1).localeCompare(Object.prototype.toString.call(t2));
19
+ if (t1.description === t2.description) {
20
+ return 0;
21
+ }
22
+ return (t1.description || "").localeCompare((t2.description) || "");
20
23
  case "function":
21
24
  throw new TypeError("Cannot compare functions.");
22
25
  case "undefined":
@@ -41,7 +44,7 @@ export let useCompare = (t1, t2) => {
41
44
  }
42
45
  throw new TypeError("Cannot compare values of different types.");
43
46
  };
44
- export let useRandom = (index) => {
47
+ export let Useandom = (index) => {
45
48
  if (isNumber(index)) {
46
49
  let x = Number(index);
47
50
  let phi = (1 + Math.sqrt(5)) / 2;
@@ -64,15 +67,20 @@ export let useRandom = (index) => {
64
67
  }
65
68
  throw new TypeError("Invalid input type");
66
69
  };
70
+ ;
71
+ ;
72
+ ;
67
73
  export let useTraverse = (t, callback) => {
68
74
  if (isObject(t)) {
69
75
  let seen = new WeakSet();
76
+ let path = [];
70
77
  let traverse = (target) => {
71
78
  if (!seen.has(target)) {
72
79
  seen.add(target);
73
80
  let stop = false;
74
81
  let properties = Reflect.ownKeys(target);
75
82
  for (let property of properties) {
83
+ path.push(property);
76
84
  let value = Reflect.get(target, property);
77
85
  if (stop) {
78
86
  break;
@@ -82,12 +90,13 @@ export let useTraverse = (t, callback) => {
82
90
  if (isIterable(value)) {
83
91
  let index = 0;
84
92
  for (let item of value) {
93
+ path.push(index);
85
94
  if (validate(item)) {
86
95
  if (isObject(item)) {
87
96
  traverse(item);
88
97
  }
89
98
  else {
90
- if (!callback(index, item)) {
99
+ if (!callback(index, item, path)) {
91
100
  stop = true;
92
101
  break;
93
102
  }
@@ -96,9 +105,12 @@ export let useTraverse = (t, callback) => {
96
105
  index++;
97
106
  }
98
107
  }
108
+ else {
109
+ traverse(value);
110
+ }
99
111
  }
100
112
  else {
101
- if (!callback(property, value)) {
113
+ if (!callback(property, value, path)) {
102
114
  stop = true;
103
115
  break;
104
116
  }
@@ -166,15 +178,50 @@ export let useArrange = (source, comparator) => {
166
178
  return useGenerator([]);
167
179
  };
168
180
  export let useToNumber = (target) => {
169
- if (isNumber(target)) {
170
- return target;
181
+ switch (typeof target) {
182
+ case "number":
183
+ return isNumber(target) ? target : 0;
184
+ case "boolean":
185
+ return target ? 1 : 0;
186
+ case "string":
187
+ let result = Number(target);
188
+ return isNumber(result) ? result : 0;
189
+ case "bigint":
190
+ return Number(target);
191
+ case "object":
192
+ if (invalidate(target)) {
193
+ return 0;
194
+ }
195
+ if (Reflect.has(target, Symbol.toPrimitive)) {
196
+ let resolved = Reflect.apply(Reflect.get(target, Symbol.toPrimitive), target, ["default"]);
197
+ return isNumber(resolved) ? resolved : 0;
198
+ }
199
+ return 0;
200
+ default:
201
+ return 0;
171
202
  }
172
- let resolved = Reflect.apply(Reflect.get(target, Symbol.toPrimitive), target, ["default"]);
173
- return isNumber(resolved) ? resolved : 0;
174
203
  };
175
204
  export let useToBigInt = (target) => {
176
- if (isBigInt(target)) {
177
- return target;
205
+ switch (typeof target) {
206
+ case "number":
207
+ return isNumber(target) ? BigInt(target) : 0n;
208
+ case "boolean":
209
+ return target ? 1n : 0n;
210
+ case "string":
211
+ let regex = /^[-+]?\d+$/;
212
+ return regex.test(target) ? BigInt(target) : 0n;
213
+ case "bigint":
214
+ return target;
215
+ case "object":
216
+ if (invalidate(target)) {
217
+ return 0n;
218
+ }
219
+ if (Reflect.has(target, Symbol.toPrimitive)) {
220
+ let resolved = Reflect.apply(Reflect.get(target, Symbol.toPrimitive), target, ["default"]);
221
+ return isBigInt(resolved) ? resolved : 0n;
222
+ }
223
+ return 0n;
224
+ default:
225
+ return 0n;
178
226
  }
179
- return BigInt(useToNumber(target));
180
227
  };
package/dist/index.d.ts CHANGED
@@ -2,9 +2,12 @@ export * from "./collectable";
2
2
  export * from "./collector";
3
3
  export * from "./factory";
4
4
  export * from "./guard";
5
+ export * from "./hash";
5
6
  export * from "./hook";
7
+ export * from "./map";
6
8
  export * from "./optional";
7
9
  export * from "./semantic";
10
+ export * from "./set";
8
11
  export * from "./symbol";
9
12
  export * from "./statistics";
10
13
  export * from "./utility";
package/dist/index.js CHANGED
@@ -2,9 +2,12 @@ export * from "./collectable";
2
2
  export * from "./collector";
3
3
  export * from "./factory";
4
4
  export * from "./guard";
5
+ export * from "./hash";
5
6
  export * from "./hook";
7
+ export * from "./map";
6
8
  export * from "./optional";
7
9
  export * from "./semantic";
10
+ export * from "./set";
8
11
  export * from "./symbol";
9
12
  export * from "./statistics";
10
13
  export * from "./utility";
package/dist/map.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ import { type BiConsumer, type BiFunctional, type Comparator, type MaybeInvalid, type MaybeUndefined, type Supplier, type TriConsumer } from "./utility";
2
+ export interface Entry<K, V> {
3
+ key: K;
4
+ value: V;
5
+ }
6
+ export interface SemanticMap<K, V> extends globalThis.Map<K, V> {
7
+ clear(): void;
8
+ compute(key: K, remapping: BiFunctional<K, MaybeInvalid<V>, MaybeInvalid<V>>): MaybeInvalid<V>;
9
+ computeIfAbsent(key: K, remapping: Supplier<V>): V;
10
+ computeIfPresent(key: K, remapping: BiFunctional<K, V, MaybeInvalid<V>>): MaybeInvalid<V>;
11
+ delete(key: K): boolean;
12
+ entries(): MapIterator<[K, V]>;
13
+ forEach(consumer: BiConsumer<V, K>): void;
14
+ forEach(consumer: TriConsumer<V, K, Map<K, V>>): void;
15
+ get(key: K): MaybeUndefined<V>;
16
+ get(key: K, defaultValue: V): V;
17
+ has(key: K): boolean;
18
+ replace(key: K, value: V): MaybeInvalid<V>;
19
+ replace(key: K, oldValue: V, newValue: V): boolean;
20
+ replaceAll(operator: BiFunctional<K, V, MaybeInvalid<V>>): void;
21
+ set(key: K, value: V): this;
22
+ size: number;
23
+ values(): IterableIterator<V>;
24
+ }
25
+ export declare abstract class AbstractSemanticMap<K, V> implements SemanticMap<K, V> {
26
+ protected internal: bigint;
27
+ size: number;
28
+ protected readonly SemanticMap: symbol;
29
+ constructor();
30
+ abstract clear(): void;
31
+ compute(key: K, remapping: BiFunctional<K, MaybeInvalid<V>, MaybeInvalid<V>>): MaybeInvalid<V>;
32
+ computeIfAbsent(key: K, remapping: Supplier<V>): V;
33
+ computeIfPresent(key: K, remapping: BiFunctional<K, V, MaybeInvalid<V>>): MaybeInvalid<V>;
34
+ abstract delete(key: K): boolean;
35
+ abstract entries(): MapIterator<[K, V]>;
36
+ forEach(consumer: BiConsumer<V, K>): void;
37
+ forEach(consumer: TriConsumer<V, K, Map<K, V>>): void;
38
+ abstract get(key: K): MaybeUndefined<V>;
39
+ abstract get(key: K, defaultValue: V): V;
40
+ abstract keys(): MapIterator<K>;
41
+ has(key: K): boolean;
42
+ replace(key: K, value: V): MaybeInvalid<V>;
43
+ replace(key: K, oldValue: V, newValue: V): boolean;
44
+ replaceAll(operator: BiFunctional<K, V, MaybeInvalid<V>>): void;
45
+ abstract set(key: K, value: V): this;
46
+ [Symbol.iterator](): IterableIterator<[K, V]>;
47
+ [Symbol.toStringTag]: string;
48
+ abstract values(): IterableIterator<V>;
49
+ }
50
+ export declare class HashMap<K, V> extends AbstractSemanticMap<K, V> {
51
+ protected buckets: Map<bigint, Array<Entry<K, V>>>;
52
+ protected threashold: number;
53
+ protected comparator: Comparator<K>;
54
+ protected capacity: number;
55
+ protected readonly HashMap: symbol;
56
+ constructor();
57
+ constructor(comparator: Comparator<K>);
58
+ constructor(threashold: number, initialCapacity: number);
59
+ constructor(comparator: Comparator<K>, threashold: number, capacity: number);
60
+ clear(): void;
61
+ delete(key: K): boolean;
62
+ entries(): MapIterator<[K, V]>;
63
+ has(key: K): boolean;
64
+ protected hash(key: K): bigint;
65
+ protected findEntry(key: K, hash: bigint): MaybeInvalid<Entry<K, V>>;
66
+ get(key: K): MaybeUndefined<V>;
67
+ get(key: K, defaultValue: V): V;
68
+ keys(): MapIterator<K>;
69
+ protected rehash(): void;
70
+ set(key: K, value: V): this;
71
+ values(): IterableIterator<V>;
72
+ }