@adaas/a-utils 0.3.6 → 0.3.7
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/.conf/tsconfig.browser.json +4 -1
- package/.conf/tsconfig.node.json +5 -2
- package/dist/browser/a-signal.d.mts +19 -23
- package/dist/browser/a-signal.mjs +36 -60
- package/dist/browser/a-signal.mjs.map +1 -1
- package/dist/browser/chunk-S2RSPZXR.mjs +143 -0
- package/dist/browser/chunk-S2RSPZXR.mjs.map +1 -0
- package/dist/browser/helpers.d.mts +56 -0
- package/dist/browser/helpers.mjs +5 -0
- package/dist/browser/helpers.mjs.map +1 -0
- package/dist/node/{A-Signal.types-C0Ta5Unp.d.mts → A-Signal.types-DxQHmPm6.d.mts} +19 -23
- package/dist/node/{A-Signal.types-C0Ta5Unp.d.ts → A-Signal.types-DxQHmPm6.d.ts} +19 -23
- package/dist/node/helpers/A-Utils.helper.d.mts +56 -0
- package/dist/node/helpers/A-Utils.helper.d.ts +56 -0
- package/dist/node/helpers/A-Utils.helper.js +153 -0
- package/dist/node/helpers/A-Utils.helper.js.map +1 -0
- package/dist/node/helpers/A-Utils.helper.mjs +143 -0
- package/dist/node/helpers/A-Utils.helper.mjs.map +1 -0
- package/dist/node/helpers/index.d.mts +3 -0
- package/dist/node/helpers/index.d.ts +3 -0
- package/dist/node/helpers/index.js +12 -0
- package/dist/node/helpers/index.js.map +1 -0
- package/dist/node/helpers/index.mjs +4 -0
- package/dist/node/helpers/index.mjs.map +1 -0
- package/dist/node/lib/A-Signal/A-Signal.types.d.mts +1 -1
- package/dist/node/lib/A-Signal/A-Signal.types.d.ts +1 -1
- package/dist/node/lib/A-Signal/components/A-SignalBus.component.d.mts +1 -1
- package/dist/node/lib/A-Signal/components/A-SignalBus.component.d.ts +1 -1
- package/dist/node/lib/A-Signal/context/A-SignalConfig.context.d.mts +1 -1
- package/dist/node/lib/A-Signal/context/A-SignalConfig.context.d.ts +1 -1
- package/dist/node/lib/A-Signal/context/A-SignalState.context.d.mts +1 -1
- package/dist/node/lib/A-Signal/context/A-SignalState.context.d.ts +1 -1
- package/dist/node/lib/A-Signal/entities/A-Signal.entity.d.mts +1 -1
- package/dist/node/lib/A-Signal/entities/A-Signal.entity.d.ts +1 -1
- package/dist/node/lib/A-Signal/entities/A-Signal.entity.js +35 -59
- package/dist/node/lib/A-Signal/entities/A-Signal.entity.js.map +1 -1
- package/dist/node/lib/A-Signal/entities/A-Signal.entity.mjs +35 -59
- package/dist/node/lib/A-Signal/entities/A-Signal.entity.mjs.map +1 -1
- package/dist/node/lib/A-Signal/entities/A-SignalVector.entity.d.mts +1 -1
- package/dist/node/lib/A-Signal/entities/A-SignalVector.entity.d.ts +1 -1
- package/dist/node/lib/A-Signal/entities/A-SignalVector.entity.js +1 -1
- package/dist/node/lib/A-Signal/entities/A-SignalVector.entity.js.map +1 -1
- package/dist/node/lib/A-Signal/entities/A-SignalVector.entity.mjs +1 -1
- package/dist/node/lib/A-Signal/entities/A-SignalVector.entity.mjs.map +1 -1
- package/dist/node/lib/A-Signal/index.d.mts +1 -1
- package/dist/node/lib/A-Signal/index.d.ts +1 -1
- package/jest.config.ts +3 -1
- package/package.json +17 -1
- package/src/helpers/A-Utils.helper.ts +186 -0
- package/src/helpers/index.ts +1 -0
- package/src/lib/A-Signal/entities/A-Signal.entity.ts +38 -79
- package/src/lib/A-Signal/entities/A-SignalVector.entity.ts +1 -1
- package/tests/A-Signal.test.ts +8 -4
- package/tsconfig.json +4 -1
- package/tsup.config.ts +2 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/A-Utils.helper.ts"],"names":[],"mappings":"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","file":"chunk-S2RSPZXR.mjs","sourcesContent":["import { A_Caller, A_Component, A_Feature, A_Inject } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame\";\nimport { A_ExecutionContext } from \"@adaas/a-utils/a-execution\";\n\n\n\n@A_Frame.Component({\n namespace: 'A-Utils',\n name: 'A-UtilsHelper',\n description: 'Utility helper class providing common functions for A-Utils library, such as hashing and serialization.'\n})\nexport class A_UtilsHelper extends A_Component {\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── Hashing ──────────────────────────────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Produces a deterministic, collision-resistant hash string for any JS value.\n * \n * Improvements over the legacy `createHash`:\n * - **Null-safe** — handles `null` without throwing \n * - **Function-aware serialization** — functions inside objects / arrays are\n * serialized via `.toString()` so `{ fn: () => 1 }` ≠ `{}` \n * - **FNV-1a 52-bit** — better avalanche / distribution than DJB2-32,\n * and uses the safe JS integer range so the result is always positive \n * - **Hex output** — compact, URL-safe, fixed-width (13 chars)\n * \n * @param value Any value: string, number, boolean, null, undefined,\n * object, array, Map, Set, function, or a mix of these.\n * @returns A 13-character lower-hex string (52-bit FNV-1a).\n */\n static hash(value?: any): string {\n const source = A_UtilsHelper.serialize(value);\n return A_UtilsHelper.fnv1a52(source);\n }\n\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── Serialization ────────────────────────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Converts any JS value into a deterministic string representation\n * suitable for hashing.\n * \n * Key properties:\n * - **Deterministic**: same logical value → same string every time\n * - **Injective-ish**: structurally different values produce different\n * strings (type tags prevent `\"3\"` vs `3` collisions)\n * - **Recursive**: handles nested objects, arrays, Maps, Sets\n * - **Function-aware**: serializes functions via `.toString()`\n * \n * @param value Anything.\n * @returns A deterministic string.\n */\n static serialize(value: any): string {\n // Primitives & null/undefined\n if (value === null) return '<null>';\n if (value === undefined) return '<undefined>';\n\n switch (typeof value) {\n case 'string':\n return `s:${value}`;\n case 'number':\n return `n:${value}`;\n case 'boolean':\n return `b:${value}`;\n case 'bigint':\n return `bi:${value}`;\n case 'symbol':\n return `sym:${value.toString()}`;\n case 'function':\n return `fn:${value.toString()}`;\n }\n\n // Map\n if (value instanceof Map) {\n const entries = Array.from(value.entries())\n .map(([k, v]) => `${A_UtilsHelper.serialize(k)}=>${A_UtilsHelper.serialize(v)}`)\n .sort()\n .join(',');\n return `Map{${entries}}`;\n }\n\n // Set\n if (value instanceof Set) {\n const items = Array.from(value.values())\n .map(v => A_UtilsHelper.serialize(v))\n .sort()\n .join(',');\n return `Set{${items}}`;\n }\n\n // Date\n if (value instanceof Date) {\n return `Date:${value.toISOString()}`;\n }\n\n // RegExp\n if (value instanceof RegExp) {\n return `RegExp:${value.toString()}`;\n }\n\n // Array\n if (Array.isArray(value)) {\n const items = value.map(v => A_UtilsHelper.serialize(v)).join(',');\n return `[${items}]`;\n }\n\n // toJSON support (e.g. custom entities, ASEID, etc.)\n if (typeof value.toJSON === 'function') {\n return `json:${A_UtilsHelper.serialize(value.toJSON())}`;\n }\n\n // Plain object — sort keys for determinism, serialize functions too\n const keys = Object.keys(value).sort();\n const pairs = keys.map(k => `${k}:${A_UtilsHelper.serialize(value[k])}`).join(',');\n return `{${pairs}}`;\n }\n\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── FNV-1a (pure Number, no BigInt) ──────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * FNV-1a hash using two 32-bit halves to simulate a 52-bit space,\n * without requiring BigInt.\n * \n * Works identically in:\n * - All browsers (including Safari 13, IE11 polyfill targets, React Native)\n * - Node.js (any version)\n * - Web Workers, Service Workers, Deno, Bun\n * \n * - Better avalanche than DJB2 (each input bit affects many output bits)\n * - ~52-bit effective space — vastly fewer collisions than 32-bit\n * - Always produces a **positive** hex string of 13 characters\n * \n * @param input Pre-serialized string.\n * @returns 13-character lower-hex string.\n */\n private static fnv1a52(input: string): string {\n // FNV-1a offset basis split into two 32-bit halves\n let h1 = 0x811c9dc5; // low 32 bits\n let h2 = 0x00000842; // high 20 bits (keeps us in 52-bit range)\n\n // FNV prime = 0x01000193\n const PRIME = 0x01000193;\n\n for (let i = 0; i < input.length; i++) {\n h1 ^= input.charCodeAt(i);\n\n // Multiply h1 by prime (32-bit, unsigned)\n const product = Math.imul(h1, PRIME);\n h1 = product >>> 0;\n\n // Carry overflow into h2, keep h2 within 20 bits\n h2 = ((Math.imul(h2, PRIME) + (product / 0x100000000 >>> 0)) & 0xFFFFF) >>> 0;\n }\n\n // Combine: h2 (20 bits) << 32 | h1 (32 bits) → 52-bit number\n // Since 2^52 fits in Number.MAX_SAFE_INTEGER, this is exact.\n const combined = h2 * 0x100000000 + h1;\n\n return combined.toString(16).padStart(13, '0');\n }\n\n\n\n // ==============================================================================\n // =============== Instance methods for used for Injection ======================\n // ==============================================================================\n @A_Frame.Method({\n description: 'Instance method wrapper for the static hash function, allowing it to be injected as a dependency.'\n })\n hash(\n @A_Inject(A_Caller) caller: any,\n @A_Inject(A_ExecutionContext) context: A_ExecutionContext,\n @A_Inject(A_Feature) feature: A_Feature\n ) {\n const hash = A_UtilsHelper.hash(caller);\n\n context.set(feature.name, hash);\n }\n}"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { A_Component, A_Feature } from '@adaas/a-concept';
|
|
2
|
+
import { A_ExecutionContext } from './a-execution.mjs';
|
|
3
|
+
|
|
4
|
+
declare class A_UtilsHelper extends A_Component {
|
|
5
|
+
/**
|
|
6
|
+
* Produces a deterministic, collision-resistant hash string for any JS value.
|
|
7
|
+
*
|
|
8
|
+
* Improvements over the legacy `createHash`:
|
|
9
|
+
* - **Null-safe** — handles `null` without throwing
|
|
10
|
+
* - **Function-aware serialization** — functions inside objects / arrays are
|
|
11
|
+
* serialized via `.toString()` so `{ fn: () => 1 }` ≠ `{}`
|
|
12
|
+
* - **FNV-1a 52-bit** — better avalanche / distribution than DJB2-32,
|
|
13
|
+
* and uses the safe JS integer range so the result is always positive
|
|
14
|
+
* - **Hex output** — compact, URL-safe, fixed-width (13 chars)
|
|
15
|
+
*
|
|
16
|
+
* @param value Any value: string, number, boolean, null, undefined,
|
|
17
|
+
* object, array, Map, Set, function, or a mix of these.
|
|
18
|
+
* @returns A 13-character lower-hex string (52-bit FNV-1a).
|
|
19
|
+
*/
|
|
20
|
+
static hash(value?: any): string;
|
|
21
|
+
/**
|
|
22
|
+
* Converts any JS value into a deterministic string representation
|
|
23
|
+
* suitable for hashing.
|
|
24
|
+
*
|
|
25
|
+
* Key properties:
|
|
26
|
+
* - **Deterministic**: same logical value → same string every time
|
|
27
|
+
* - **Injective-ish**: structurally different values produce different
|
|
28
|
+
* strings (type tags prevent `"3"` vs `3` collisions)
|
|
29
|
+
* - **Recursive**: handles nested objects, arrays, Maps, Sets
|
|
30
|
+
* - **Function-aware**: serializes functions via `.toString()`
|
|
31
|
+
*
|
|
32
|
+
* @param value Anything.
|
|
33
|
+
* @returns A deterministic string.
|
|
34
|
+
*/
|
|
35
|
+
static serialize(value: any): string;
|
|
36
|
+
/**
|
|
37
|
+
* FNV-1a hash using two 32-bit halves to simulate a 52-bit space,
|
|
38
|
+
* without requiring BigInt.
|
|
39
|
+
*
|
|
40
|
+
* Works identically in:
|
|
41
|
+
* - All browsers (including Safari 13, IE11 polyfill targets, React Native)
|
|
42
|
+
* - Node.js (any version)
|
|
43
|
+
* - Web Workers, Service Workers, Deno, Bun
|
|
44
|
+
*
|
|
45
|
+
* - Better avalanche than DJB2 (each input bit affects many output bits)
|
|
46
|
+
* - ~52-bit effective space — vastly fewer collisions than 32-bit
|
|
47
|
+
* - Always produces a **positive** hex string of 13 characters
|
|
48
|
+
*
|
|
49
|
+
* @param input Pre-serialized string.
|
|
50
|
+
* @returns 13-character lower-hex string.
|
|
51
|
+
*/
|
|
52
|
+
private static fnv1a52;
|
|
53
|
+
hash(caller: any, context: A_ExecutionContext, feature: A_Feature): void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { A_UtilsHelper };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"helpers.mjs"}
|
|
@@ -14,32 +14,10 @@ import { A_Entity, A_TYPES__Entity_Serialized, A_TYPES__Entity_Constructor } fro
|
|
|
14
14
|
* such as monitoring systems, real-time dashboards, or stateful applications.
|
|
15
15
|
*/
|
|
16
16
|
declare class A_Signal<_TSignalDataType extends any = any, _TSignalSerializedDataType extends any = _TSignalDataType> extends A_Entity<A_Signal_Init<_TSignalDataType>, A_Signal_Serialized<_TSignalSerializedDataType>> {
|
|
17
|
-
/**
|
|
18
|
-
* Allows to define default data for the signal.
|
|
19
|
-
*
|
|
20
|
-
* If no data is provided during initialization, the default data will be used.
|
|
21
|
-
*
|
|
22
|
-
* @returns
|
|
23
|
-
*/
|
|
24
|
-
static default(): A_Signal | undefined;
|
|
25
17
|
/**
|
|
26
18
|
* The actual data carried by the signal.
|
|
27
19
|
*/
|
|
28
20
|
data: _TSignalDataType;
|
|
29
|
-
/**
|
|
30
|
-
* Generates signal hash uses for comparison
|
|
31
|
-
*
|
|
32
|
-
* @param str
|
|
33
|
-
*/
|
|
34
|
-
protected createHash(str?: string): string;
|
|
35
|
-
protected createHash(str?: undefined): string;
|
|
36
|
-
protected createHash(str?: Record<string, any>): string;
|
|
37
|
-
protected createHash(str?: Array<any>): string;
|
|
38
|
-
protected createHash(str?: number): string;
|
|
39
|
-
protected createHash(str?: boolean): string;
|
|
40
|
-
protected createHash(str?: null): string;
|
|
41
|
-
protected createHash(map?: Map<any, any>): string;
|
|
42
|
-
protected createHash(set?: Set<any>): string;
|
|
43
21
|
/**
|
|
44
22
|
* This method compares the current signal with another signal instance by deduplication ID
|
|
45
23
|
* this id can be configured during initialization with the "id" property.
|
|
@@ -54,8 +32,26 @@ declare class A_Signal<_TSignalDataType extends any = any, _TSignalSerializedDat
|
|
|
54
32
|
* @returns
|
|
55
33
|
*/
|
|
56
34
|
compare(other: A_Signal<_TSignalDataType>): boolean;
|
|
57
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Allows to define default data for the signal.
|
|
37
|
+
*
|
|
38
|
+
* If no data is provided during initialization, the default data will be used.
|
|
39
|
+
*
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
fromUndefined(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Allows to initialize the signal from a new signal entity. This is useful for example when we want to create a new instance of the signal entity with the same data as another instance, but with a different ASEID.
|
|
45
|
+
*
|
|
46
|
+
* @param newEntity
|
|
47
|
+
*/
|
|
58
48
|
fromNew(newEntity: A_Signal_Init<_TSignalDataType>): void;
|
|
49
|
+
/**
|
|
50
|
+
* Allows to initialize the signal from a serialized version of the signal. This is useful for example when we receive a signal from the server and we want to create an instance of the signal entity from the received data.
|
|
51
|
+
*
|
|
52
|
+
* @param serializedEntity
|
|
53
|
+
*/
|
|
54
|
+
fromJSON(serializedEntity: A_Signal_Serialized<_TSignalSerializedDataType>): void;
|
|
59
55
|
toJSON(): A_Signal_Serialized<_TSignalSerializedDataType>;
|
|
60
56
|
}
|
|
61
57
|
|
|
@@ -14,32 +14,10 @@ import { A_Entity, A_TYPES__Entity_Serialized, A_TYPES__Entity_Constructor } fro
|
|
|
14
14
|
* such as monitoring systems, real-time dashboards, or stateful applications.
|
|
15
15
|
*/
|
|
16
16
|
declare class A_Signal<_TSignalDataType extends any = any, _TSignalSerializedDataType extends any = _TSignalDataType> extends A_Entity<A_Signal_Init<_TSignalDataType>, A_Signal_Serialized<_TSignalSerializedDataType>> {
|
|
17
|
-
/**
|
|
18
|
-
* Allows to define default data for the signal.
|
|
19
|
-
*
|
|
20
|
-
* If no data is provided during initialization, the default data will be used.
|
|
21
|
-
*
|
|
22
|
-
* @returns
|
|
23
|
-
*/
|
|
24
|
-
static default(): A_Signal | undefined;
|
|
25
17
|
/**
|
|
26
18
|
* The actual data carried by the signal.
|
|
27
19
|
*/
|
|
28
20
|
data: _TSignalDataType;
|
|
29
|
-
/**
|
|
30
|
-
* Generates signal hash uses for comparison
|
|
31
|
-
*
|
|
32
|
-
* @param str
|
|
33
|
-
*/
|
|
34
|
-
protected createHash(str?: string): string;
|
|
35
|
-
protected createHash(str?: undefined): string;
|
|
36
|
-
protected createHash(str?: Record<string, any>): string;
|
|
37
|
-
protected createHash(str?: Array<any>): string;
|
|
38
|
-
protected createHash(str?: number): string;
|
|
39
|
-
protected createHash(str?: boolean): string;
|
|
40
|
-
protected createHash(str?: null): string;
|
|
41
|
-
protected createHash(map?: Map<any, any>): string;
|
|
42
|
-
protected createHash(set?: Set<any>): string;
|
|
43
21
|
/**
|
|
44
22
|
* This method compares the current signal with another signal instance by deduplication ID
|
|
45
23
|
* this id can be configured during initialization with the "id" property.
|
|
@@ -54,8 +32,26 @@ declare class A_Signal<_TSignalDataType extends any = any, _TSignalSerializedDat
|
|
|
54
32
|
* @returns
|
|
55
33
|
*/
|
|
56
34
|
compare(other: A_Signal<_TSignalDataType>): boolean;
|
|
57
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Allows to define default data for the signal.
|
|
37
|
+
*
|
|
38
|
+
* If no data is provided during initialization, the default data will be used.
|
|
39
|
+
*
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
fromUndefined(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Allows to initialize the signal from a new signal entity. This is useful for example when we want to create a new instance of the signal entity with the same data as another instance, but with a different ASEID.
|
|
45
|
+
*
|
|
46
|
+
* @param newEntity
|
|
47
|
+
*/
|
|
58
48
|
fromNew(newEntity: A_Signal_Init<_TSignalDataType>): void;
|
|
49
|
+
/**
|
|
50
|
+
* Allows to initialize the signal from a serialized version of the signal. This is useful for example when we receive a signal from the server and we want to create an instance of the signal entity from the received data.
|
|
51
|
+
*
|
|
52
|
+
* @param serializedEntity
|
|
53
|
+
*/
|
|
54
|
+
fromJSON(serializedEntity: A_Signal_Serialized<_TSignalSerializedDataType>): void;
|
|
59
55
|
toJSON(): A_Signal_Serialized<_TSignalSerializedDataType>;
|
|
60
56
|
}
|
|
61
57
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { A_Component, A_Feature } from '@adaas/a-concept';
|
|
2
|
+
import { A_ExecutionContext } from '../lib/A-Execution/A-Execution.context.mjs';
|
|
3
|
+
|
|
4
|
+
declare class A_UtilsHelper extends A_Component {
|
|
5
|
+
/**
|
|
6
|
+
* Produces a deterministic, collision-resistant hash string for any JS value.
|
|
7
|
+
*
|
|
8
|
+
* Improvements over the legacy `createHash`:
|
|
9
|
+
* - **Null-safe** — handles `null` without throwing
|
|
10
|
+
* - **Function-aware serialization** — functions inside objects / arrays are
|
|
11
|
+
* serialized via `.toString()` so `{ fn: () => 1 }` ≠ `{}`
|
|
12
|
+
* - **FNV-1a 52-bit** — better avalanche / distribution than DJB2-32,
|
|
13
|
+
* and uses the safe JS integer range so the result is always positive
|
|
14
|
+
* - **Hex output** — compact, URL-safe, fixed-width (13 chars)
|
|
15
|
+
*
|
|
16
|
+
* @param value Any value: string, number, boolean, null, undefined,
|
|
17
|
+
* object, array, Map, Set, function, or a mix of these.
|
|
18
|
+
* @returns A 13-character lower-hex string (52-bit FNV-1a).
|
|
19
|
+
*/
|
|
20
|
+
static hash(value?: any): string;
|
|
21
|
+
/**
|
|
22
|
+
* Converts any JS value into a deterministic string representation
|
|
23
|
+
* suitable for hashing.
|
|
24
|
+
*
|
|
25
|
+
* Key properties:
|
|
26
|
+
* - **Deterministic**: same logical value → same string every time
|
|
27
|
+
* - **Injective-ish**: structurally different values produce different
|
|
28
|
+
* strings (type tags prevent `"3"` vs `3` collisions)
|
|
29
|
+
* - **Recursive**: handles nested objects, arrays, Maps, Sets
|
|
30
|
+
* - **Function-aware**: serializes functions via `.toString()`
|
|
31
|
+
*
|
|
32
|
+
* @param value Anything.
|
|
33
|
+
* @returns A deterministic string.
|
|
34
|
+
*/
|
|
35
|
+
static serialize(value: any): string;
|
|
36
|
+
/**
|
|
37
|
+
* FNV-1a hash using two 32-bit halves to simulate a 52-bit space,
|
|
38
|
+
* without requiring BigInt.
|
|
39
|
+
*
|
|
40
|
+
* Works identically in:
|
|
41
|
+
* - All browsers (including Safari 13, IE11 polyfill targets, React Native)
|
|
42
|
+
* - Node.js (any version)
|
|
43
|
+
* - Web Workers, Service Workers, Deno, Bun
|
|
44
|
+
*
|
|
45
|
+
* - Better avalanche than DJB2 (each input bit affects many output bits)
|
|
46
|
+
* - ~52-bit effective space — vastly fewer collisions than 32-bit
|
|
47
|
+
* - Always produces a **positive** hex string of 13 characters
|
|
48
|
+
*
|
|
49
|
+
* @param input Pre-serialized string.
|
|
50
|
+
* @returns 13-character lower-hex string.
|
|
51
|
+
*/
|
|
52
|
+
private static fnv1a52;
|
|
53
|
+
hash(caller: any, context: A_ExecutionContext, feature: A_Feature): void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { A_UtilsHelper };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { A_Component, A_Feature } from '@adaas/a-concept';
|
|
2
|
+
import { A_ExecutionContext } from '../lib/A-Execution/A-Execution.context.js';
|
|
3
|
+
|
|
4
|
+
declare class A_UtilsHelper extends A_Component {
|
|
5
|
+
/**
|
|
6
|
+
* Produces a deterministic, collision-resistant hash string for any JS value.
|
|
7
|
+
*
|
|
8
|
+
* Improvements over the legacy `createHash`:
|
|
9
|
+
* - **Null-safe** — handles `null` without throwing
|
|
10
|
+
* - **Function-aware serialization** — functions inside objects / arrays are
|
|
11
|
+
* serialized via `.toString()` so `{ fn: () => 1 }` ≠ `{}`
|
|
12
|
+
* - **FNV-1a 52-bit** — better avalanche / distribution than DJB2-32,
|
|
13
|
+
* and uses the safe JS integer range so the result is always positive
|
|
14
|
+
* - **Hex output** — compact, URL-safe, fixed-width (13 chars)
|
|
15
|
+
*
|
|
16
|
+
* @param value Any value: string, number, boolean, null, undefined,
|
|
17
|
+
* object, array, Map, Set, function, or a mix of these.
|
|
18
|
+
* @returns A 13-character lower-hex string (52-bit FNV-1a).
|
|
19
|
+
*/
|
|
20
|
+
static hash(value?: any): string;
|
|
21
|
+
/**
|
|
22
|
+
* Converts any JS value into a deterministic string representation
|
|
23
|
+
* suitable for hashing.
|
|
24
|
+
*
|
|
25
|
+
* Key properties:
|
|
26
|
+
* - **Deterministic**: same logical value → same string every time
|
|
27
|
+
* - **Injective-ish**: structurally different values produce different
|
|
28
|
+
* strings (type tags prevent `"3"` vs `3` collisions)
|
|
29
|
+
* - **Recursive**: handles nested objects, arrays, Maps, Sets
|
|
30
|
+
* - **Function-aware**: serializes functions via `.toString()`
|
|
31
|
+
*
|
|
32
|
+
* @param value Anything.
|
|
33
|
+
* @returns A deterministic string.
|
|
34
|
+
*/
|
|
35
|
+
static serialize(value: any): string;
|
|
36
|
+
/**
|
|
37
|
+
* FNV-1a hash using two 32-bit halves to simulate a 52-bit space,
|
|
38
|
+
* without requiring BigInt.
|
|
39
|
+
*
|
|
40
|
+
* Works identically in:
|
|
41
|
+
* - All browsers (including Safari 13, IE11 polyfill targets, React Native)
|
|
42
|
+
* - Node.js (any version)
|
|
43
|
+
* - Web Workers, Service Workers, Deno, Bun
|
|
44
|
+
*
|
|
45
|
+
* - Better avalanche than DJB2 (each input bit affects many output bits)
|
|
46
|
+
* - ~52-bit effective space — vastly fewer collisions than 32-bit
|
|
47
|
+
* - Always produces a **positive** hex string of 13 characters
|
|
48
|
+
*
|
|
49
|
+
* @param input Pre-serialized string.
|
|
50
|
+
* @returns 13-character lower-hex string.
|
|
51
|
+
*/
|
|
52
|
+
private static fnv1a52;
|
|
53
|
+
hash(caller: any, context: A_ExecutionContext, feature: A_Feature): void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { A_UtilsHelper };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var aConcept = require('@adaas/a-concept');
|
|
4
|
+
var aFrame = require('@adaas/a-frame');
|
|
5
|
+
var aExecution = require('@adaas/a-utils/a-execution');
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
10
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
11
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
12
|
+
if (decorator = decorators[i])
|
|
13
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
14
|
+
if (kind && result) __defProp(target, key, result);
|
|
15
|
+
return result;
|
|
16
|
+
};
|
|
17
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
18
|
+
exports.A_UtilsHelper = class A_UtilsHelper extends aConcept.A_Component {
|
|
19
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
20
|
+
// ── Hashing ──────────────────────────────────────────────────────────────────
|
|
21
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
22
|
+
/**
|
|
23
|
+
* Produces a deterministic, collision-resistant hash string for any JS value.
|
|
24
|
+
*
|
|
25
|
+
* Improvements over the legacy `createHash`:
|
|
26
|
+
* - **Null-safe** — handles `null` without throwing
|
|
27
|
+
* - **Function-aware serialization** — functions inside objects / arrays are
|
|
28
|
+
* serialized via `.toString()` so `{ fn: () => 1 }` ≠ `{}`
|
|
29
|
+
* - **FNV-1a 52-bit** — better avalanche / distribution than DJB2-32,
|
|
30
|
+
* and uses the safe JS integer range so the result is always positive
|
|
31
|
+
* - **Hex output** — compact, URL-safe, fixed-width (13 chars)
|
|
32
|
+
*
|
|
33
|
+
* @param value Any value: string, number, boolean, null, undefined,
|
|
34
|
+
* object, array, Map, Set, function, or a mix of these.
|
|
35
|
+
* @returns A 13-character lower-hex string (52-bit FNV-1a).
|
|
36
|
+
*/
|
|
37
|
+
static hash(value) {
|
|
38
|
+
const source = exports.A_UtilsHelper.serialize(value);
|
|
39
|
+
return exports.A_UtilsHelper.fnv1a52(source);
|
|
40
|
+
}
|
|
41
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
42
|
+
// ── Serialization ────────────────────────────────────────────────────────────
|
|
43
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
44
|
+
/**
|
|
45
|
+
* Converts any JS value into a deterministic string representation
|
|
46
|
+
* suitable for hashing.
|
|
47
|
+
*
|
|
48
|
+
* Key properties:
|
|
49
|
+
* - **Deterministic**: same logical value → same string every time
|
|
50
|
+
* - **Injective-ish**: structurally different values produce different
|
|
51
|
+
* strings (type tags prevent `"3"` vs `3` collisions)
|
|
52
|
+
* - **Recursive**: handles nested objects, arrays, Maps, Sets
|
|
53
|
+
* - **Function-aware**: serializes functions via `.toString()`
|
|
54
|
+
*
|
|
55
|
+
* @param value Anything.
|
|
56
|
+
* @returns A deterministic string.
|
|
57
|
+
*/
|
|
58
|
+
static serialize(value) {
|
|
59
|
+
if (value === null) return "<null>";
|
|
60
|
+
if (value === void 0) return "<undefined>";
|
|
61
|
+
switch (typeof value) {
|
|
62
|
+
case "string":
|
|
63
|
+
return `s:${value}`;
|
|
64
|
+
case "number":
|
|
65
|
+
return `n:${value}`;
|
|
66
|
+
case "boolean":
|
|
67
|
+
return `b:${value}`;
|
|
68
|
+
case "bigint":
|
|
69
|
+
return `bi:${value}`;
|
|
70
|
+
case "symbol":
|
|
71
|
+
return `sym:${value.toString()}`;
|
|
72
|
+
case "function":
|
|
73
|
+
return `fn:${value.toString()}`;
|
|
74
|
+
}
|
|
75
|
+
if (value instanceof Map) {
|
|
76
|
+
const entries = Array.from(value.entries()).map(([k, v]) => `${exports.A_UtilsHelper.serialize(k)}=>${exports.A_UtilsHelper.serialize(v)}`).sort().join(",");
|
|
77
|
+
return `Map{${entries}}`;
|
|
78
|
+
}
|
|
79
|
+
if (value instanceof Set) {
|
|
80
|
+
const items = Array.from(value.values()).map((v) => exports.A_UtilsHelper.serialize(v)).sort().join(",");
|
|
81
|
+
return `Set{${items}}`;
|
|
82
|
+
}
|
|
83
|
+
if (value instanceof Date) {
|
|
84
|
+
return `Date:${value.toISOString()}`;
|
|
85
|
+
}
|
|
86
|
+
if (value instanceof RegExp) {
|
|
87
|
+
return `RegExp:${value.toString()}`;
|
|
88
|
+
}
|
|
89
|
+
if (Array.isArray(value)) {
|
|
90
|
+
const items = value.map((v) => exports.A_UtilsHelper.serialize(v)).join(",");
|
|
91
|
+
return `[${items}]`;
|
|
92
|
+
}
|
|
93
|
+
if (typeof value.toJSON === "function") {
|
|
94
|
+
return `json:${exports.A_UtilsHelper.serialize(value.toJSON())}`;
|
|
95
|
+
}
|
|
96
|
+
const keys = Object.keys(value).sort();
|
|
97
|
+
const pairs = keys.map((k) => `${k}:${exports.A_UtilsHelper.serialize(value[k])}`).join(",");
|
|
98
|
+
return `{${pairs}}`;
|
|
99
|
+
}
|
|
100
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
101
|
+
// ── FNV-1a (pure Number, no BigInt) ──────────────────────────────────────────
|
|
102
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
103
|
+
/**
|
|
104
|
+
* FNV-1a hash using two 32-bit halves to simulate a 52-bit space,
|
|
105
|
+
* without requiring BigInt.
|
|
106
|
+
*
|
|
107
|
+
* Works identically in:
|
|
108
|
+
* - All browsers (including Safari 13, IE11 polyfill targets, React Native)
|
|
109
|
+
* - Node.js (any version)
|
|
110
|
+
* - Web Workers, Service Workers, Deno, Bun
|
|
111
|
+
*
|
|
112
|
+
* - Better avalanche than DJB2 (each input bit affects many output bits)
|
|
113
|
+
* - ~52-bit effective space — vastly fewer collisions than 32-bit
|
|
114
|
+
* - Always produces a **positive** hex string of 13 characters
|
|
115
|
+
*
|
|
116
|
+
* @param input Pre-serialized string.
|
|
117
|
+
* @returns 13-character lower-hex string.
|
|
118
|
+
*/
|
|
119
|
+
static fnv1a52(input) {
|
|
120
|
+
let h1 = 2166136261;
|
|
121
|
+
let h2 = 2114;
|
|
122
|
+
const PRIME = 16777619;
|
|
123
|
+
for (let i = 0; i < input.length; i++) {
|
|
124
|
+
h1 ^= input.charCodeAt(i);
|
|
125
|
+
const product = Math.imul(h1, PRIME);
|
|
126
|
+
h1 = product >>> 0;
|
|
127
|
+
h2 = (Math.imul(h2, PRIME) + (product / 4294967296 >>> 0) & 1048575) >>> 0;
|
|
128
|
+
}
|
|
129
|
+
const combined = h2 * 4294967296 + h1;
|
|
130
|
+
return combined.toString(16).padStart(13, "0");
|
|
131
|
+
}
|
|
132
|
+
hash(caller, context, feature) {
|
|
133
|
+
const hash = exports.A_UtilsHelper.hash(caller);
|
|
134
|
+
context.set(feature.name, hash);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
__decorateClass([
|
|
138
|
+
aFrame.A_Frame.Method({
|
|
139
|
+
description: "Instance method wrapper for the static hash function, allowing it to be injected as a dependency."
|
|
140
|
+
}),
|
|
141
|
+
__decorateParam(0, aConcept.A_Inject(aConcept.A_Caller)),
|
|
142
|
+
__decorateParam(1, aConcept.A_Inject(aExecution.A_ExecutionContext)),
|
|
143
|
+
__decorateParam(2, aConcept.A_Inject(aConcept.A_Feature))
|
|
144
|
+
], exports.A_UtilsHelper.prototype, "hash", 1);
|
|
145
|
+
exports.A_UtilsHelper = __decorateClass([
|
|
146
|
+
aFrame.A_Frame.Component({
|
|
147
|
+
namespace: "A-Utils",
|
|
148
|
+
name: "A-UtilsHelper",
|
|
149
|
+
description: "Utility helper class providing common functions for A-Utils library, such as hashing and serialization."
|
|
150
|
+
})
|
|
151
|
+
], exports.A_UtilsHelper);
|
|
152
|
+
//# sourceMappingURL=A-Utils.helper.js.map
|
|
153
|
+
//# sourceMappingURL=A-Utils.helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/helpers/A-Utils.helper.ts"],"names":["A_UtilsHelper","A_Component","A_Frame","A_Caller","A_ExecutionContext","A_Feature"],"mappings":"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","file":"A-Utils.helper.js","sourcesContent":["import { A_Caller, A_Component, A_Feature, A_Inject } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame\";\nimport { A_ExecutionContext } from \"@adaas/a-utils/a-execution\";\n\n\n\n@A_Frame.Component({\n namespace: 'A-Utils',\n name: 'A-UtilsHelper',\n description: 'Utility helper class providing common functions for A-Utils library, such as hashing and serialization.'\n})\nexport class A_UtilsHelper extends A_Component {\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── Hashing ──────────────────────────────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Produces a deterministic, collision-resistant hash string for any JS value.\n * \n * Improvements over the legacy `createHash`:\n * - **Null-safe** — handles `null` without throwing \n * - **Function-aware serialization** — functions inside objects / arrays are\n * serialized via `.toString()` so `{ fn: () => 1 }` ≠ `{}` \n * - **FNV-1a 52-bit** — better avalanche / distribution than DJB2-32,\n * and uses the safe JS integer range so the result is always positive \n * - **Hex output** — compact, URL-safe, fixed-width (13 chars)\n * \n * @param value Any value: string, number, boolean, null, undefined,\n * object, array, Map, Set, function, or a mix of these.\n * @returns A 13-character lower-hex string (52-bit FNV-1a).\n */\n static hash(value?: any): string {\n const source = A_UtilsHelper.serialize(value);\n return A_UtilsHelper.fnv1a52(source);\n }\n\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── Serialization ────────────────────────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Converts any JS value into a deterministic string representation\n * suitable for hashing.\n * \n * Key properties:\n * - **Deterministic**: same logical value → same string every time\n * - **Injective-ish**: structurally different values produce different\n * strings (type tags prevent `\"3\"` vs `3` collisions)\n * - **Recursive**: handles nested objects, arrays, Maps, Sets\n * - **Function-aware**: serializes functions via `.toString()`\n * \n * @param value Anything.\n * @returns A deterministic string.\n */\n static serialize(value: any): string {\n // Primitives & null/undefined\n if (value === null) return '<null>';\n if (value === undefined) return '<undefined>';\n\n switch (typeof value) {\n case 'string':\n return `s:${value}`;\n case 'number':\n return `n:${value}`;\n case 'boolean':\n return `b:${value}`;\n case 'bigint':\n return `bi:${value}`;\n case 'symbol':\n return `sym:${value.toString()}`;\n case 'function':\n return `fn:${value.toString()}`;\n }\n\n // Map\n if (value instanceof Map) {\n const entries = Array.from(value.entries())\n .map(([k, v]) => `${A_UtilsHelper.serialize(k)}=>${A_UtilsHelper.serialize(v)}`)\n .sort()\n .join(',');\n return `Map{${entries}}`;\n }\n\n // Set\n if (value instanceof Set) {\n const items = Array.from(value.values())\n .map(v => A_UtilsHelper.serialize(v))\n .sort()\n .join(',');\n return `Set{${items}}`;\n }\n\n // Date\n if (value instanceof Date) {\n return `Date:${value.toISOString()}`;\n }\n\n // RegExp\n if (value instanceof RegExp) {\n return `RegExp:${value.toString()}`;\n }\n\n // Array\n if (Array.isArray(value)) {\n const items = value.map(v => A_UtilsHelper.serialize(v)).join(',');\n return `[${items}]`;\n }\n\n // toJSON support (e.g. custom entities, ASEID, etc.)\n if (typeof value.toJSON === 'function') {\n return `json:${A_UtilsHelper.serialize(value.toJSON())}`;\n }\n\n // Plain object — sort keys for determinism, serialize functions too\n const keys = Object.keys(value).sort();\n const pairs = keys.map(k => `${k}:${A_UtilsHelper.serialize(value[k])}`).join(',');\n return `{${pairs}}`;\n }\n\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── FNV-1a (pure Number, no BigInt) ──────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * FNV-1a hash using two 32-bit halves to simulate a 52-bit space,\n * without requiring BigInt.\n * \n * Works identically in:\n * - All browsers (including Safari 13, IE11 polyfill targets, React Native)\n * - Node.js (any version)\n * - Web Workers, Service Workers, Deno, Bun\n * \n * - Better avalanche than DJB2 (each input bit affects many output bits)\n * - ~52-bit effective space — vastly fewer collisions than 32-bit\n * - Always produces a **positive** hex string of 13 characters\n * \n * @param input Pre-serialized string.\n * @returns 13-character lower-hex string.\n */\n private static fnv1a52(input: string): string {\n // FNV-1a offset basis split into two 32-bit halves\n let h1 = 0x811c9dc5; // low 32 bits\n let h2 = 0x00000842; // high 20 bits (keeps us in 52-bit range)\n\n // FNV prime = 0x01000193\n const PRIME = 0x01000193;\n\n for (let i = 0; i < input.length; i++) {\n h1 ^= input.charCodeAt(i);\n\n // Multiply h1 by prime (32-bit, unsigned)\n const product = Math.imul(h1, PRIME);\n h1 = product >>> 0;\n\n // Carry overflow into h2, keep h2 within 20 bits\n h2 = ((Math.imul(h2, PRIME) + (product / 0x100000000 >>> 0)) & 0xFFFFF) >>> 0;\n }\n\n // Combine: h2 (20 bits) << 32 | h1 (32 bits) → 52-bit number\n // Since 2^52 fits in Number.MAX_SAFE_INTEGER, this is exact.\n const combined = h2 * 0x100000000 + h1;\n\n return combined.toString(16).padStart(13, '0');\n }\n\n\n\n // ==============================================================================\n // =============== Instance methods for used for Injection ======================\n // ==============================================================================\n @A_Frame.Method({\n description: 'Instance method wrapper for the static hash function, allowing it to be injected as a dependency.'\n })\n hash(\n @A_Inject(A_Caller) caller: any,\n @A_Inject(A_ExecutionContext) context: A_ExecutionContext,\n @A_Inject(A_Feature) feature: A_Feature\n ) {\n const hash = A_UtilsHelper.hash(caller);\n\n context.set(feature.name, hash);\n }\n}"]}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { __decorateClass, __decorateParam } from '../chunk-EQQGB2QZ.mjs';
|
|
2
|
+
import { A_Inject, A_Caller, A_Feature, A_Component } from '@adaas/a-concept';
|
|
3
|
+
import { A_Frame } from '@adaas/a-frame';
|
|
4
|
+
import { A_ExecutionContext } from '@adaas/a-utils/a-execution';
|
|
5
|
+
|
|
6
|
+
let A_UtilsHelper = class extends A_Component {
|
|
7
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
8
|
+
// ── Hashing ──────────────────────────────────────────────────────────────────
|
|
9
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
10
|
+
/**
|
|
11
|
+
* Produces a deterministic, collision-resistant hash string for any JS value.
|
|
12
|
+
*
|
|
13
|
+
* Improvements over the legacy `createHash`:
|
|
14
|
+
* - **Null-safe** — handles `null` without throwing
|
|
15
|
+
* - **Function-aware serialization** — functions inside objects / arrays are
|
|
16
|
+
* serialized via `.toString()` so `{ fn: () => 1 }` ≠ `{}`
|
|
17
|
+
* - **FNV-1a 52-bit** — better avalanche / distribution than DJB2-32,
|
|
18
|
+
* and uses the safe JS integer range so the result is always positive
|
|
19
|
+
* - **Hex output** — compact, URL-safe, fixed-width (13 chars)
|
|
20
|
+
*
|
|
21
|
+
* @param value Any value: string, number, boolean, null, undefined,
|
|
22
|
+
* object, array, Map, Set, function, or a mix of these.
|
|
23
|
+
* @returns A 13-character lower-hex string (52-bit FNV-1a).
|
|
24
|
+
*/
|
|
25
|
+
static hash(value) {
|
|
26
|
+
const source = A_UtilsHelper.serialize(value);
|
|
27
|
+
return A_UtilsHelper.fnv1a52(source);
|
|
28
|
+
}
|
|
29
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
// ── Serialization ────────────────────────────────────────────────────────────
|
|
31
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Converts any JS value into a deterministic string representation
|
|
34
|
+
* suitable for hashing.
|
|
35
|
+
*
|
|
36
|
+
* Key properties:
|
|
37
|
+
* - **Deterministic**: same logical value → same string every time
|
|
38
|
+
* - **Injective-ish**: structurally different values produce different
|
|
39
|
+
* strings (type tags prevent `"3"` vs `3` collisions)
|
|
40
|
+
* - **Recursive**: handles nested objects, arrays, Maps, Sets
|
|
41
|
+
* - **Function-aware**: serializes functions via `.toString()`
|
|
42
|
+
*
|
|
43
|
+
* @param value Anything.
|
|
44
|
+
* @returns A deterministic string.
|
|
45
|
+
*/
|
|
46
|
+
static serialize(value) {
|
|
47
|
+
if (value === null) return "<null>";
|
|
48
|
+
if (value === void 0) return "<undefined>";
|
|
49
|
+
switch (typeof value) {
|
|
50
|
+
case "string":
|
|
51
|
+
return `s:${value}`;
|
|
52
|
+
case "number":
|
|
53
|
+
return `n:${value}`;
|
|
54
|
+
case "boolean":
|
|
55
|
+
return `b:${value}`;
|
|
56
|
+
case "bigint":
|
|
57
|
+
return `bi:${value}`;
|
|
58
|
+
case "symbol":
|
|
59
|
+
return `sym:${value.toString()}`;
|
|
60
|
+
case "function":
|
|
61
|
+
return `fn:${value.toString()}`;
|
|
62
|
+
}
|
|
63
|
+
if (value instanceof Map) {
|
|
64
|
+
const entries = Array.from(value.entries()).map(([k, v]) => `${A_UtilsHelper.serialize(k)}=>${A_UtilsHelper.serialize(v)}`).sort().join(",");
|
|
65
|
+
return `Map{${entries}}`;
|
|
66
|
+
}
|
|
67
|
+
if (value instanceof Set) {
|
|
68
|
+
const items = Array.from(value.values()).map((v) => A_UtilsHelper.serialize(v)).sort().join(",");
|
|
69
|
+
return `Set{${items}}`;
|
|
70
|
+
}
|
|
71
|
+
if (value instanceof Date) {
|
|
72
|
+
return `Date:${value.toISOString()}`;
|
|
73
|
+
}
|
|
74
|
+
if (value instanceof RegExp) {
|
|
75
|
+
return `RegExp:${value.toString()}`;
|
|
76
|
+
}
|
|
77
|
+
if (Array.isArray(value)) {
|
|
78
|
+
const items = value.map((v) => A_UtilsHelper.serialize(v)).join(",");
|
|
79
|
+
return `[${items}]`;
|
|
80
|
+
}
|
|
81
|
+
if (typeof value.toJSON === "function") {
|
|
82
|
+
return `json:${A_UtilsHelper.serialize(value.toJSON())}`;
|
|
83
|
+
}
|
|
84
|
+
const keys = Object.keys(value).sort();
|
|
85
|
+
const pairs = keys.map((k) => `${k}:${A_UtilsHelper.serialize(value[k])}`).join(",");
|
|
86
|
+
return `{${pairs}}`;
|
|
87
|
+
}
|
|
88
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
89
|
+
// ── FNV-1a (pure Number, no BigInt) ──────────────────────────────────────────
|
|
90
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
91
|
+
/**
|
|
92
|
+
* FNV-1a hash using two 32-bit halves to simulate a 52-bit space,
|
|
93
|
+
* without requiring BigInt.
|
|
94
|
+
*
|
|
95
|
+
* Works identically in:
|
|
96
|
+
* - All browsers (including Safari 13, IE11 polyfill targets, React Native)
|
|
97
|
+
* - Node.js (any version)
|
|
98
|
+
* - Web Workers, Service Workers, Deno, Bun
|
|
99
|
+
*
|
|
100
|
+
* - Better avalanche than DJB2 (each input bit affects many output bits)
|
|
101
|
+
* - ~52-bit effective space — vastly fewer collisions than 32-bit
|
|
102
|
+
* - Always produces a **positive** hex string of 13 characters
|
|
103
|
+
*
|
|
104
|
+
* @param input Pre-serialized string.
|
|
105
|
+
* @returns 13-character lower-hex string.
|
|
106
|
+
*/
|
|
107
|
+
static fnv1a52(input) {
|
|
108
|
+
let h1 = 2166136261;
|
|
109
|
+
let h2 = 2114;
|
|
110
|
+
const PRIME = 16777619;
|
|
111
|
+
for (let i = 0; i < input.length; i++) {
|
|
112
|
+
h1 ^= input.charCodeAt(i);
|
|
113
|
+
const product = Math.imul(h1, PRIME);
|
|
114
|
+
h1 = product >>> 0;
|
|
115
|
+
h2 = (Math.imul(h2, PRIME) + (product / 4294967296 >>> 0) & 1048575) >>> 0;
|
|
116
|
+
}
|
|
117
|
+
const combined = h2 * 4294967296 + h1;
|
|
118
|
+
return combined.toString(16).padStart(13, "0");
|
|
119
|
+
}
|
|
120
|
+
hash(caller, context, feature) {
|
|
121
|
+
const hash = A_UtilsHelper.hash(caller);
|
|
122
|
+
context.set(feature.name, hash);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
__decorateClass([
|
|
126
|
+
A_Frame.Method({
|
|
127
|
+
description: "Instance method wrapper for the static hash function, allowing it to be injected as a dependency."
|
|
128
|
+
}),
|
|
129
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
130
|
+
__decorateParam(1, A_Inject(A_ExecutionContext)),
|
|
131
|
+
__decorateParam(2, A_Inject(A_Feature))
|
|
132
|
+
], A_UtilsHelper.prototype, "hash", 1);
|
|
133
|
+
A_UtilsHelper = __decorateClass([
|
|
134
|
+
A_Frame.Component({
|
|
135
|
+
namespace: "A-Utils",
|
|
136
|
+
name: "A-UtilsHelper",
|
|
137
|
+
description: "Utility helper class providing common functions for A-Utils library, such as hashing and serialization."
|
|
138
|
+
})
|
|
139
|
+
], A_UtilsHelper);
|
|
140
|
+
|
|
141
|
+
export { A_UtilsHelper };
|
|
142
|
+
//# sourceMappingURL=A-Utils.helper.mjs.map
|
|
143
|
+
//# sourceMappingURL=A-Utils.helper.mjs.map
|