scxq2-cc 1.0.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/src/index.js ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @asx/scxq2-cc - SCXQ2 Compression Calculus Engine
3
+ *
4
+ * A deterministic, proof-generating compression engine that produces
5
+ * content-addressable language packs following the frozen SCXQ2 specification.
6
+ *
7
+ * @module @asx/scxq2-cc
8
+ * @version 1.0.0
9
+ *
10
+ * @example
11
+ * // Basic compression
12
+ * import { ccCompress, ccDecompress } from '@asx/scxq2-cc';
13
+ *
14
+ * const pack = await ccCompress('function hello() { console.log("Hello"); }');
15
+ * console.log(pack.proof.ok); // true
16
+ *
17
+ * const roundtrip = ccDecompress(pack.dict, pack.block);
18
+ * // roundtrip === original input
19
+ *
20
+ * @example
21
+ * // Multi-lane compression
22
+ * import { ccCompressLanes } from '@asx/scxq2-cc';
23
+ *
24
+ * const pack = await ccCompressLanes({
25
+ * lanes: [
26
+ * { lane_id: 'main', text: 'function main() {}' },
27
+ * { lane_id: 'util', text: 'function util() {}' }
28
+ * ]
29
+ * });
30
+ */
31
+
32
+ // Re-export engine API
33
+ export {
34
+ CC_ENGINE,
35
+ SCXQ2_ENCODING,
36
+ CC_OPS,
37
+ ccCompress,
38
+ ccCompressSync,
39
+ ccCompressLanes,
40
+ ccCompressLanesSync,
41
+ ccDecompress,
42
+ verifyPack
43
+ } from "./engine.js";
44
+
45
+ // Re-export utilities for advanced use
46
+ export { canon, sortKeysDeep, strip } from "./canon.js";
47
+ export { sha256HexUtf8, sha256HexUtf8Sync, getNodeCrypto } from "./sha.js";
48
+ export { bytesToBase64, base64ToBytes, isValidBase64 } from "./base64.js";
package/src/sha.js ADDED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * SCXQ2 SHA-256 Utilities
3
+ *
4
+ * Universal SHA-256 hashing that works in Node.js, browsers, and workers.
5
+ * Provides both async (WebCrypto) and sync (Node crypto) implementations.
6
+ *
7
+ * @module @asx/scxq2-cc/sha
8
+ * @version 1.0.0
9
+ */
10
+
11
+ /**
12
+ * Computes SHA-256 hash of UTF-8 text, returning hex string.
13
+ * Uses WebCrypto when available, falls back to Node crypto.
14
+ *
15
+ * @param {string} text - UTF-8 text to hash
16
+ * @returns {Promise<string>} Hex-encoded SHA-256 hash
17
+ */
18
+ export async function sha256HexUtf8(text) {
19
+ // WebCrypto (browser / worker)
20
+ if (globalThis.crypto?.subtle) {
21
+ const data = new TextEncoder().encode(text);
22
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", data);
23
+ return [...new Uint8Array(digest)]
24
+ .map(b => b.toString(16).padStart(2, "0"))
25
+ .join("");
26
+ }
27
+
28
+ // Node.js
29
+ const { createHash } = await import("crypto");
30
+ return createHash("sha256").update(text, "utf8").digest("hex");
31
+ }
32
+
33
+ /**
34
+ * Synchronous SHA-256 hash (Node.js only).
35
+ * Throws if crypto module is not available.
36
+ *
37
+ * @param {string} text - UTF-8 text to hash
38
+ * @param {Object} [nodeCrypto] - Pre-imported crypto module (optional)
39
+ * @returns {string} Hex-encoded SHA-256 hash
40
+ */
41
+ export function sha256HexUtf8Sync(text, nodeCrypto = null) {
42
+ if (nodeCrypto) {
43
+ return nodeCrypto.createHash("sha256").update(text, "utf8").digest("hex");
44
+ }
45
+
46
+ // Dynamic require for Node.js environments
47
+ if (typeof process !== "undefined" && process.versions?.node) {
48
+ // Use dynamic import trick for sync context
49
+ const crypto = require("crypto");
50
+ return crypto.createHash("sha256").update(text, "utf8").digest("hex");
51
+ }
52
+
53
+ throw new Error("SCXQ2: sync hashing requires Node.js crypto module");
54
+ }
55
+
56
+ /**
57
+ * Gets Node.js crypto module if available.
58
+ * Returns null in browser/worker environments.
59
+ *
60
+ * @returns {Object|null} Node crypto module or null
61
+ */
62
+ export function getNodeCrypto() {
63
+ if (typeof process !== "undefined" && process.versions?.node) {
64
+ try {
65
+ return require("crypto");
66
+ } catch {
67
+ return null;
68
+ }
69
+ }
70
+ return null;
71
+ }