@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 +21 -0
- package/README.md +37 -0
- package/dist/buffered.d.ts +104 -0
- package/dist/buffered.js +156 -0
- package/dist/extensions.d.ts +1 -0
- package/dist/extensions.js +66 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +112 -0
- package/dist/lib/utils.d.ts +6 -0
- package/dist/lib/utils.js +9 -0
- package/dist/packr.d.ts +10 -0
- package/dist/packr.js +17 -0
- package/dist/schema.d.ts +5 -0
- package/dist/schema.js +1 -0
- package/dist/type-codes.d.ts +19 -0
- package/dist/type-codes.js +19 -0
- package/dist/walk.d.ts +19 -0
- package/dist/walk.js +69 -0
- package/package.json +70 -0
- package/src/buffered.ts +178 -0
- package/src/extensions.ts +93 -0
- package/src/index.ts +169 -0
- package/src/lib/utils.ts +9 -0
- package/src/packr.ts +18 -0
- package/src/schema.ts +13 -0
- package/src/type-codes.ts +19 -0
- package/src/walk.ts +97 -0
package/src/walk.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BufferedBlob,
|
|
3
|
+
BufferedFile,
|
|
4
|
+
BufferedRequest,
|
|
5
|
+
BufferedResponse,
|
|
6
|
+
} from "./buffered"
|
|
7
|
+
import { isPlainObject } from "./lib/utils"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Walks a value tree and replaces anything with an async body (`Request`,
|
|
11
|
+
* `Response`, `Blob`, `File`) with a sync-buffered snapshot, so the result can
|
|
12
|
+
* be handed to a synchronous encoder.
|
|
13
|
+
*
|
|
14
|
+
* Recurses through plain objects, arrays, `Map`s, and `Set`s. Leaves
|
|
15
|
+
* primitives, typed arrays, and sync class instances (`Headers`, `URL`, etc.)
|
|
16
|
+
* alone — those either have no async surface or msgpackr handles them natively
|
|
17
|
+
* via registered extensions at pack time.
|
|
18
|
+
*
|
|
19
|
+
* Dedupes by reference within a single call so that a tree sharing the same
|
|
20
|
+
* `Request`/`Response`/`Blob`/`File` in multiple places doesn't trigger "body
|
|
21
|
+
* already used".
|
|
22
|
+
*
|
|
23
|
+
* Does not detect cycles. Automation outputs are expected to be tree-shaped.
|
|
24
|
+
*
|
|
25
|
+
* @param value - Value tree to prepare for synchronous encoding.
|
|
26
|
+
*/
|
|
27
|
+
export async function bufferAsyncValues(value: unknown): Promise<unknown> {
|
|
28
|
+
return walk(value, new WeakMap())
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Walks a value while reusing in-flight work for repeated object references.
|
|
33
|
+
*
|
|
34
|
+
* @param value - Value at the current traversal position.
|
|
35
|
+
* @param cache - Buffered results keyed by source object identity.
|
|
36
|
+
*/
|
|
37
|
+
async function walk(
|
|
38
|
+
value: unknown,
|
|
39
|
+
cache: WeakMap<object, Promise<unknown>>,
|
|
40
|
+
): Promise<unknown> {
|
|
41
|
+
if (value === null || typeof value !== "object") return value
|
|
42
|
+
|
|
43
|
+
const cached = cache.get(value)
|
|
44
|
+
if (cached) return cached
|
|
45
|
+
|
|
46
|
+
const task = walkFresh(value, cache)
|
|
47
|
+
cache.set(value, task)
|
|
48
|
+
return task
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Buffers an object that does not yet have a cached traversal task.
|
|
53
|
+
*
|
|
54
|
+
* @param value - Object to inspect and buffer.
|
|
55
|
+
* @param cache - Buffered results keyed by source object identity.
|
|
56
|
+
*/
|
|
57
|
+
async function walkFresh(
|
|
58
|
+
value: object,
|
|
59
|
+
cache: WeakMap<object, Promise<unknown>>,
|
|
60
|
+
): Promise<unknown> {
|
|
61
|
+
if (value instanceof Request) return BufferedRequest.from(value)
|
|
62
|
+
if (value instanceof Response) return BufferedResponse.from(value)
|
|
63
|
+
// File extends Blob — must be checked first so we don't lose name/lastModified.
|
|
64
|
+
if (value instanceof File) return BufferedFile.from(value)
|
|
65
|
+
if (value instanceof Blob) return BufferedBlob.from(value)
|
|
66
|
+
|
|
67
|
+
if (Array.isArray(value)) {
|
|
68
|
+
return Promise.all(value.map((v) => walk(v, cache)))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (value instanceof Map) {
|
|
72
|
+
return new Map(
|
|
73
|
+
await Promise.all(
|
|
74
|
+
[...value.entries()].map(
|
|
75
|
+
async ([k, v]) =>
|
|
76
|
+
[await walk(k, cache), await walk(v, cache)] as const,
|
|
77
|
+
),
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (value instanceof Set) {
|
|
83
|
+
return new Set(await Promise.all([...value].map((v) => walk(v, cache))))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (isPlainObject(value)) {
|
|
87
|
+
return Object.fromEntries(
|
|
88
|
+
await Promise.all(
|
|
89
|
+
Object.entries(value).map(
|
|
90
|
+
async ([k, v]) => [k, await walk(v, cache)] as const,
|
|
91
|
+
),
|
|
92
|
+
),
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return value
|
|
97
|
+
}
|