@affectively/aeon 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/compression/index.cjs +580 -0
- package/dist/compression/index.cjs.map +1 -0
- package/dist/compression/index.d.cts +189 -0
- package/dist/compression/index.d.ts +189 -0
- package/dist/compression/index.js +573 -0
- package/dist/compression/index.js.map +1 -0
- package/dist/core/index.d.cts +70 -5
- package/dist/core/index.d.ts +70 -5
- package/dist/crypto/index.cjs +100 -0
- package/dist/crypto/index.cjs.map +1 -0
- package/dist/crypto/index.d.cts +407 -0
- package/dist/crypto/index.d.ts +407 -0
- package/dist/crypto/index.js +96 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/distributed/index.cjs +420 -23
- package/dist/distributed/index.cjs.map +1 -1
- package/dist/distributed/index.d.cts +901 -2
- package/dist/distributed/index.d.ts +901 -2
- package/dist/distributed/index.js +420 -23
- package/dist/distributed/index.js.map +1 -1
- package/dist/index.cjs +1222 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -811
- package/dist/index.d.ts +11 -811
- package/dist/index.js +1221 -56
- package/dist/index.js.map +1 -1
- package/dist/offline/index.cjs +419 -0
- package/dist/offline/index.cjs.map +1 -0
- package/dist/offline/index.d.cts +148 -0
- package/dist/offline/index.d.ts +148 -0
- package/dist/offline/index.js +415 -0
- package/dist/offline/index.js.map +1 -0
- package/dist/optimization/index.cjs +797 -0
- package/dist/optimization/index.cjs.map +1 -0
- package/dist/optimization/index.d.cts +347 -0
- package/dist/optimization/index.d.ts +347 -0
- package/dist/optimization/index.js +787 -0
- package/dist/optimization/index.js.map +1 -0
- package/dist/persistence/index.cjs +145 -0
- package/dist/persistence/index.cjs.map +1 -0
- package/dist/persistence/index.d.cts +63 -0
- package/dist/persistence/index.d.ts +63 -0
- package/dist/persistence/index.js +142 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/presence/index.cjs +489 -0
- package/dist/presence/index.cjs.map +1 -0
- package/dist/presence/index.d.cts +283 -0
- package/dist/presence/index.d.ts +283 -0
- package/dist/presence/index.js +485 -0
- package/dist/presence/index.js.map +1 -0
- package/dist/types-CMxO7QF0.d.cts +33 -0
- package/dist/types-CMxO7QF0.d.ts +33 -0
- package/dist/versioning/index.cjs +296 -14
- package/dist/versioning/index.cjs.map +1 -1
- package/dist/versioning/index.d.cts +66 -1
- package/dist/versioning/index.d.ts +66 -1
- package/dist/versioning/index.js +296 -14
- package/dist/versioning/index.js.map +1 -1
- package/package.json +51 -1
- package/dist/index-C_4CMV5c.d.cts +0 -1207
- package/dist/index-C_4CMV5c.d.ts +0 -1207
package/dist/versioning/index.js
CHANGED
|
@@ -75,7 +75,9 @@ var SchemaVersionManager = class {
|
|
|
75
75
|
*/
|
|
76
76
|
setCurrentVersion(version) {
|
|
77
77
|
if (!this.versions.has(this.versionToString(version))) {
|
|
78
|
-
throw new Error(
|
|
78
|
+
throw new Error(
|
|
79
|
+
`Version ${this.versionToString(version)} not registered`
|
|
80
|
+
);
|
|
79
81
|
}
|
|
80
82
|
this.currentVersion = version;
|
|
81
83
|
logger.debug("[SchemaVersionManager] Current version set", {
|
|
@@ -361,7 +363,9 @@ var MigrationEngine = class {
|
|
|
361
363
|
id: migrationId,
|
|
362
364
|
error: result.errors[0]
|
|
363
365
|
});
|
|
364
|
-
throw new Error(
|
|
366
|
+
throw new Error(
|
|
367
|
+
`Rollback for ${migrationId} failed: ${result.errors[0]}`
|
|
368
|
+
);
|
|
365
369
|
}
|
|
366
370
|
}
|
|
367
371
|
/**
|
|
@@ -414,8 +418,14 @@ var MigrationEngine = class {
|
|
|
414
418
|
getStatistics() {
|
|
415
419
|
const successful = this.executedMigrations.filter((m) => m.success).length;
|
|
416
420
|
const failed = this.executedMigrations.filter((m) => !m.success).length;
|
|
417
|
-
const totalDuration = this.executedMigrations.reduce(
|
|
418
|
-
|
|
421
|
+
const totalDuration = this.executedMigrations.reduce(
|
|
422
|
+
(sum, m) => sum + m.duration,
|
|
423
|
+
0
|
|
424
|
+
);
|
|
425
|
+
const totalAffected = this.executedMigrations.reduce(
|
|
426
|
+
(sum, m) => sum + m.itemsAffected,
|
|
427
|
+
0
|
|
428
|
+
);
|
|
419
429
|
return {
|
|
420
430
|
totalExecuted: this.executedMigrations.length,
|
|
421
431
|
successful,
|
|
@@ -469,7 +479,9 @@ var DataTransformer = class {
|
|
|
469
479
|
return rule.transformer(value);
|
|
470
480
|
} catch (error) {
|
|
471
481
|
if (rule.required) {
|
|
472
|
-
throw new Error(
|
|
482
|
+
throw new Error(
|
|
483
|
+
`Failed to transform required field ${field}: ${error instanceof Error ? error.message : String(error)}`
|
|
484
|
+
);
|
|
473
485
|
}
|
|
474
486
|
return rule.defaultValue !== void 0 ? rule.defaultValue : value;
|
|
475
487
|
}
|
|
@@ -542,7 +554,9 @@ var DataTransformer = class {
|
|
|
542
554
|
validateTransformation(original, transformed) {
|
|
543
555
|
const issues = [];
|
|
544
556
|
if (original.length !== transformed.length) {
|
|
545
|
-
issues.push(
|
|
557
|
+
issues.push(
|
|
558
|
+
`Item count mismatch: ${original.length} -> ${transformed.length}`
|
|
559
|
+
);
|
|
546
560
|
}
|
|
547
561
|
for (let i = 0; i < Math.min(original.length, transformed.length); i++) {
|
|
548
562
|
const orig = original[i];
|
|
@@ -633,14 +647,40 @@ var DataTransformer = class {
|
|
|
633
647
|
};
|
|
634
648
|
|
|
635
649
|
// src/versioning/MigrationTracker.ts
|
|
636
|
-
var MigrationTracker = class {
|
|
650
|
+
var MigrationTracker = class _MigrationTracker {
|
|
651
|
+
static DEFAULT_PERSIST_KEY = "aeon:migration-tracker:v1";
|
|
652
|
+
static INTEGRITY_ROOT = "aeon:migration-integrity-root:v1";
|
|
637
653
|
migrations = [];
|
|
638
654
|
snapshots = /* @__PURE__ */ new Map();
|
|
655
|
+
persistence = null;
|
|
656
|
+
persistTimer = null;
|
|
657
|
+
persistInFlight = false;
|
|
658
|
+
persistPending = false;
|
|
659
|
+
constructor(options) {
|
|
660
|
+
if (options?.persistence) {
|
|
661
|
+
this.persistence = {
|
|
662
|
+
...options.persistence,
|
|
663
|
+
key: options.persistence.key ?? _MigrationTracker.DEFAULT_PERSIST_KEY,
|
|
664
|
+
autoPersist: options.persistence.autoPersist ?? true,
|
|
665
|
+
autoLoad: options.persistence.autoLoad ?? false,
|
|
666
|
+
persistDebounceMs: options.persistence.persistDebounceMs ?? 25
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
if (this.persistence?.autoLoad) {
|
|
670
|
+
void this.loadFromPersistence().catch((error) => {
|
|
671
|
+
logger.error("[MigrationTracker] Failed to load persistence", {
|
|
672
|
+
key: this.persistence?.key,
|
|
673
|
+
error: error instanceof Error ? error.message : String(error)
|
|
674
|
+
});
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
}
|
|
639
678
|
/**
|
|
640
679
|
* Track a new migration
|
|
641
680
|
*/
|
|
642
681
|
recordMigration(record) {
|
|
643
682
|
this.migrations.push({ ...record });
|
|
683
|
+
this.schedulePersist();
|
|
644
684
|
logger.debug("[MigrationTracker] Migration recorded", {
|
|
645
685
|
id: record.id,
|
|
646
686
|
migrationId: record.migrationId,
|
|
@@ -697,7 +737,9 @@ var MigrationTracker = class {
|
|
|
697
737
|
* Check if can rollback
|
|
698
738
|
*/
|
|
699
739
|
canRollback(fromVersion, toVersion) {
|
|
700
|
-
const fromIndex = this.migrations.findIndex(
|
|
740
|
+
const fromIndex = this.migrations.findIndex(
|
|
741
|
+
(m) => m.version === fromVersion
|
|
742
|
+
);
|
|
701
743
|
const toIndex = this.migrations.findIndex((m) => m.version === toVersion);
|
|
702
744
|
if (fromIndex === -1 || toIndex === -1) {
|
|
703
745
|
return false;
|
|
@@ -721,7 +763,9 @@ var MigrationTracker = class {
|
|
|
721
763
|
const affectedVersions = [];
|
|
722
764
|
let estimatedDuration = 0;
|
|
723
765
|
if (canRollback) {
|
|
724
|
-
const fromIndex = this.migrations.findIndex(
|
|
766
|
+
const fromIndex = this.migrations.findIndex(
|
|
767
|
+
(m) => m.version === fromVersion
|
|
768
|
+
);
|
|
725
769
|
const toIndex = this.migrations.findIndex((m) => m.version === toVersion);
|
|
726
770
|
for (let i = fromIndex; i > toIndex; i--) {
|
|
727
771
|
const migration = this.migrations[i];
|
|
@@ -777,12 +821,24 @@ var MigrationTracker = class {
|
|
|
777
821
|
* Get migration statistics
|
|
778
822
|
*/
|
|
779
823
|
getStatistics() {
|
|
780
|
-
const applied = this.migrations.filter(
|
|
824
|
+
const applied = this.migrations.filter(
|
|
825
|
+
(m) => m.status === "applied"
|
|
826
|
+
).length;
|
|
781
827
|
const failed = this.migrations.filter((m) => m.status === "failed").length;
|
|
782
|
-
const pending = this.migrations.filter(
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
const
|
|
828
|
+
const pending = this.migrations.filter(
|
|
829
|
+
(m) => m.status === "pending"
|
|
830
|
+
).length;
|
|
831
|
+
const rolledBack = this.migrations.filter(
|
|
832
|
+
(m) => m.status === "rolled-back"
|
|
833
|
+
).length;
|
|
834
|
+
const totalDuration = this.migrations.reduce(
|
|
835
|
+
(sum, m) => sum + m.duration,
|
|
836
|
+
0
|
|
837
|
+
);
|
|
838
|
+
const totalAffected = this.migrations.reduce(
|
|
839
|
+
(sum, m) => sum + m.itemsAffected,
|
|
840
|
+
0
|
|
841
|
+
);
|
|
786
842
|
return {
|
|
787
843
|
total: this.migrations.length,
|
|
788
844
|
applied,
|
|
@@ -833,7 +889,147 @@ var MigrationTracker = class {
|
|
|
833
889
|
status,
|
|
834
890
|
hasError: !!error
|
|
835
891
|
});
|
|
892
|
+
this.schedulePersist();
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Persist tracker state with integrity chain verification metadata.
|
|
897
|
+
*/
|
|
898
|
+
async saveToPersistence() {
|
|
899
|
+
if (!this.persistence) {
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
const normalizedMigrations = this.migrations.map((migration) => ({
|
|
903
|
+
...migration,
|
|
904
|
+
previousHash: void 0,
|
|
905
|
+
integrityHash: void 0
|
|
906
|
+
}));
|
|
907
|
+
const integrityEntries = [];
|
|
908
|
+
let previousHash = _MigrationTracker.INTEGRITY_ROOT;
|
|
909
|
+
for (const migration of normalizedMigrations) {
|
|
910
|
+
const hash = await this.computeDigestHex(
|
|
911
|
+
`${previousHash}|${this.stableStringify(migration)}`
|
|
912
|
+
);
|
|
913
|
+
integrityEntries.push({
|
|
914
|
+
recordId: migration.id,
|
|
915
|
+
previousHash,
|
|
916
|
+
hash
|
|
917
|
+
});
|
|
918
|
+
previousHash = hash;
|
|
919
|
+
}
|
|
920
|
+
const persistedMigrations = normalizedMigrations.map((migration, index) => ({
|
|
921
|
+
...migration,
|
|
922
|
+
previousHash: integrityEntries[index]?.previousHash,
|
|
923
|
+
integrityHash: integrityEntries[index]?.hash
|
|
924
|
+
}));
|
|
925
|
+
const data = {
|
|
926
|
+
migrations: persistedMigrations,
|
|
927
|
+
snapshots: Array.from(this.snapshots.entries()).map(
|
|
928
|
+
([recordId, snapshot]) => ({
|
|
929
|
+
recordId,
|
|
930
|
+
beforeHash: snapshot.beforeHash,
|
|
931
|
+
afterHash: snapshot.afterHash,
|
|
932
|
+
itemCount: snapshot.itemCount
|
|
933
|
+
})
|
|
934
|
+
),
|
|
935
|
+
integrity: {
|
|
936
|
+
algorithm: "sha256-chain-v1",
|
|
937
|
+
entries: integrityEntries,
|
|
938
|
+
rootHash: previousHash
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
const envelope = {
|
|
942
|
+
version: 1,
|
|
943
|
+
updatedAt: Date.now(),
|
|
944
|
+
data
|
|
945
|
+
};
|
|
946
|
+
const serialize = this.persistence.serializer ?? ((value) => JSON.stringify(value));
|
|
947
|
+
await this.persistence.adapter.setItem(this.persistence.key, serialize(envelope));
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Load tracker state and verify integrity chain.
|
|
951
|
+
*/
|
|
952
|
+
async loadFromPersistence() {
|
|
953
|
+
if (!this.persistence) {
|
|
954
|
+
return { migrations: 0, snapshots: 0 };
|
|
955
|
+
}
|
|
956
|
+
const raw = await this.persistence.adapter.getItem(this.persistence.key);
|
|
957
|
+
if (!raw) {
|
|
958
|
+
return { migrations: 0, snapshots: 0 };
|
|
959
|
+
}
|
|
960
|
+
const deserialize = this.persistence.deserializer ?? ((value) => JSON.parse(value));
|
|
961
|
+
const envelope = deserialize(raw);
|
|
962
|
+
if (envelope.version !== 1 || !envelope.data) {
|
|
963
|
+
throw new Error("Invalid migration tracker persistence payload");
|
|
964
|
+
}
|
|
965
|
+
if (!Array.isArray(envelope.data.migrations) || !Array.isArray(envelope.data.snapshots) || !envelope.data.integrity || !Array.isArray(envelope.data.integrity.entries) || typeof envelope.data.integrity.rootHash !== "string") {
|
|
966
|
+
throw new Error("Invalid migration tracker persistence structure");
|
|
967
|
+
}
|
|
968
|
+
if (envelope.data.integrity.algorithm !== "sha256-chain-v1") {
|
|
969
|
+
throw new Error("Unsupported migration integrity algorithm");
|
|
970
|
+
}
|
|
971
|
+
if (envelope.data.integrity.entries.length !== envelope.data.migrations.length) {
|
|
972
|
+
throw new Error("Migration integrity entry count mismatch");
|
|
973
|
+
}
|
|
974
|
+
const validatedMigrations = [];
|
|
975
|
+
let previousHash = _MigrationTracker.INTEGRITY_ROOT;
|
|
976
|
+
for (let i = 0; i < envelope.data.migrations.length; i++) {
|
|
977
|
+
const migration = envelope.data.migrations[i];
|
|
978
|
+
const integrity = envelope.data.integrity.entries[i];
|
|
979
|
+
if (!this.isValidMigrationRecord(migration)) {
|
|
980
|
+
throw new Error("Invalid persisted migration record");
|
|
981
|
+
}
|
|
982
|
+
if (!integrity || integrity.recordId !== migration.id || integrity.previousHash !== previousHash) {
|
|
983
|
+
throw new Error("Migration integrity chain mismatch");
|
|
984
|
+
}
|
|
985
|
+
const expectedHash = await this.computeDigestHex(
|
|
986
|
+
`${previousHash}|${this.stableStringify({
|
|
987
|
+
...migration,
|
|
988
|
+
previousHash: void 0,
|
|
989
|
+
integrityHash: void 0
|
|
990
|
+
})}`
|
|
991
|
+
);
|
|
992
|
+
if (expectedHash !== integrity.hash) {
|
|
993
|
+
throw new Error("Migration integrity verification failed");
|
|
994
|
+
}
|
|
995
|
+
validatedMigrations.push({
|
|
996
|
+
...migration,
|
|
997
|
+
previousHash: integrity.previousHash,
|
|
998
|
+
integrityHash: integrity.hash
|
|
999
|
+
});
|
|
1000
|
+
previousHash = expectedHash;
|
|
1001
|
+
}
|
|
1002
|
+
if (previousHash !== envelope.data.integrity.rootHash) {
|
|
1003
|
+
throw new Error("Migration integrity root hash mismatch");
|
|
1004
|
+
}
|
|
1005
|
+
const validatedSnapshots = /* @__PURE__ */ new Map();
|
|
1006
|
+
for (const snapshot of envelope.data.snapshots) {
|
|
1007
|
+
if (typeof snapshot.recordId !== "string" || typeof snapshot.beforeHash !== "string" || typeof snapshot.afterHash !== "string" || typeof snapshot.itemCount !== "number") {
|
|
1008
|
+
throw new Error("Invalid persisted migration snapshot");
|
|
1009
|
+
}
|
|
1010
|
+
validatedSnapshots.set(snapshot.recordId, {
|
|
1011
|
+
beforeHash: snapshot.beforeHash,
|
|
1012
|
+
afterHash: snapshot.afterHash,
|
|
1013
|
+
itemCount: snapshot.itemCount
|
|
1014
|
+
});
|
|
836
1015
|
}
|
|
1016
|
+
this.migrations = validatedMigrations;
|
|
1017
|
+
this.snapshots = validatedSnapshots;
|
|
1018
|
+
logger.debug("[MigrationTracker] Loaded from persistence", {
|
|
1019
|
+
key: this.persistence.key,
|
|
1020
|
+
migrations: this.migrations.length,
|
|
1021
|
+
snapshots: this.snapshots.size
|
|
1022
|
+
});
|
|
1023
|
+
return { migrations: this.migrations.length, snapshots: this.snapshots.size };
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Remove persisted migration tracker state.
|
|
1027
|
+
*/
|
|
1028
|
+
async clearPersistence() {
|
|
1029
|
+
if (!this.persistence) {
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
await this.persistence.adapter.removeItem(this.persistence.key);
|
|
837
1033
|
}
|
|
838
1034
|
/**
|
|
839
1035
|
* Clear history (for testing)
|
|
@@ -841,6 +1037,7 @@ var MigrationTracker = class {
|
|
|
841
1037
|
clear() {
|
|
842
1038
|
this.migrations = [];
|
|
843
1039
|
this.snapshots.clear();
|
|
1040
|
+
this.schedulePersist();
|
|
844
1041
|
}
|
|
845
1042
|
/**
|
|
846
1043
|
* Get total migrations tracked
|
|
@@ -859,6 +1056,91 @@ var MigrationTracker = class {
|
|
|
859
1056
|
return time >= start && time <= end;
|
|
860
1057
|
});
|
|
861
1058
|
}
|
|
1059
|
+
schedulePersist() {
|
|
1060
|
+
if (!this.persistence || this.persistence.autoPersist === false) {
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
if (this.persistTimer) {
|
|
1064
|
+
clearTimeout(this.persistTimer);
|
|
1065
|
+
}
|
|
1066
|
+
this.persistTimer = setTimeout(() => {
|
|
1067
|
+
void this.persistSafely();
|
|
1068
|
+
}, this.persistence.persistDebounceMs ?? 25);
|
|
1069
|
+
}
|
|
1070
|
+
async persistSafely() {
|
|
1071
|
+
if (!this.persistence) {
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
if (this.persistInFlight) {
|
|
1075
|
+
this.persistPending = true;
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
this.persistInFlight = true;
|
|
1079
|
+
try {
|
|
1080
|
+
await this.saveToPersistence();
|
|
1081
|
+
} catch (error) {
|
|
1082
|
+
logger.error("[MigrationTracker] Persistence write failed", {
|
|
1083
|
+
key: this.persistence.key,
|
|
1084
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1085
|
+
});
|
|
1086
|
+
} finally {
|
|
1087
|
+
this.persistInFlight = false;
|
|
1088
|
+
const shouldRunAgain = this.persistPending;
|
|
1089
|
+
this.persistPending = false;
|
|
1090
|
+
if (shouldRunAgain) {
|
|
1091
|
+
void this.persistSafely();
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
isValidMigrationRecord(value) {
|
|
1096
|
+
if (typeof value !== "object" || value === null) {
|
|
1097
|
+
return false;
|
|
1098
|
+
}
|
|
1099
|
+
const record = value;
|
|
1100
|
+
const validDirection = record.direction === "up" || record.direction === "down";
|
|
1101
|
+
const validStatus = record.status === "pending" || record.status === "applied" || record.status === "failed" || record.status === "rolled-back";
|
|
1102
|
+
return typeof record.id === "string" && typeof record.migrationId === "string" && typeof record.timestamp === "string" && typeof record.version === "string" && validDirection && validStatus && typeof record.duration === "number" && typeof record.itemsAffected === "number" && typeof record.appliedBy === "string";
|
|
1103
|
+
}
|
|
1104
|
+
stableStringify(value) {
|
|
1105
|
+
if (value === null || typeof value !== "object") {
|
|
1106
|
+
return JSON.stringify(value);
|
|
1107
|
+
}
|
|
1108
|
+
if (Array.isArray(value)) {
|
|
1109
|
+
return `[${value.map((item) => this.stableStringify(item)).join(",")}]`;
|
|
1110
|
+
}
|
|
1111
|
+
const entries = Object.entries(value).sort(
|
|
1112
|
+
([a], [b]) => a.localeCompare(b)
|
|
1113
|
+
);
|
|
1114
|
+
return `{${entries.map(
|
|
1115
|
+
([key, entryValue]) => `${JSON.stringify(key)}:${this.stableStringify(entryValue)}`
|
|
1116
|
+
).join(",")}}`;
|
|
1117
|
+
}
|
|
1118
|
+
async computeDigestHex(value) {
|
|
1119
|
+
if (globalThis.crypto?.subtle) {
|
|
1120
|
+
const bytes = new TextEncoder().encode(value);
|
|
1121
|
+
const normalized = bytes.buffer.slice(
|
|
1122
|
+
bytes.byteOffset,
|
|
1123
|
+
bytes.byteOffset + bytes.byteLength
|
|
1124
|
+
);
|
|
1125
|
+
const digest = await globalThis.crypto.subtle.digest(
|
|
1126
|
+
"SHA-256",
|
|
1127
|
+
normalized
|
|
1128
|
+
);
|
|
1129
|
+
return this.toHex(new Uint8Array(digest));
|
|
1130
|
+
}
|
|
1131
|
+
return this.fallbackDigestHex(value);
|
|
1132
|
+
}
|
|
1133
|
+
toHex(bytes) {
|
|
1134
|
+
return Array.from(bytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
1135
|
+
}
|
|
1136
|
+
fallbackDigestHex(value) {
|
|
1137
|
+
let hash = 2166136261;
|
|
1138
|
+
for (let i = 0; i < value.length; i++) {
|
|
1139
|
+
hash ^= value.charCodeAt(i);
|
|
1140
|
+
hash = Math.imul(hash, 16777619);
|
|
1141
|
+
}
|
|
1142
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
1143
|
+
}
|
|
862
1144
|
};
|
|
863
1145
|
|
|
864
1146
|
export { DataTransformer, MigrationEngine, MigrationTracker, SchemaVersionManager };
|