@fulmenhq/tsfulmen 0.1.13 → 0.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.
Files changed (165) hide show
  1. package/CHANGELOG.md +73 -512
  2. package/README.md +111 -28
  3. package/config/crucible-ts/agentic/roles/README.md +76 -0
  4. package/config/crucible-ts/agentic/roles/cicd.yaml +82 -0
  5. package/config/crucible-ts/agentic/roles/dataeng.yaml +104 -0
  6. package/config/crucible-ts/agentic/roles/devlead.yaml +84 -0
  7. package/config/crucible-ts/agentic/roles/devrev.yaml +105 -0
  8. package/config/crucible-ts/agentic/roles/entarch.yaml +101 -0
  9. package/config/crucible-ts/agentic/roles/infoarch.yaml +95 -0
  10. package/config/crucible-ts/agentic/roles/prodmktg.yaml +92 -0
  11. package/config/crucible-ts/agentic/roles/qa.yaml +148 -0
  12. package/config/crucible-ts/agentic/roles/secrev.yaml +101 -0
  13. package/config/crucible-ts/agentic/roles/uxdev.yaml +168 -0
  14. package/config/crucible-ts/branding/ecosystem.yaml +26 -0
  15. package/config/crucible-ts/library/foundry/exit-codes.snapshot.json +26 -0
  16. package/config/crucible-ts/library/foundry/exit-codes.yaml +28 -3
  17. package/config/crucible-ts/library/foundry/patterns.yaml +2 -2
  18. package/config/crucible-ts/library/foundry/signal-resolution-fixtures.yaml +207 -0
  19. package/config/crucible-ts/library/foundry/signals.yaml +21 -0
  20. package/config/crucible-ts/library/foundry/simplified-modes.snapshot.json +9 -1
  21. package/config/crucible-ts/library/{foundry/similarity-fixtures.yaml → similarity/fixtures.yaml} +1 -1
  22. package/config/crucible-ts/library/v1.0.0/module-manifest.yaml +1 -2
  23. package/config/crucible-ts/taxonomy/fixture-catalog.yaml +145 -0
  24. package/config/crucible-ts/taxonomy/languages.yaml +2 -2
  25. package/config/crucible-ts/taxonomy/library/foundry-catalogs/v1.1.0/catalogs.yaml +77 -0
  26. package/config/crucible-ts/taxonomy/library/platform-modules/v1.1.0/modules.yaml +722 -0
  27. package/config/crucible-ts/taxonomy/metrics.yaml +1 -1
  28. package/config/crucible-ts/taxonomy/repository-categories.yaml +134 -1
  29. package/dist/appidentity/index.d.ts +117 -35
  30. package/dist/appidentity/index.js +752 -592
  31. package/dist/appidentity/index.js.map +1 -1
  32. package/dist/config/index.js +118 -6
  33. package/dist/config/index.js.map +1 -1
  34. package/dist/crucible/index.js +118 -6
  35. package/dist/crucible/index.js.map +1 -1
  36. package/dist/errors/index.js +118 -6
  37. package/dist/errors/index.js.map +1 -1
  38. package/dist/foundry/index.d.ts +13 -676
  39. package/dist/foundry/index.js +118 -6
  40. package/dist/foundry/index.js.map +1 -1
  41. package/dist/foundry/similarity/index.d.ts +2 -2
  42. package/dist/fulhash/index.d.ts +64 -12
  43. package/dist/fulhash/index.js +292 -53
  44. package/dist/fulhash/index.js.map +1 -1
  45. package/dist/index.d.ts +2 -2
  46. package/dist/index.js +753 -593
  47. package/dist/index.js.map +1 -1
  48. package/dist/{manager-D27vrdaS.d.ts → manager-CH3fX7zO.d.ts} +1 -1
  49. package/dist/pathfinder/index.js +368 -59
  50. package/dist/pathfinder/index.js.map +1 -1
  51. package/dist/reports/license-inventory.csv +302 -0
  52. package/dist/schema/index.js +118 -6
  53. package/dist/schema/index.js.map +1 -1
  54. package/dist/signals/index.d.ts +675 -0
  55. package/dist/signals/index.js +5790 -0
  56. package/dist/signals/index.js.map +1 -0
  57. package/dist/similarity/index.d.ts +2 -0
  58. package/dist/similarity/index.js +136 -0
  59. package/dist/similarity/index.js.map +1 -0
  60. package/dist/{suggest-Cv7SVQRu.d.ts → suggest-D8LbwtPV.d.ts} +1 -1
  61. package/dist/telemetry/http/index.js +704 -591
  62. package/dist/telemetry/http/index.js.map +1 -1
  63. package/dist/telemetry/index.js +118 -6
  64. package/dist/telemetry/index.js.map +1 -1
  65. package/dist/telemetry/prometheus/index.d.ts +1 -1
  66. package/dist/telemetry/prometheus/index.js +175 -11
  67. package/dist/telemetry/prometheus/index.js.map +1 -1
  68. package/package.json +15 -6
  69. package/schemas/crucible-ts/assessment/v1.0.0/severity-definitions.schema.json +1 -1
  70. package/schemas/crucible-ts/config/fulmen-ecosystem/v1.0.0/fulmen-config-paths.schema.json +1 -1
  71. package/schemas/crucible-ts/config/repository/app-identity/v1.0.0/app-identity.schema.json +3 -3
  72. package/schemas/crucible-ts/config/repository/v1.0.0/lifecycle-phase.json +1 -1
  73. package/schemas/crucible-ts/config/repository-category/codex/v1.0.0/codex-config.schema.json +1 -1
  74. package/schemas/crucible-ts/config/standards/v1.0.0/adr-adoption-status.json +1 -1
  75. package/schemas/crucible-ts/config/standards/v1.0.0/adr-frontmatter.schema.json +3 -3
  76. package/schemas/crucible-ts/config/standards/v1.0.0/adr-lifecycle-status.json +1 -1
  77. package/schemas/crucible-ts/config/sync-keys.schema.yaml +14 -0
  78. package/schemas/crucible-ts/content/ssot-provenance/v1.0.0/ssot-provenance.schema.json +1 -1
  79. package/schemas/crucible-ts/design/README.md +159 -0
  80. package/schemas/crucible-ts/design/core/v1.0.0/component-states.schema.json +204 -0
  81. package/schemas/crucible-ts/design/core/v1.0.0/semantic-colors.schema.json +179 -0
  82. package/schemas/crucible-ts/design/core/v1.0.0/spacing-scale.schema.json +165 -0
  83. package/schemas/crucible-ts/design/core/v1.0.0/typography-roles.schema.json +195 -0
  84. package/schemas/crucible-ts/design/tui/v1.0.0/color-palette.schema.json +303 -0
  85. package/schemas/crucible-ts/design/tui/v1.0.0/component.schema.json +374 -0
  86. package/schemas/crucible-ts/design/tui/v1.0.0/layout.schema.json +272 -0
  87. package/schemas/crucible-ts/design/tui/v1.0.0/theme.schema.json +205 -0
  88. package/schemas/crucible-ts/design/tui/v1.0.0/typography.schema.json +316 -0
  89. package/schemas/crucible-ts/devsecops/lorage-central/activity/v1.0.0/activity.schema.json +1 -1
  90. package/schemas/crucible-ts/devsecops/lorage-central/credentials/v1.0.0/credentials.schema.json +1 -1
  91. package/schemas/crucible-ts/devsecops/lorage-central/policy/v1.0.0/policy.schema.json +1 -1
  92. package/schemas/crucible-ts/devsecops/lorage-central/recipe/v1.0.0/recipe.schema.json +1 -1
  93. package/schemas/crucible-ts/devsecops/lorage-central/runbooks/v1.0.0/runbook.schema.json +1 -1
  94. package/schemas/crucible-ts/devsecops/lorage-central/tenant/v1.0.0/tenant.schema.json +1 -1
  95. package/schemas/crucible-ts/devsecops/secrets/v1.0.0/secrets.schema.json +1 -1
  96. package/schemas/crucible-ts/error-handling/v1.0.0/error-response.schema.json +1 -1
  97. package/schemas/crucible-ts/library/foundry/v1.0.0/country-codes.schema.json +1 -1
  98. package/schemas/crucible-ts/library/foundry/v1.0.0/exit-codes.schema.json +1 -1
  99. package/schemas/crucible-ts/library/foundry/v1.0.0/http-status-groups.schema.json +1 -1
  100. package/schemas/crucible-ts/library/foundry/v1.0.0/mime-types.schema.json +1 -1
  101. package/schemas/crucible-ts/library/foundry/v1.0.0/patterns.schema.json +1 -1
  102. package/schemas/crucible-ts/library/foundry/v1.0.0/signal-resolution-fixtures.schema.json +140 -0
  103. package/schemas/crucible-ts/library/foundry/v1.0.0/signals.schema.json +6 -1
  104. package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-config.schema.json +1 -1
  105. package/schemas/crucible-ts/library/fulhash/v1.0.0/checksum-string.schema.json +2 -2
  106. package/schemas/crucible-ts/library/fulhash/v1.0.0/digest.schema.json +61 -1
  107. package/schemas/crucible-ts/library/fulhash/v1.0.0/fixtures.schema.json +1 -1
  108. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-entry.schema.json +1 -1
  109. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-info.schema.json +1 -1
  110. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-manifest.schema.json +2 -2
  111. package/schemas/crucible-ts/library/fulpack/v1.0.0/create-options.schema.json +1 -1
  112. package/schemas/crucible-ts/library/fulpack/v1.0.0/extract-options.schema.json +1 -1
  113. package/schemas/crucible-ts/library/fulpack/v1.0.0/extract-result.schema.json +1 -1
  114. package/schemas/crucible-ts/library/fulpack/v1.0.0/scan-options.schema.json +1 -1
  115. package/schemas/crucible-ts/library/fulpack/v1.0.0/validation-result.schema.json +1 -1
  116. package/schemas/crucible-ts/library/module-manifest/v1.0.0/module-manifest.schema.json +1 -1
  117. package/schemas/crucible-ts/library/{foundry → similarity}/v1.0.0/similarity.schema.json +2 -2
  118. package/schemas/crucible-ts/library/{foundry → similarity}/v2.0.0/similarity.schema.json +2 -2
  119. package/schemas/crucible-ts/observability/metrics/v1.0.0/metrics-event.schema.json +1 -1
  120. package/schemas/crucible-ts/pathfinder/v1.0.0/find-query.schema.json +1 -1
  121. package/schemas/crucible-ts/pathfinder/v1.0.0/finder-config.schema.json +1 -1
  122. package/schemas/crucible-ts/pathfinder/v1.0.0/path-result.schema.json +1 -1
  123. package/schemas/crucible-ts/protocol/http/v1.0.0/error-response.schema.json +1 -1
  124. package/schemas/crucible-ts/protocol/http/v1.0.0/health-response.schema.json +1 -1
  125. package/schemas/crucible-ts/protocol/http/v1.0.0/success-response.schema.json +1 -1
  126. package/schemas/crucible-ts/protocol/http/v1.0.0/version-response.schema.json +1 -1
  127. package/schemas/crucible-ts/server/management/v1.0.0/server-management.schema.json +1 -1
  128. package/schemas/crucible-ts/standards/publishing/v1.0.0/spec-catalog.schema.json +134 -0
  129. package/schemas/crucible-ts/taxonomy/devsecops/auth-methods/v1.0.0/auth-methods-key.schema.json +1 -1
  130. package/schemas/crucible-ts/taxonomy/devsecops/auth-methods/v1.0.0/auth-methods-metadata.schema.json +1 -1
  131. package/schemas/crucible-ts/taxonomy/devsecops/geo/v1.0.0/geo-key.schema.json +1 -1
  132. package/schemas/crucible-ts/taxonomy/devsecops/geo/v1.0.0/geo-metadata.schema.json +1 -1
  133. package/schemas/crucible-ts/taxonomy/devsecops/infra-phases/v1.0.0/infra-phases-key.schema.json +1 -1
  134. package/schemas/crucible-ts/taxonomy/devsecops/infra-phases/v1.0.0/infra-phases-metadata.schema.json +1 -1
  135. package/schemas/crucible-ts/taxonomy/devsecops/infra-providers/v1.0.0/infra-providers-key.schema.json +1 -1
  136. package/schemas/crucible-ts/taxonomy/devsecops/infra-providers/v1.0.0/infra-providers-metadata.schema.json +1 -1
  137. package/schemas/crucible-ts/taxonomy/devsecops/modules/v1.0.0/devsecops-module-entry.schema.json +1 -1
  138. package/schemas/crucible-ts/taxonomy/fixture/v1.0.0/fixture-catalog.schema.json +166 -0
  139. package/schemas/crucible-ts/taxonomy/language/v1.0.0/language-key.schema.json +1 -1
  140. package/schemas/crucible-ts/taxonomy/language/v1.0.0/language-metadata.schema.json +1 -1
  141. package/schemas/crucible-ts/taxonomy/library/foundry-catalogs/v1.1.0/catalog-entry.schema.json +98 -0
  142. package/schemas/crucible-ts/taxonomy/library/fulencode/detection-confidence/v1.0.0/levels.schema.json +1 -1
  143. package/schemas/crucible-ts/taxonomy/library/fulencode/encoding-families/v1.0.0/families.schema.json +1 -1
  144. package/schemas/crucible-ts/taxonomy/library/fulencode/normalization-profiles/v1.0.0/profiles.schema.json +1 -1
  145. package/schemas/crucible-ts/taxonomy/library/fulhash/algorithms/v1.0.0/algorithms.yaml +16 -0
  146. package/schemas/crucible-ts/taxonomy/library/modules/v1.0.0/module-entry.schema.json +1 -1
  147. package/schemas/crucible-ts/taxonomy/library/modules/v1.1.0/module-entry.schema.json +436 -0
  148. package/schemas/crucible-ts/taxonomy/repository-category/v1.0.0/category-key.schema.json +16 -8
  149. package/schemas/crucible-ts/taxonomy/repository-category/v1.0.0/category-metadata.schema.json +1 -1
  150. package/schemas/crucible-ts/upstream/3leaps/PROVENANCE.md +43 -0
  151. package/schemas/crucible-ts/upstream/3leaps/agentic/v0/role-prompt.schema.json +183 -0
  152. package/schemas/crucible-ts/upstream/3leaps/ailink/v0/prompt.schema.json +204 -0
  153. package/schemas/crucible-ts/upstream/3leaps/ailink/v0/search-response.schema.json +152 -0
  154. package/schemas/crucible-ts/upstream/README.md +50 -0
  155. package/schemas/crucible-ts/web/branding/v1.0.0/site-branding.schema.json +1 -1
  156. package/schemas/crucible-ts/web/styling/v1.0.0/site-styling.schema.json +1 -1
  157. package/schemas/crucible-ts/config/goneat/README.md +0 -60
  158. package/schemas/crucible-ts/config/goneat/v1.0.0/dates.yaml +0 -234
  159. package/schemas/crucible-ts/config/goneat/v1.0.0/goneat-config.yaml +0 -344
  160. package/schemas/crucible-ts/config/goneat/v1.0.0/lifecycle-phase.json +0 -20
  161. package/schemas/crucible-ts/config/goneat/v1.0.0/release-phase.json +0 -17
  162. package/schemas/crucible-ts/config/goneat/v1.0.0/security-policy.yaml +0 -178
  163. package/schemas/crucible-ts/config/goneat/v1.0.0/version-policy.schema.yaml +0 -205
  164. package/schemas/crucible-ts/tooling/goneat-tools/v1.0.0/README.md +0 -177
  165. package/schemas/crucible-ts/tooling/goneat-tools/v1.0.0/goneat-tools-config.schema.yaml +0 -146
@@ -1,5 +1,5 @@
1
- import { F as FoundryCatalogError } from '../../suggest-Cv7SVQRu.js';
2
- export { M as MetricType, N as NormalizationPreset, f as NormalizeOptions, g as SuggestOptions, S as Suggestion, c as casefold, d as distance, e as equalsIgnoreCase, n as normalize, a as score, s as stripAccents, b as suggest } from '../../suggest-Cv7SVQRu.js';
1
+ import { F as FoundryCatalogError } from '../../suggest-D8LbwtPV.js';
2
+ export { M as MetricType, g as NormalizationPreset, N as NormalizeOptions, a as SuggestOptions, S as Suggestion, c as casefold, d as distance, e as equalsIgnoreCase, n as normalize, s as score, b as stripAccents, f as suggest } from '../../suggest-D8LbwtPV.js';
3
3
 
4
4
  declare class SimilarityError extends FoundryCatalogError {
5
5
  constructor(message: string, cause?: Error);
@@ -1,28 +1,80 @@
1
1
  /**
2
- * Type definitions for FulHash hashing module
2
+ * FulHash Types
3
+ * Code generated by scripts/codegen/generate-fulhash-types.ts; DO NOT EDIT.
4
+ */
5
+ /**
6
+ * Supported hashing algorithms for FulHash
3
7
  */
4
8
  declare enum Algorithm {
9
+ /**
10
+ * XXH3 (128-bit)
11
+ * Fast non-cryptographic hash (default). Excellent collision resistance, extremely high throughput (50GB/s+).
12
+ */
5
13
  XXH3_128 = "xxh3-128",
6
- SHA256 = "sha256"
7
- }
8
- interface HashOptions {
9
- algorithm?: Algorithm;
10
- encoding?: BufferEncoding;
14
+ /**
15
+ * SHA-256
16
+ * Cryptographic security standard. Resistant to intentional collisions. Use for security verification.
17
+ */
18
+ SHA256 = "sha256",
19
+ /**
20
+ * CRC-32 (IEEE)
21
+ * 32-bit Cyclic Redundancy Check. Standard for GZIP/ZIP/PNG legacy format interoperability.
22
+ */
23
+ CRC32 = "crc32",
24
+ /**
25
+ * CRC-32C (Castagnoli)
26
+ * 32-bit CRC (Castagnoli). HW accelerated (SSE4.2/ARMv8). Use for cloud storage (GCS, AWS) and networking.
27
+ */
28
+ CRC32C = "crc32c"
11
29
  }
30
+ /**
31
+ * Standard digest payload returned by FulHash helpers
32
+ */
12
33
  interface Digest$1 {
13
- algorithm: Algorithm;
34
+ /**
35
+ * Hash algorithm identifier
36
+ */
37
+ algorithm: "xxh3-128" | "crc32" | "crc32c" | "sha256";
38
+ /**
39
+ * Lowercase hexadecimal representation of the digest
40
+ */
14
41
  hex: string;
15
- bytes: Uint8Array;
42
+ /**
43
+ * Canonical string representation '<algorithm>:<hex>'
44
+ */
16
45
  formatted: string;
46
+ /**
47
+ * Raw digest bytes (optional)
48
+ */
49
+ bytes?: number[];
17
50
  }
18
- interface StreamHasherOptions {
51
+
52
+ interface HashOptions {
19
53
  algorithm?: Algorithm;
54
+ encoding?: BufferEncoding;
20
55
  }
21
56
  interface StreamHasher {
22
57
  update(data: string | Uint8Array): StreamHasher;
23
58
  digest(): Digest$1;
24
59
  reset(): StreamHasher;
25
60
  }
61
+ interface StreamHasherOptions {
62
+ algorithm?: Algorithm;
63
+ }
64
+ type MultiHashResult = Partial<Record<Algorithm, Digest$1>>;
65
+
66
+ type HashInput = string | Uint8Array | AsyncIterable<string | Uint8Array>;
67
+ /**
68
+ * Compute multiple hashes in a single pass over the data.
69
+ * Useful for generating checksums for multiple algorithms (e.g. SHA256 + XXH3)
70
+ * without reading the stream multiple times.
71
+ */
72
+ declare function multiHash(input: HashInput, algorithms: Algorithm[], encoding?: BufferEncoding): Promise<MultiHashResult>;
73
+ /**
74
+ * Verify data against a formatted checksum (e.g. "sha256:abc...").
75
+ * Automatically selects the algorithm from the checksum prefix.
76
+ */
77
+ declare function verify(input: HashInput, checksum: string, encoding?: BufferEncoding): Promise<boolean>;
26
78
 
27
79
  /**
28
80
  * Digest implementation - immutable hash result container
@@ -34,7 +86,7 @@ declare class Digest implements Digest$1 {
34
86
  readonly hex: string;
35
87
  readonly formatted: string;
36
88
  constructor(algorithm: Algorithm, bytes: Uint8Array);
37
- get bytes(): Uint8Array;
89
+ get bytes(): number[];
38
90
  toJSON(): object;
39
91
  toString(): string;
40
92
  static parse(formatted: string): Digest;
@@ -74,9 +126,9 @@ declare function createStreamHasher(options?: StreamHasherOptions): Promise<Stre
74
126
  /**
75
127
  * FulHash - Consistent hashing API for Fulmen ecosystem
76
128
  *
77
- * Provides block and streaming hashing with xxh3-128 and sha256 algorithms.
129
+ * Provides block and streaming hashing with XXH3-128, SHA-256, CRC32, and CRC32C algorithms.
78
130
  * Cross-language compatible with gofulmen and pyfulmen.
79
131
  */
80
132
  declare const VERSION = "1.0.0";
81
133
 
82
- export { Algorithm, Digest, DigestStateError, FulHashError, type HashOptions, InvalidChecksumError, InvalidChecksumFormatError, type StreamHasher, type StreamHasherOptions, UnsupportedAlgorithmError, VERSION, createStreamHasher, hash, hashBytes, hashString };
134
+ export { Algorithm, Digest, DigestStateError, FulHashError, type HashInput, type HashOptions, InvalidChecksumError, InvalidChecksumFormatError, type StreamHasher, type StreamHasherOptions, UnsupportedAlgorithmError, VERSION, createStreamHasher, hash, hashBytes, hashString, multiHash, verify };
@@ -1,5 +1,5 @@
1
+ import { crc32, xxhash128, createXXHash128, createCRC32 } from 'hash-wasm';
1
2
  import { createHash } from 'crypto';
2
- import { xxhash128, createXXHash128 } from 'hash-wasm';
3
3
 
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -11,6 +11,20 @@ var __export = (target, all) => {
11
11
  __defProp(target, name, { get: all[name], enumerable: true });
12
12
  };
13
13
 
14
+ // src/crucible/fulhash/types.ts
15
+ var Algorithm;
16
+ var init_types = __esm({
17
+ "src/crucible/fulhash/types.ts"() {
18
+ Algorithm = /* @__PURE__ */ ((Algorithm2) => {
19
+ Algorithm2["XXH3_128"] = "xxh3-128";
20
+ Algorithm2["SHA256"] = "sha256";
21
+ Algorithm2["CRC32"] = "crc32";
22
+ Algorithm2["CRC32C"] = "crc32c";
23
+ return Algorithm2;
24
+ })(Algorithm || {});
25
+ }
26
+ });
27
+
14
28
  // src/fulhash/errors.ts
15
29
  var FulHashError, UnsupportedAlgorithmError, InvalidChecksumError, InvalidChecksumFormatError, DigestStateError;
16
30
  var init_errors = __esm({
@@ -54,24 +68,70 @@ var init_errors = __esm({
54
68
  };
55
69
  }
56
70
  });
57
-
58
- // src/fulhash/types.ts
59
- var Algorithm;
60
- var init_types = __esm({
61
- "src/fulhash/types.ts"() {
62
- Algorithm = /* @__PURE__ */ ((Algorithm2) => {
63
- Algorithm2["XXH3_128"] = "xxh3-128";
64
- Algorithm2["SHA256"] = "sha256";
65
- return Algorithm2;
66
- })(Algorithm || {});
71
+ function hexToBytes(hex) {
72
+ const bytes = new Uint8Array(4);
73
+ for (let i = 0; i < 4; i++) {
74
+ bytes[i] = Number.parseInt(hex.substr(i * 2, 2), 16);
75
+ }
76
+ return bytes;
77
+ }
78
+ async function hashBytes(data) {
79
+ const hex = await crc32(data);
80
+ return hexToBytes(hex);
81
+ }
82
+ async function hashString(str, encoding = "utf8") {
83
+ if (encoding !== "utf8") {
84
+ const buf = Buffer.from(str, encoding);
85
+ const hex2 = await crc32(buf);
86
+ return hexToBytes(hex2);
87
+ }
88
+ const hex = await crc32(str);
89
+ return hexToBytes(hex);
90
+ }
91
+ async function createHasher() {
92
+ const hasher = await createCRC32();
93
+ return hasher;
94
+ }
95
+ var init_crc32 = __esm({
96
+ "src/fulhash/algorithms/crc32.ts"() {
67
97
  }
68
98
  });
69
- function hashBytes(data) {
99
+ function hexToBytes2(hex) {
100
+ const bytes = new Uint8Array(4);
101
+ for (let i = 0; i < 4; i++) {
102
+ bytes[i] = Number.parseInt(hex.substr(i * 2, 2), 16);
103
+ }
104
+ return bytes;
105
+ }
106
+ async function hashBytes2(data) {
107
+ const hex = await crc32(data, CRC32C_POLYNOMIAL);
108
+ return hexToBytes2(hex);
109
+ }
110
+ async function hashString2(str, encoding = "utf8") {
111
+ if (encoding !== "utf8") {
112
+ const buf = Buffer.from(str, encoding);
113
+ const hex2 = await crc32(buf, CRC32C_POLYNOMIAL);
114
+ return hexToBytes2(hex2);
115
+ }
116
+ const hex = await crc32(str, CRC32C_POLYNOMIAL);
117
+ return hexToBytes2(hex);
118
+ }
119
+ async function createHasher2() {
120
+ const hasher = await createCRC32(CRC32C_POLYNOMIAL);
121
+ return hasher;
122
+ }
123
+ var CRC32C_POLYNOMIAL;
124
+ var init_crc32c = __esm({
125
+ "src/fulhash/algorithms/crc32c.ts"() {
126
+ CRC32C_POLYNOMIAL = 2197175160;
127
+ }
128
+ });
129
+ function hashBytes3(data) {
70
130
  const hash2 = createHash("sha256");
71
131
  hash2.update(data);
72
132
  return new Uint8Array(hash2.digest());
73
133
  }
74
- function hashString(str, encoding = "utf8") {
134
+ function hashString3(str, encoding = "utf8") {
75
135
  const hash2 = createHash("sha256");
76
136
  hash2.update(str, encoding);
77
137
  return new Uint8Array(hash2.digest());
@@ -80,25 +140,25 @@ var init_sha256 = __esm({
80
140
  "src/fulhash/algorithms/sha256.ts"() {
81
141
  }
82
142
  });
83
- function hexToBytes(hex) {
143
+ function hexToBytes3(hex) {
84
144
  const bytes = new Uint8Array(16);
85
145
  for (let i = 0; i < 16; i++) {
86
146
  bytes[i] = Number.parseInt(hex.substr(i * 2, 2), 16);
87
147
  }
88
148
  return bytes;
89
149
  }
90
- async function hashBytes2(data) {
150
+ async function hashBytes4(data) {
91
151
  const hex = await xxhash128(data);
92
- return hexToBytes(hex);
152
+ return hexToBytes3(hex);
93
153
  }
94
- async function hashString2(str, encoding = "utf8") {
154
+ async function hashString4(str, encoding = "utf8") {
95
155
  if (encoding !== "utf8") {
96
156
  throw new FulHashError(
97
157
  "XXH3-128 only supports UTF-8 encoding. Use utf8 encoding or convert data to Uint8Array."
98
158
  );
99
159
  }
100
160
  const hex = await xxhash128(str);
101
- return hexToBytes(hex);
161
+ return hexToBytes3(hex);
102
162
  }
103
163
  var init_xxh3 = __esm({
104
164
  "src/fulhash/algorithms/xxh3.ts"() {
@@ -110,43 +170,66 @@ var init_xxh3 = __esm({
110
170
  var hash_exports = {};
111
171
  __export(hash_exports, {
112
172
  hash: () => hash,
113
- hashBytes: () => hashBytes3,
114
- hashString: () => hashString3
173
+ hashBytes: () => hashBytes5,
174
+ hashString: () => hashString5
115
175
  });
116
176
  async function hash(input, options) {
117
177
  const algorithm = options?.algorithm ?? "xxh3-128" /* XXH3_128 */;
118
178
  const encoding = options?.encoding ?? "utf8";
119
179
  let bytes;
120
- if (algorithm === "sha256" /* SHA256 */) {
121
- if (typeof input === "string") {
122
- bytes = hashString(input, encoding);
123
- } else {
124
- bytes = hashBytes(input);
125
- }
126
- } else if (algorithm === "xxh3-128" /* XXH3_128 */) {
127
- if (typeof input === "string") {
128
- bytes = await hashString2(input, "utf8");
129
- } else {
130
- bytes = await hashBytes2(input);
131
- }
132
- } else {
133
- throw new UnsupportedAlgorithmError(algorithm, ["sha256" /* SHA256 */, "xxh3-128" /* XXH3_128 */]);
180
+ switch (algorithm) {
181
+ case "sha256" /* SHA256 */:
182
+ if (typeof input === "string") {
183
+ bytes = hashString3(input, encoding);
184
+ } else {
185
+ bytes = hashBytes3(input);
186
+ }
187
+ break;
188
+ case "xxh3-128" /* XXH3_128 */:
189
+ if (typeof input === "string") {
190
+ if (encoding !== "utf8") {
191
+ bytes = await hashBytes4(Buffer.from(input, encoding));
192
+ } else {
193
+ bytes = await hashString4(input, "utf8");
194
+ }
195
+ } else {
196
+ bytes = await hashBytes4(input);
197
+ }
198
+ break;
199
+ case "crc32" /* CRC32 */:
200
+ if (typeof input === "string") {
201
+ bytes = await hashString(input, encoding);
202
+ } else {
203
+ bytes = await hashBytes(input);
204
+ }
205
+ break;
206
+ case "crc32c" /* CRC32C */:
207
+ if (typeof input === "string") {
208
+ bytes = await hashString2(input, encoding);
209
+ } else {
210
+ bytes = await hashBytes2(input);
211
+ }
212
+ break;
213
+ default:
214
+ throw new UnsupportedAlgorithmError(algorithm, Object.values(Algorithm));
134
215
  }
135
216
  return new Digest(algorithm, bytes);
136
217
  }
137
- async function hashString3(str, options) {
218
+ async function hashString5(str, options) {
138
219
  return hash(str, options);
139
220
  }
140
- async function hashBytes3(data, options) {
221
+ async function hashBytes5(data, options) {
141
222
  return hash(data, options);
142
223
  }
143
224
  var init_hash = __esm({
144
225
  "src/fulhash/hash.ts"() {
226
+ init_types();
227
+ init_crc32();
228
+ init_crc32c();
145
229
  init_sha256();
146
230
  init_xxh3();
147
231
  init_digest();
148
232
  init_errors();
149
- init_types();
150
233
  }
151
234
  });
152
235
 
@@ -154,8 +237,8 @@ var init_hash = __esm({
154
237
  var Digest;
155
238
  var init_digest = __esm({
156
239
  "src/fulhash/digest.ts"() {
157
- init_errors();
158
240
  init_types();
241
+ init_errors();
159
242
  Digest = class _Digest {
160
243
  algorithm;
161
244
  _bytes;
@@ -169,7 +252,7 @@ var init_digest = __esm({
169
252
  Object.freeze(this);
170
253
  }
171
254
  get bytes() {
172
- return new Uint8Array(this._bytes);
255
+ return Array.from(this._bytes);
173
256
  }
174
257
  toJSON() {
175
258
  return {
@@ -199,7 +282,21 @@ var init_digest = __esm({
199
282
  "hex must contain only lowercase hexadecimal characters"
200
283
  );
201
284
  }
202
- const expectedLength = algorithm === "xxh3-128" /* XXH3_128 */ ? 32 : 64;
285
+ let expectedLength;
286
+ switch (algorithm) {
287
+ case "xxh3-128" /* XXH3_128 */:
288
+ expectedLength = 32;
289
+ break;
290
+ case "sha256" /* SHA256 */:
291
+ expectedLength = 64;
292
+ break;
293
+ case "crc32" /* CRC32 */:
294
+ case "crc32c" /* CRC32C */:
295
+ expectedLength = 8;
296
+ break;
297
+ default:
298
+ throw new UnsupportedAlgorithmError(algorithm, Object.values(Algorithm));
299
+ }
203
300
  if (hex.length !== expectedLength) {
204
301
  throw new InvalidChecksumError(
205
302
  formatted,
@@ -232,14 +329,17 @@ var init_digest = __esm({
232
329
  });
233
330
 
234
331
  // src/fulhash/index.ts
332
+ init_types();
333
+
334
+ // src/fulhash/convenience.ts
235
335
  init_digest();
236
- init_errors();
237
- init_hash();
238
336
 
239
337
  // src/fulhash/stream.ts
338
+ init_types();
339
+ init_crc32();
340
+ init_crc32c();
240
341
  init_digest();
241
342
  init_errors();
242
- init_types();
243
343
 
244
344
  // src/fulhash/wasm-loader.ts
245
345
  init_errors();
@@ -260,7 +360,7 @@ async function initializeWasm() {
260
360
  });
261
361
  return initPromise;
262
362
  }
263
- async function createHasher() {
363
+ async function createHasher3() {
264
364
  if (!isWasmReady) {
265
365
  throw new FulHashError("WASM not initialized. Call initializeWasm() first.");
266
366
  }
@@ -268,6 +368,15 @@ async function createHasher() {
268
368
  }
269
369
 
270
370
  // src/fulhash/stream.ts
371
+ function intToBytes(crc) {
372
+ const bytes = new Uint8Array(4);
373
+ const unsigned = crc >>> 0;
374
+ bytes[0] = unsigned >>> 24 & 255;
375
+ bytes[1] = unsigned >>> 16 & 255;
376
+ bytes[2] = unsigned >>> 8 & 255;
377
+ bytes[3] = unsigned & 255;
378
+ return bytes;
379
+ }
271
380
  var BaseStreamHasher = class {
272
381
  state = "initial" /* INITIAL */;
273
382
  algorithm;
@@ -352,23 +461,153 @@ var XXH3StreamHasher = class extends BaseStreamHasher {
352
461
  return this;
353
462
  }
354
463
  };
464
+ var CRC32StreamHasher = class extends BaseStreamHasher {
465
+ hasher = null;
466
+ constructor() {
467
+ super("crc32" /* CRC32 */);
468
+ }
469
+ async init() {
470
+ this.hasher = await createHasher();
471
+ this.hasher.init();
472
+ }
473
+ update(data) {
474
+ this.ensureNotFinalized();
475
+ this.markUpdating();
476
+ if (!this.hasher) {
477
+ throw new Error("Hasher not initialized");
478
+ }
479
+ if (typeof data === "string") {
480
+ const encoder = new TextEncoder();
481
+ this.hasher.update(encoder.encode(data));
482
+ } else {
483
+ this.hasher.update(data);
484
+ }
485
+ return this;
486
+ }
487
+ digest() {
488
+ this.ensureUpdating();
489
+ this.markFinalized();
490
+ if (!this.hasher) throw new Error("Hasher not initialized");
491
+ const hex = this.hasher.digest();
492
+ const bytes = intToBytes(parseInt(hex, 16));
493
+ return new Digest(this.algorithm, bytes);
494
+ }
495
+ reset() {
496
+ if (!this.hasher) throw new Error("Hasher not initialized");
497
+ this.hasher.init();
498
+ this.markInitial();
499
+ return this;
500
+ }
501
+ };
502
+ var CRC32CStreamHasher = class extends BaseStreamHasher {
503
+ hasher = null;
504
+ constructor() {
505
+ super("crc32c" /* CRC32C */);
506
+ }
507
+ async init() {
508
+ this.hasher = await createHasher2();
509
+ this.hasher.init();
510
+ }
511
+ update(data) {
512
+ this.ensureNotFinalized();
513
+ this.markUpdating();
514
+ if (!this.hasher) throw new Error("Hasher not initialized");
515
+ if (typeof data === "string") {
516
+ const encoder = new TextEncoder();
517
+ this.hasher.update(encoder.encode(data));
518
+ } else {
519
+ this.hasher.update(data);
520
+ }
521
+ return this;
522
+ }
523
+ digest() {
524
+ this.ensureUpdating();
525
+ this.markFinalized();
526
+ if (!this.hasher) throw new Error("Hasher not initialized");
527
+ const hex = this.hasher.digest();
528
+ const bytes = intToBytes(parseInt(hex, 16));
529
+ return new Digest(this.algorithm, bytes);
530
+ }
531
+ reset() {
532
+ if (!this.hasher) throw new Error("Hasher not initialized");
533
+ this.hasher.init();
534
+ this.markInitial();
535
+ return this;
536
+ }
537
+ };
355
538
  async function createStreamHasher(options = {}) {
356
539
  const algorithm = options.algorithm ?? "xxh3-128" /* XXH3_128 */;
357
- if (algorithm === "sha256" /* SHA256 */) {
358
- return new SHA256StreamHasher();
540
+ switch (algorithm) {
541
+ case "sha256" /* SHA256 */:
542
+ return new SHA256StreamHasher();
543
+ case "xxh3-128" /* XXH3_128 */: {
544
+ await initializeWasm();
545
+ const wasmHasher = await createHasher3();
546
+ return new XXH3StreamHasher(wasmHasher);
547
+ }
548
+ case "crc32" /* CRC32 */: {
549
+ const hasher = new CRC32StreamHasher();
550
+ await hasher.init();
551
+ return hasher;
552
+ }
553
+ case "crc32c" /* CRC32C */: {
554
+ const hasher = new CRC32CStreamHasher();
555
+ await hasher.init();
556
+ return hasher;
557
+ }
558
+ default:
559
+ throw new UnsupportedAlgorithmError(algorithm, Object.values(Algorithm));
560
+ }
561
+ }
562
+
563
+ // src/fulhash/convenience.ts
564
+ async function multiHash(input, algorithms, encoding = "utf8") {
565
+ const uniqueAlgorithms = [...new Set(algorithms)];
566
+ const hashers = await Promise.all(
567
+ uniqueAlgorithms.map((algo) => createStreamHasher({ algorithm: algo }))
568
+ );
569
+ if (typeof input === "string") {
570
+ if (encoding !== "utf8") {
571
+ const buf = Buffer.from(input, encoding);
572
+ for (const hasher of hashers) {
573
+ hasher.update(buf);
574
+ }
575
+ } else {
576
+ for (const hasher of hashers) {
577
+ hasher.update(input);
578
+ }
579
+ }
580
+ } else if (input instanceof Uint8Array) {
581
+ for (const hasher of hashers) {
582
+ hasher.update(input);
583
+ }
584
+ } else {
585
+ for await (const chunk of input) {
586
+ for (const hasher of hashers) {
587
+ hasher.update(chunk);
588
+ }
589
+ }
359
590
  }
360
- if (algorithm === "xxh3-128" /* XXH3_128 */) {
361
- await initializeWasm();
362
- const wasmHasher = await createHasher();
363
- return new XXH3StreamHasher(wasmHasher);
591
+ const result = {};
592
+ for (let i = 0; i < uniqueAlgorithms.length; i++) {
593
+ result[uniqueAlgorithms[i]] = hashers[i].digest();
364
594
  }
365
- throw new UnsupportedAlgorithmError(algorithm, ["sha256" /* SHA256 */, "xxh3-128" /* XXH3_128 */]);
595
+ return result;
596
+ }
597
+ async function verify(input, checksum, encoding = "utf8") {
598
+ const expected = Digest.parse(checksum);
599
+ const result = await multiHash(input, [expected.algorithm], encoding);
600
+ const actual = result[expected.algorithm];
601
+ if (!actual) return false;
602
+ return actual.algorithm === expected.algorithm && actual.hex === expected.hex;
366
603
  }
367
604
 
368
605
  // src/fulhash/index.ts
369
- init_types();
606
+ init_digest();
607
+ init_errors();
608
+ init_hash();
370
609
  var VERSION = "1.0.0";
371
610
 
372
- export { Algorithm, Digest, DigestStateError, FulHashError, InvalidChecksumError, InvalidChecksumFormatError, UnsupportedAlgorithmError, VERSION, createStreamHasher, hash, hashBytes3 as hashBytes, hashString3 as hashString };
611
+ export { Algorithm, Digest, DigestStateError, FulHashError, InvalidChecksumError, InvalidChecksumFormatError, UnsupportedAlgorithmError, VERSION, createStreamHasher, hash, hashBytes5 as hashBytes, hashString5 as hashString, multiHash, verify };
373
612
  //# sourceMappingURL=index.js.map
374
613
  //# sourceMappingURL=index.js.map