Sign In

@looptail/sdk

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@looptail/sdk - npm Package Compare versions

Comparing version
0.2.0
to
0.2.1
+6
-1
dist/chain.d.ts

@@ -21,4 +21,9 @@ export declare const FORMAT_VERSION = "0.1";

export declare function b64urlDecode(text: string): Buffer;
/** Sort by Unicode code point (matches Python's sort_keys / UTF-8 byte order),
* NOT the default UTF-16-code-unit order, so canonical bytes are identical
* across the JS and Python implementations. The orders differ whenever a key
* in U+E000–U+FFFF is compared against an astral-plane key. */
export declare function compareCodePoints(a: string, b: string): number;
/** Key-sorted, whitespace-free JSON — matches Python json.dumps(sort_keys=True,
* separators=(',',':'), ensure_ascii=False) for spec-conformant values. */
* separators=(',',':'), ensure_ascii=False) byte-for-byte. */
export declare function canonical(value: unknown): string;

@@ -25,0 +30,0 @@ export declare function eventHash(event: Partial<TrailEvent>): string;

@@ -28,4 +28,22 @@ /**

}
/** Sort by Unicode code point (matches Python's sort_keys / UTF-8 byte order),
* NOT the default UTF-16-code-unit order, so canonical bytes are identical
* across the JS and Python implementations. The orders differ whenever a key
* in U+E000–U+FFFF is compared against an astral-plane key. */
export function compareCodePoints(a, b) {
const ai = a[Symbol.iterator]();
const bi = b[Symbol.iterator]();
for (;;) {
const x = ai.next();
const y = bi.next();
if (x.done || y.done)
return x.done ? (y.done ? 0 : -1) : 1;
const cx = x.value.codePointAt(0);
const cy = y.value.codePointAt(0);
if (cx !== cy)
return cx - cy;
}
}
/** Key-sorted, whitespace-free JSON — matches Python json.dumps(sort_keys=True,
* separators=(',',':'), ensure_ascii=False) for spec-conformant values. */
* separators=(',',':'), ensure_ascii=False) byte-for-byte. */
export function canonical(value) {

@@ -37,3 +55,3 @@ if (value === null || typeof value !== 'object')

const entries = Object.keys(value)
.sort()
.sort(compareCodePoints)
.map((k) => JSON.stringify(k) + ':' + canonical(value[k]));

@@ -43,3 +61,6 @@ return '{' + entries.join(',') + '}';

export function eventHash(event) {
const unsigned = {};
// null prototype: on a plain {} an assignment to "__proto__" hits the
// prototype setter instead of creating an own property, silently dropping
// the field from the hash — a JS/Python divergence and a signature bypass.
const unsigned = Object.create(null);
for (const [k, v] of Object.entries(event)) {

@@ -46,0 +67,0 @@ if (k !== 'hash' && k !== 'sig' && v !== undefined)

+1
-1
{
"name": "@looptail/sdk",
"version": "0.2.0",
"version": "0.2.1",
"description": "Record every AI decision as a signed, append-only trail. Every loop leaves a tail.",

@@ -5,0 +5,0 @@ "license": "Apache-2.0",