@automate.ax/codec 0.1.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zach Sents
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # `@automate.ax/codec`
2
+
3
+ Msgpack-based encoding helpers for Automate.ax runtime data.
4
+
5
+ This package owns the shared `Encodable` value contract used by automation signals and storage boundaries. Most app authors should not need it directly.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ bun add @automate.ax/codec
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { decode, encodableSchema, encode } from "@automate.ax/codec"
17
+
18
+ const bytes = await encode({
19
+ message: "hello",
20
+ createdAt: new Date(),
21
+ })
22
+
23
+ const value = await decode(bytes)
24
+ const validated = encodableSchema.parse(value)
25
+ ```
26
+
27
+ ## API
28
+
29
+ - `encode(value)` — Checks an unknown value against the supported input surface, then serializes it.
30
+ - `decode(bytes)` — Deserializes msgpack bytes and returns `Encodable`.
31
+ - `encodableSchema` — Zod schema for validating unknown values against the supported input surface.
32
+ - `isEncodable(value)` — Runtime guard for the supported input surface.
33
+ - `Encodable` — Recursive type accepted by the encoder.
34
+
35
+ ## Supported Values
36
+
37
+ `Encodable` includes primitives, arrays, plain objects, `Map`, `Set`, `Date`, `RegExp`, typed arrays, `ArrayBuffer`, `DataView`, and web platform values such as `Request`, `Response`, `Blob`, `File`, `Headers`, `URL`, and `URLSearchParams`.
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Sync snapshots of async-bodied web types (`Request`, `Response`, `Blob`,
3
+ * `File`) after their bodies have been drained. msgpackr's extension `write`
4
+ * callback is synchronous, so anything with an async body must be pre-processed
5
+ * into one of these before packing.
6
+ */
7
+ /**
8
+ * `Uint8Array<ArrayBuffer>` — the shape `BodyInit`/`BlobPart` expect under DOM
9
+ * lib.
10
+ */
11
+ type Bytes = Uint8Array<ArrayBuffer>;
12
+ /** A serializable snapshot of a request and its buffered body. */
13
+ export declare class BufferedRequest {
14
+ readonly url: string;
15
+ readonly method: string;
16
+ readonly headers: Record<string, string>;
17
+ readonly body: Bytes | null;
18
+ /**
19
+ * Creates a buffered request snapshot.
20
+ *
21
+ * @param url - Original request URL.
22
+ * @param method - Original HTTP method.
23
+ * @param headers - Original headers as string entries.
24
+ * @param body - Buffered body, or `null` when the request has no body.
25
+ */
26
+ constructor(url: string, method: string, headers: Record<string, string>, body: Bytes | null);
27
+ /**
28
+ * Drains a request into a serializable snapshot.
29
+ *
30
+ * @param req - Request to buffer.
31
+ */
32
+ static from(req: Request): Promise<BufferedRequest>;
33
+ /** Reconstructs a request from this snapshot. */
34
+ toRequest(): Request;
35
+ }
36
+ /** A serializable snapshot of a response and its buffered body. */
37
+ export declare class BufferedResponse {
38
+ readonly status: number;
39
+ readonly statusText: string;
40
+ readonly headers: Record<string, string>;
41
+ readonly body: Bytes | null;
42
+ /**
43
+ * Creates a buffered response snapshot.
44
+ *
45
+ * @param status - Original response status code.
46
+ * @param statusText - Original response status text.
47
+ * @param headers - Original headers as string entries.
48
+ * @param body - Buffered body, or `null` when the response has no body.
49
+ */
50
+ constructor(status: number, statusText: string, headers: Record<string, string>, body: Bytes | null);
51
+ /**
52
+ * Drains a response into a serializable snapshot.
53
+ *
54
+ * @param res - Response to buffer.
55
+ */
56
+ static from(res: Response): Promise<BufferedResponse>;
57
+ /** Reconstructs a response from this snapshot. */
58
+ toResponse(): Response;
59
+ }
60
+ /** A serializable snapshot of a blob and its buffered bytes. */
61
+ export declare class BufferedBlob {
62
+ readonly type: string;
63
+ readonly bytes: Bytes;
64
+ /**
65
+ * Creates a buffered blob snapshot.
66
+ *
67
+ * @param type - Original media type.
68
+ * @param bytes - Buffered blob contents.
69
+ */
70
+ constructor(type: string, bytes: Bytes);
71
+ /**
72
+ * Drains a blob into a serializable snapshot.
73
+ *
74
+ * @param blob - Blob to buffer.
75
+ */
76
+ static from(blob: Blob): Promise<BufferedBlob>;
77
+ /** Reconstructs a blob from this snapshot. */
78
+ toBlob(): Blob;
79
+ }
80
+ /** A serializable snapshot of a file and its buffered bytes. */
81
+ export declare class BufferedFile {
82
+ readonly name: string;
83
+ readonly type: string;
84
+ readonly lastModified: number;
85
+ readonly bytes: Bytes;
86
+ /**
87
+ * Creates a buffered file snapshot.
88
+ *
89
+ * @param name - Original file name.
90
+ * @param type - Original media type.
91
+ * @param lastModified - Original modification timestamp.
92
+ * @param bytes - Buffered file contents.
93
+ */
94
+ constructor(name: string, type: string, lastModified: number, bytes: Bytes);
95
+ /**
96
+ * Drains a file into a serializable snapshot.
97
+ *
98
+ * @param file - File to buffer.
99
+ */
100
+ static from(file: File): Promise<BufferedFile>;
101
+ /** Reconstructs a file from this snapshot. */
102
+ toFile(): File;
103
+ }
104
+ export {};
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Sync snapshots of async-bodied web types (`Request`, `Response`, `Blob`,
3
+ * `File`) after their bodies have been drained. msgpackr's extension `write`
4
+ * callback is synchronous, so anything with an async body must be pre-processed
5
+ * into one of these before packing.
6
+ */
7
+ const METHODS_WITHOUT_BODY = new Set(["GET", "HEAD"]);
8
+ /**
9
+ * Wraps an `ArrayBuffer` in the byte-array shape accepted by web body APIs.
10
+ *
11
+ * @param buffer - Buffer to expose as bytes.
12
+ */
13
+ function toBytes(buffer) {
14
+ return new Uint8Array(buffer);
15
+ }
16
+ /** A serializable snapshot of a request and its buffered body. */
17
+ export class BufferedRequest {
18
+ url;
19
+ method;
20
+ headers;
21
+ body;
22
+ /**
23
+ * Creates a buffered request snapshot.
24
+ *
25
+ * @param url - Original request URL.
26
+ * @param method - Original HTTP method.
27
+ * @param headers - Original headers as string entries.
28
+ * @param body - Buffered body, or `null` when the request has no body.
29
+ */
30
+ constructor(url, method, headers, body) {
31
+ this.url = url;
32
+ this.method = method;
33
+ this.headers = headers;
34
+ this.body = body;
35
+ }
36
+ /**
37
+ * Drains a request into a serializable snapshot.
38
+ *
39
+ * @param req - Request to buffer.
40
+ */
41
+ static async from(req) {
42
+ return new BufferedRequest(req.url, req.method, Object.fromEntries(req.headers), req.body !== null && !METHODS_WITHOUT_BODY.has(req.method)
43
+ ? toBytes(await req.arrayBuffer())
44
+ : null);
45
+ }
46
+ /** Reconstructs a request from this snapshot. */
47
+ toRequest() {
48
+ return new Request(this.url, {
49
+ method: this.method,
50
+ headers: new Headers(this.headers),
51
+ body: this.body !== null && !METHODS_WITHOUT_BODY.has(this.method)
52
+ ? this.body
53
+ : undefined,
54
+ });
55
+ }
56
+ }
57
+ /** A serializable snapshot of a response and its buffered body. */
58
+ export class BufferedResponse {
59
+ status;
60
+ statusText;
61
+ headers;
62
+ body;
63
+ /**
64
+ * Creates a buffered response snapshot.
65
+ *
66
+ * @param status - Original response status code.
67
+ * @param statusText - Original response status text.
68
+ * @param headers - Original headers as string entries.
69
+ * @param body - Buffered body, or `null` when the response has no body.
70
+ */
71
+ constructor(status, statusText, headers, body) {
72
+ this.status = status;
73
+ this.statusText = statusText;
74
+ this.headers = headers;
75
+ this.body = body;
76
+ }
77
+ /**
78
+ * Drains a response into a serializable snapshot.
79
+ *
80
+ * @param res - Response to buffer.
81
+ */
82
+ static async from(res) {
83
+ return new BufferedResponse(res.status, res.statusText, Object.fromEntries(res.headers), res.body !== null ? toBytes(await res.arrayBuffer()) : null);
84
+ }
85
+ /** Reconstructs a response from this snapshot. */
86
+ toResponse() {
87
+ return new Response(this.body, {
88
+ status: this.status,
89
+ statusText: this.statusText,
90
+ headers: new Headers(this.headers),
91
+ });
92
+ }
93
+ }
94
+ /** A serializable snapshot of a blob and its buffered bytes. */
95
+ export class BufferedBlob {
96
+ type;
97
+ bytes;
98
+ /**
99
+ * Creates a buffered blob snapshot.
100
+ *
101
+ * @param type - Original media type.
102
+ * @param bytes - Buffered blob contents.
103
+ */
104
+ constructor(type, bytes) {
105
+ this.type = type;
106
+ this.bytes = bytes;
107
+ }
108
+ /**
109
+ * Drains a blob into a serializable snapshot.
110
+ *
111
+ * @param blob - Blob to buffer.
112
+ */
113
+ static async from(blob) {
114
+ return new BufferedBlob(blob.type, toBytes(await blob.arrayBuffer()));
115
+ }
116
+ /** Reconstructs a blob from this snapshot. */
117
+ toBlob() {
118
+ return new Blob([this.bytes], { type: this.type });
119
+ }
120
+ }
121
+ /** A serializable snapshot of a file and its buffered bytes. */
122
+ export class BufferedFile {
123
+ name;
124
+ type;
125
+ lastModified;
126
+ bytes;
127
+ /**
128
+ * Creates a buffered file snapshot.
129
+ *
130
+ * @param name - Original file name.
131
+ * @param type - Original media type.
132
+ * @param lastModified - Original modification timestamp.
133
+ * @param bytes - Buffered file contents.
134
+ */
135
+ constructor(name, type, lastModified, bytes) {
136
+ this.name = name;
137
+ this.type = type;
138
+ this.lastModified = lastModified;
139
+ this.bytes = bytes;
140
+ }
141
+ /**
142
+ * Drains a file into a serializable snapshot.
143
+ *
144
+ * @param file - File to buffer.
145
+ */
146
+ static async from(file) {
147
+ return new BufferedFile(file.name, file.type, file.lastModified, toBytes(await file.arrayBuffer()));
148
+ }
149
+ /** Reconstructs a file from this snapshot. */
150
+ toFile() {
151
+ return new File([this.bytes], this.name, {
152
+ type: this.type,
153
+ lastModified: this.lastModified,
154
+ });
155
+ }
156
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ import { addExtension } from "msgpackr";
2
+ import { BufferedBlob, BufferedFile, BufferedRequest, BufferedResponse, } from "./buffered.js";
3
+ import { EXT_CODES } from "./type-codes.js";
4
+ addExtension({
5
+ Class: BufferedRequest,
6
+ type: EXT_CODES.REQUEST,
7
+ write(instance) {
8
+ return [instance.url, instance.method, instance.headers, instance.body];
9
+ },
10
+ read([url, method, headers, body]) {
11
+ return new BufferedRequest(url, method, headers, body).toRequest();
12
+ },
13
+ });
14
+ addExtension({
15
+ Class: BufferedResponse,
16
+ type: EXT_CODES.RESPONSE,
17
+ write(instance) {
18
+ return [
19
+ instance.status,
20
+ instance.statusText,
21
+ instance.headers,
22
+ instance.body,
23
+ ];
24
+ },
25
+ read([status, statusText, headers, body]) {
26
+ return new BufferedResponse(status, statusText, headers, body).toResponse();
27
+ },
28
+ });
29
+ addExtension({
30
+ Class: BufferedBlob,
31
+ type: EXT_CODES.BLOB,
32
+ write(instance) {
33
+ return [instance.type, instance.bytes];
34
+ },
35
+ read([type, bytes]) {
36
+ return new BufferedBlob(type, bytes).toBlob();
37
+ },
38
+ });
39
+ addExtension({
40
+ Class: BufferedFile,
41
+ type: EXT_CODES.FILE,
42
+ write(instance) {
43
+ return [instance.name, instance.type, instance.lastModified, instance.bytes];
44
+ },
45
+ read([name, type, lastModified, bytes]) {
46
+ return new BufferedFile(name, type, lastModified, bytes).toFile();
47
+ },
48
+ });
49
+ addExtension({
50
+ Class: Headers,
51
+ type: EXT_CODES.HEADERS,
52
+ write: (h) => Object.fromEntries(h),
53
+ read: (entries) => new Headers(entries),
54
+ });
55
+ addExtension({
56
+ Class: URL,
57
+ type: EXT_CODES.URL,
58
+ write: (u) => u.href,
59
+ read: (href) => new URL(href),
60
+ });
61
+ addExtension({
62
+ Class: URLSearchParams,
63
+ type: EXT_CODES.URL_SEARCH_PARAMS,
64
+ write: (p) => [...p.entries()],
65
+ read: (entries) => new URLSearchParams(entries),
66
+ });
@@ -0,0 +1,43 @@
1
+ import z from "zod";
2
+ export type { ObjectProducingSchema, ProducingSchema } from "./schema.js";
3
+ /**
4
+ * Values accepted by the codec encoder, including recursively nested containers
5
+ * and registered web-platform extension types.
6
+ */
7
+ export type Encodable = null | undefined | void | boolean | number | bigint | string | Uint8Array | Uint8ClampedArray | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array | BigUint64Array | BigInt64Array | Encodable[] | readonly Encodable[] | {
8
+ readonly [key: string]: Encodable;
9
+ } | Map<Encodable, Encodable> | Set<Encodable> | Date | RegExp | ArrayBuffer | DataView | Request | Response | Blob | File | Headers | URL | URLSearchParams;
10
+ /**
11
+ * Checks whether an unknown value fits the codec's supported input surface.
12
+ *
13
+ * @param value - Value to inspect.
14
+ */
15
+ export declare function isEncodable(value: unknown): value is Encodable;
16
+ /** Zod schema for values accepted by the codec encoder. */
17
+ export declare const encodableSchema: z.ZodCustom<Encodable, Encodable>;
18
+ /**
19
+ * Serializes a value after checking it against the codec's supported input
20
+ * surface.
21
+ *
22
+ * Pre-walks the value to buffer any async-bodied values (`Request`, `Response`)
23
+ * before handing off to the synchronous packer.
24
+ *
25
+ * @param value - Value to validate and serialize.
26
+ * @throws {TypeError} When the value is outside the supported input surface.
27
+ */
28
+ export declare function encode(value: unknown): Promise<Uint8Array>;
29
+ /**
30
+ * Deserializes msgpack bytes.
31
+ *
32
+ * Currently synchronous under the hood, but typed as async to leave room for
33
+ * future concerns that need await (e.g. resolving blob refs from external
34
+ * storage, streaming decodes).
35
+ *
36
+ * Returns the codec's supported value surface. Callers should still validate
37
+ * the domain-specific shape where they know the expected type.
38
+ *
39
+ * @param bytes - Msgpack bytes to deserialize.
40
+ * @throws {TypeError} When the decoded payload is outside the supported
41
+ * surface.
42
+ */
43
+ export declare function decode(bytes: Uint8Array): Promise<Encodable>;
package/dist/index.js ADDED
@@ -0,0 +1,112 @@
1
+ import z from "zod";
2
+ import { isPlainObject } from "./lib/utils.js";
3
+ import { packr } from "./packr.js";
4
+ import { bufferAsyncValues } from "./walk.js";
5
+ /**
6
+ * Asserts that a value belongs to the codec's supported input surface.
7
+ *
8
+ * @param value - Value to validate.
9
+ * @throws {TypeError} When the value cannot be encoded.
10
+ */
11
+ function assertEncodable(value) {
12
+ if (!isEncodable(value)) {
13
+ throw new TypeError(`Value is not encodable: ${Object.prototype.toString.call(value)}`);
14
+ }
15
+ }
16
+ /**
17
+ * Checks whether an unknown value fits the codec's supported input surface.
18
+ *
19
+ * @param value - Value to inspect.
20
+ */
21
+ export function isEncodable(value) {
22
+ const activePath = new WeakSet();
23
+ /**
24
+ * Validates one value while tracking the active traversal path for cycles.
25
+ *
26
+ * @param value - Value at the current traversal position.
27
+ */
28
+ function visit(value) {
29
+ if (value == null)
30
+ return true;
31
+ switch (typeof value) {
32
+ case "boolean":
33
+ case "bigint":
34
+ case "number":
35
+ case "string":
36
+ return true;
37
+ case "function":
38
+ case "symbol":
39
+ return false;
40
+ case "object":
41
+ break;
42
+ default:
43
+ return false;
44
+ }
45
+ if (value instanceof Date ||
46
+ value instanceof RegExp ||
47
+ value instanceof ArrayBuffer ||
48
+ ArrayBuffer.isView(value) ||
49
+ value instanceof Request ||
50
+ value instanceof Response ||
51
+ value instanceof Blob ||
52
+ value instanceof File ||
53
+ value instanceof Headers ||
54
+ value instanceof URL ||
55
+ value instanceof URLSearchParams) {
56
+ return true;
57
+ }
58
+ if (activePath.has(value))
59
+ return false;
60
+ activePath.add(value);
61
+ try {
62
+ return Array.isArray(value)
63
+ ? value.every(visit)
64
+ : value instanceof Map
65
+ ? [...value].every(([key, item]) => visit(key) && visit(item))
66
+ : value instanceof Set
67
+ ? [...value].every(visit)
68
+ : isPlainObject(value) && Object.values(value).every(visit);
69
+ }
70
+ finally {
71
+ activePath.delete(value);
72
+ }
73
+ }
74
+ return visit(value);
75
+ }
76
+ /** Zod schema for values accepted by the codec encoder. */
77
+ export const encodableSchema = z.custom(isEncodable, {
78
+ message: "Value is not encodable",
79
+ });
80
+ /**
81
+ * Serializes a value after checking it against the codec's supported input
82
+ * surface.
83
+ *
84
+ * Pre-walks the value to buffer any async-bodied values (`Request`, `Response`)
85
+ * before handing off to the synchronous packer.
86
+ *
87
+ * @param value - Value to validate and serialize.
88
+ * @throws {TypeError} When the value is outside the supported input surface.
89
+ */
90
+ export async function encode(value) {
91
+ assertEncodable(value);
92
+ return packr.pack(await bufferAsyncValues(value));
93
+ }
94
+ /**
95
+ * Deserializes msgpack bytes.
96
+ *
97
+ * Currently synchronous under the hood, but typed as async to leave room for
98
+ * future concerns that need await (e.g. resolving blob refs from external
99
+ * storage, streaming decodes).
100
+ *
101
+ * Returns the codec's supported value surface. Callers should still validate
102
+ * the domain-specific shape where they know the expected type.
103
+ *
104
+ * @param bytes - Msgpack bytes to deserialize.
105
+ * @throws {TypeError} When the decoded payload is outside the supported
106
+ * surface.
107
+ */
108
+ export async function decode(bytes) {
109
+ const value = packr.unpack(bytes);
110
+ assertEncodable(value);
111
+ return value;
112
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Checks whether an object has the standard object prototype or no prototype.
3
+ *
4
+ * @param value - Object to inspect.
5
+ */
6
+ export declare function isPlainObject(value: object): value is Record<string, unknown>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Checks whether an object has the standard object prototype or no prototype.
3
+ *
4
+ * @param value - Object to inspect.
5
+ */
6
+ export function isPlainObject(value) {
7
+ const proto = Object.getPrototypeOf(value);
8
+ return proto === Object.prototype || proto === null;
9
+ }
@@ -0,0 +1,10 @@
1
+ import { Packr } from "msgpackr";
2
+ import "./extensions.js";
3
+ /**
4
+ * Single configured `Packr` instance used for all encode/decode in the runtime.
5
+ *
6
+ * Extensions are registered globally via `addExtension` (see `./extensions`),
7
+ * so any `Packr` instance picks them up — but using one shared instance keeps
8
+ * option configuration consistent.
9
+ */
10
+ export declare const packr: Packr;
package/dist/packr.js ADDED
@@ -0,0 +1,17 @@
1
+ import { Packr } from "msgpackr";
2
+ import "./extensions.js";
3
+ /**
4
+ * Single configured `Packr` instance used for all encode/decode in the runtime.
5
+ *
6
+ * Extensions are registered globally via `addExtension` (see `./extensions`),
7
+ * so any `Packr` instance picks them up — but using one shared instance keeps
8
+ * option configuration consistent.
9
+ */
10
+ export const packr = new Packr({
11
+ useRecords: true,
12
+ mapsAsObjects: false,
13
+ moreTypes: true,
14
+ int64AsType: "bigint",
15
+ useBigIntExtension: true,
16
+ encodeUndefinedAsNil: false,
17
+ });
@@ -0,0 +1,5 @@
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ /** Standard Schema whose validated output is assignable to the given type. */
3
+ export type ProducingSchema<TOutput> = StandardSchemaV1<any, TOutput>;
4
+ /** Standard Schema whose validated output is a string-keyed object. */
5
+ export type ObjectProducingSchema<TValue> = ProducingSchema<Record<string, TValue>>;
package/dist/schema.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Stable msgpack extension type codes for built-in runtime value types.
3
+ *
4
+ * These numbers are part of the wire format. Changing an existing code is a
5
+ * breaking change that would invalidate all previously stored outputs. Treat
6
+ * this file as append-only.
7
+ *
8
+ * Msgpackr reserves negative codes for MessagePack itself and 101-127 for its
9
+ * own use. Codes 1-100 are available to built-in application values.
10
+ */
11
+ export declare const EXT_CODES: {
12
+ readonly REQUEST: 1;
13
+ readonly RESPONSE: 2;
14
+ readonly BLOB: 3;
15
+ readonly FILE: 4;
16
+ readonly HEADERS: 5;
17
+ readonly URL: 6;
18
+ readonly URL_SEARCH_PARAMS: 7;
19
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Stable msgpack extension type codes for built-in runtime value types.
3
+ *
4
+ * These numbers are part of the wire format. Changing an existing code is a
5
+ * breaking change that would invalidate all previously stored outputs. Treat
6
+ * this file as append-only.
7
+ *
8
+ * Msgpackr reserves negative codes for MessagePack itself and 101-127 for its
9
+ * own use. Codes 1-100 are available to built-in application values.
10
+ */
11
+ export const EXT_CODES = {
12
+ REQUEST: 1,
13
+ RESPONSE: 2,
14
+ BLOB: 3,
15
+ FILE: 4,
16
+ HEADERS: 5,
17
+ URL: 6,
18
+ URL_SEARCH_PARAMS: 7,
19
+ };
package/dist/walk.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Walks a value tree and replaces anything with an async body (`Request`,
3
+ * `Response`, `Blob`, `File`) with a sync-buffered snapshot, so the result can
4
+ * be handed to a synchronous encoder.
5
+ *
6
+ * Recurses through plain objects, arrays, `Map`s, and `Set`s. Leaves
7
+ * primitives, typed arrays, and sync class instances (`Headers`, `URL`, etc.)
8
+ * alone — those either have no async surface or msgpackr handles them natively
9
+ * via registered extensions at pack time.
10
+ *
11
+ * Dedupes by reference within a single call so that a tree sharing the same
12
+ * `Request`/`Response`/`Blob`/`File` in multiple places doesn't trigger "body
13
+ * already used".
14
+ *
15
+ * Does not detect cycles. Automation outputs are expected to be tree-shaped.
16
+ *
17
+ * @param value - Value tree to prepare for synchronous encoding.
18
+ */
19
+ export declare function bufferAsyncValues(value: unknown): Promise<unknown>;