castrum 0.9.0 → 0.9.2
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/README.md +153 -630
- package/castrum.linux-x64-gnu.node +0 -0
- package/dist/index.d.ts +1653 -1817
- package/dist/index.js +6172 -4294
- package/docs/API.md +337 -0
- package/docs/ARCHITECTURE.md +111 -17
- package/docs/BENCHMARKS.md +117 -49
- package/docs/CASE_STUDY.md +243 -0
- package/docs/ENVIRONMENT.md +24 -7
- package/docs/FFI_BUN_GUIDE.md +335 -0
- package/docs/GETTING_STARTED.md +18 -34
- package/docs/HOW_TO_ADD_AN_OP.md +180 -0
- package/docs/INGRESS-ROUTER.md +82 -0
- package/docs/INGRESS.md +11 -7
- package/docs/NATIVE-ROUTE.md +77 -0
- package/docs/REPO_MAP.md +103 -53
- package/docs/adr/0001-two-wire-formats.md +1 -1
- package/docs/adr/0003-bun-builtins-delegation.md +6 -5
- package/docs/ai/LOCAL_DEV.md +81 -0
- package/docs/ai/TREE.md +1070 -0
- package/docs/bun-builtins-decision-matrix.md +25 -18
- package/index.ts +9 -16
- package/package.json +41 -28
- package/src/ingress/body.ts +167 -27
- package/src/ingress/decode/result-base.ts +10 -2
- package/src/ingress/handlers.ts +116 -285
- package/src/ingress/headers/security.ts +41 -0
- package/src/ingress/health.ts +1 -0
- package/src/ingress/index.ts +45 -169
- package/src/ingress/native-route.ts +182 -0
- package/src/ingress/packing/gather-raw-headers.ts +110 -22
- package/src/ingress/packing/header-packing.ts +5 -5
- package/src/ingress/packing/input-packer.ts +17 -3
- package/src/ingress/packing/route-wire.ts +197 -0
- package/src/ingress/packing/select-headers.ts +20 -7
- package/src/ingress/path-matcher.ts +115 -0
- package/src/ingress/response/baked-response.ts +302 -0
- package/src/ingress/router.ts +277 -0
- package/src/ingress/routes/common.ts +50 -1
- package/src/ingress/routes/fallback.ts +2 -2
- package/src/ingress/routes/head.ts +3 -13
- package/src/ingress/routes/index.ts +5 -4
- package/src/ingress/routes/json-write.ts +26 -47
- package/src/ingress/routes/native.ts +130 -0
- package/src/ingress/routes/options.ts +2 -12
- package/src/ingress/routes/read.ts +3 -13
- package/src/ingress/routes/responder.ts +159 -0
- package/src/ingress/server-node.ts +7 -7
- package/src/ingress/server.ts +83 -112
- package/src/ingress/sync.ts +151 -0
- package/src/ingress/types.ts +44 -1
- package/src/integration/pipeline.ts +3 -0
- package/src/integration/streaming.ts +2 -3
- package/src/integration/websocket.ts +4 -3
- package/src/loader/batch.ts +4 -0
- package/src/loader/cost.ts +1 -0
- package/src/loader/index.ts +43 -228
- package/src/loader/state.ts +84 -0
- package/src/loader/types.ts +145 -0
- package/src/native/ffi/build/codecs.ts +736 -0
- package/src/native/ffi/build/compress.ts +248 -0
- package/src/native/ffi/build/instances.ts +598 -0
- package/src/native/ffi/build/parse.ts +539 -0
- package/src/native/ffi/build/util.ts +140 -0
- package/src/native/ffi/build.ts +94 -0
- package/src/native/ffi/constants.ts +58 -0
- package/src/native/ffi/selftest.ts +22 -0
- package/src/native/ffi/types.ts +499 -0
- package/src/native/ffi.ts +307 -1357
- package/src/native/loader.ts +52 -6
- package/src/native/types/instances.ts +279 -0
- package/src/native/types.ts +41 -238
- package/src/runtime/builtins.ts +131 -0
- package/src/runtime/codec.ts +147 -0
- package/src/runtime/detect.ts +36 -0
- package/src/runtime/index.ts +28 -0
- package/src/runtime/native.ts +35 -0
- package/src/runtime/server.ts +31 -0
- package/src/runtime/transport.ts +64 -0
- package/src/runtime/types.ts +173 -0
- package/src/runtime/uuid.ts +45 -0
- package/src/runtime/websocket.ts +30 -0
- package/src/rust-ffi/addon.ts +1 -1
- package/src/rust-ffi/batch/build.ts +155 -0
- package/src/rust-ffi/batch/index.ts +8 -0
- package/src/rust-ffi/batch/types.ts +92 -0
- package/src/rust-ffi/client.ts +5 -6
- package/src/rust-ffi/context.ts +39 -10
- package/src/rust-ffi/index.ts +28 -17
- package/src/rust-ffi/into.ts +21 -0
- package/src/rust-ffi/options.ts +1 -1
- package/src/rust-ffi/packed.ts +40 -2
- package/src/rust-ffi/proven.ts +16 -30
- package/src/rust-ffi/scalar/crypto.ts +188 -107
- package/src/rust-ffi/scalar/factories.ts +257 -27
- package/src/rust-ffi/scalar/hashing.ts +43 -41
- package/src/rust-ffi/scalar/http.ts +208 -77
- package/src/rust-ffi/scalar/index.ts +3 -3
- package/src/rust-ffi/scalar/interface.ts +88 -213
- package/src/rust-ffi/scalar/json-packed.ts +175 -0
- package/src/rust-ffi/scalar/json.ts +28 -12
- package/src/rust-ffi/scalar/payload.ts +159 -42
- package/src/rust-ffi/text.ts +31 -5
- package/src/selection.ts +27 -31
- package/src/shared/adaptive.ts +1 -2
- package/src/shared/buffer-pool.ts +72 -17
- package/src/shared/bytes.ts +75 -6
- package/src/shared/codec.ts +78 -0
- package/src/shared/env.ts +4 -4
- package/src/shared/log.ts +1 -0
- package/src/shared/packed/index.ts +10 -0
- package/src/shared/packed/parsers.ts +31 -0
- package/src/shared/packed/schema.ts +23 -0
- package/src/shared/{packed.ts → packed/wire.ts} +31 -39
- package/src/shared/proven.ts +189 -496
- package/src/shared/runtime.ts +20 -25
- package/src/shared/uuid.ts +12 -28
- package/src/data/json-rows.ts +0 -33
- package/src/rust-ffi/batch.ts +0 -431
- package/src/shared/bench-classify.ts +0 -209
package/src/shared/runtime.ts
CHANGED
|
@@ -1,34 +1,29 @@
|
|
|
1
|
-
// src/shared/runtime.ts — runtime detection helpers.
|
|
1
|
+
// src/shared/runtime.ts — runtime detection helpers (facade).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// Facade over the cached detection in `src/runtime/detect.ts` (the ONLY place
|
|
4
|
+
// `typeof Bun` is checked — resolved ONCE at module load by the runtime
|
|
5
|
+
// adapter). Kept so existing `isBun()` / `isNode()` / `runtimeName()` /
|
|
6
|
+
// `nodeMajorVersion()` call sites work unchanged.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
import {
|
|
9
|
+
detectedRuntime,
|
|
10
|
+
isBunRuntime,
|
|
11
|
+
isNodeRuntime,
|
|
12
|
+
nodeMajorVersion as nodeMajorVersionDetected,
|
|
13
|
+
} from '../runtime/detect'
|
|
14
|
+
import type { RuntimeName as RuntimeNameType } from '../runtime/types'
|
|
9
15
|
|
|
10
|
-
/**
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
/** Host runtime identifier. */
|
|
17
|
+
export type RuntimeName = RuntimeNameType
|
|
18
|
+
|
|
19
|
+
/** Whether the current runtime is Bun (the primary target). Cached once at load. */
|
|
20
|
+
export const isBun: () => boolean = isBunRuntime
|
|
15
21
|
|
|
16
22
|
/** Whether the current runtime is Node.js. */
|
|
17
|
-
export
|
|
18
|
-
return !isBun() && typeof process !== 'undefined' && process.versions?.node != null
|
|
19
|
-
}
|
|
23
|
+
export const isNode: () => boolean = isNodeRuntime
|
|
20
24
|
|
|
21
25
|
/** Best-effort name of the current runtime. */
|
|
22
|
-
export
|
|
23
|
-
if (isBun()) return 'bun'
|
|
24
|
-
if (isNode()) return 'node'
|
|
25
|
-
return 'unknown'
|
|
26
|
-
}
|
|
26
|
+
export const runtimeName: () => RuntimeName = () => detectedRuntime
|
|
27
27
|
|
|
28
28
|
/** The Node.js major version when running under Node, otherwise `null`. */
|
|
29
|
-
export
|
|
30
|
-
if (!isNode()) return null
|
|
31
|
-
const v = process.versions.node
|
|
32
|
-
const major = Number(v?.split('.')[0])
|
|
33
|
-
return Number.isFinite(major) ? major : null
|
|
34
|
-
}
|
|
29
|
+
export const nodeMajorVersion: () => number | null = nodeMajorVersionDetected
|
package/src/shared/uuid.ts
CHANGED
|
@@ -1,31 +1,15 @@
|
|
|
1
|
-
// src/shared/uuid.ts — UUIDv7 generation.
|
|
1
|
+
// src/shared/uuid.ts — UUIDv7 generation (facade).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// built-in and falls back to crypto.randomUUID (RFC 4122 v4) under Node.
|
|
3
|
+
// UUIDv7 delegates to the runtime adapter's uuid (`src/runtime/uuid.ts`):
|
|
4
|
+
// `Bun.randomUUIDv7` on Bun (measured ~2x faster than the FFI-crossing rust
|
|
5
|
+
// path) and `crypto.randomUUID` (RFC 4122 v4) under Node.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
export function uuidv7(): string {
|
|
10
|
-
const bun = (globalThis as { Bun?: { randomUUIDv7?: () => string } }).Bun
|
|
11
|
-
if (typeof bun?.randomUUIDv7 === 'function') {
|
|
12
|
-
return bun.randomUUIDv7()
|
|
13
|
-
}
|
|
14
|
-
// Node / non-Bun fallback: crypto.randomUUID (v4 — order not guaranteed).
|
|
15
|
-
return globalThis.crypto?.randomUUID?.() ?? fallbackRandomUuid()
|
|
16
|
-
}
|
|
7
|
+
import { runtimeUuid } from '../runtime/uuid'
|
|
17
8
|
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256)
|
|
26
|
-
}
|
|
27
|
-
bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40 // version 4
|
|
28
|
-
bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80 // variant 10xx
|
|
29
|
-
const hex = [...bytes].map((b) => b.toString(16).padStart(2, '0')).join('')
|
|
30
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`
|
|
31
|
-
}
|
|
9
|
+
/**
|
|
10
|
+
* Generate a UUIDv7 (time-ordered) string, preferring Bun's native built-in.
|
|
11
|
+
* Under Node this falls back to `crypto.randomUUID` (v4).
|
|
12
|
+
*
|
|
13
|
+
* @returns A UUID string.
|
|
14
|
+
*/
|
|
15
|
+
export const uuidv7: () => string = runtimeUuid.uuidv7
|
package/src/data/json-rows.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { encoder } from '../shared/bytes'
|
|
2
|
-
|
|
3
|
-
export interface JsonRowNested {
|
|
4
|
-
version: number
|
|
5
|
-
createdAt: string
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface JsonRow {
|
|
9
|
-
id: number
|
|
10
|
-
name: string
|
|
11
|
-
active: boolean
|
|
12
|
-
score: number
|
|
13
|
-
tags: string[]
|
|
14
|
-
nested: JsonRowNested
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function createJsonRows(rows: number): JsonRow[] {
|
|
18
|
-
return Array.from({ length: rows }, (_, i) => ({
|
|
19
|
-
id: i,
|
|
20
|
-
name: `user_${i}`,
|
|
21
|
-
active: i % 2 === 0,
|
|
22
|
-
score: i * 1.25,
|
|
23
|
-
tags: ['alpha', 'beta', 'gamma'],
|
|
24
|
-
nested: {
|
|
25
|
-
version: i % 10,
|
|
26
|
-
createdAt: '2026-01-01T00:00:00Z',
|
|
27
|
-
},
|
|
28
|
-
}))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function jsonRowsBytes(rows: number): Uint8Array {
|
|
32
|
-
return encoder.encode(JSON.stringify(createJsonRows(rows)))
|
|
33
|
-
}
|
package/src/rust-ffi/batch.ts
DELETED
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
// src/rust-ffi/batch.ts — Array-of-bytes FFI namespace.
|
|
2
|
-
//
|
|
3
|
-
// `rust.batch.*` packs an array of byte slices into the packed wire format,
|
|
4
|
-
// calls the native batch function, and unpacks the result into the friendly
|
|
5
|
-
// JS shape (bitsets, u32 arrays, i64 arrays, byte results).
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
schemaValidateBatch,
|
|
9
|
-
schemaValidateBatchCount,
|
|
10
|
-
unpackBitset,
|
|
11
|
-
unpackByteResults,
|
|
12
|
-
unpackI64ArrayAsBigInt,
|
|
13
|
-
unpackMultipartParts,
|
|
14
|
-
unpackU32Array,
|
|
15
|
-
unpackU64ArrayAsBigInt,
|
|
16
|
-
withPackScratch,
|
|
17
|
-
withPackScratch2,
|
|
18
|
-
type SchemaValidator,
|
|
19
|
-
} from '../shared/packed'
|
|
20
|
-
import { resolvePoolNative, type RustClientContext } from './context'
|
|
21
|
-
import type { MultipartPart, PasswordHashOptions } from '../native'
|
|
22
|
-
|
|
23
|
-
/** Array-of-bytes FFI namespace. */
|
|
24
|
-
export interface RustBatch {
|
|
25
|
-
jsonValid(items: Uint8Array[]): Uint8Array
|
|
26
|
-
crc32(items: Uint8Array[]): Uint32Array
|
|
27
|
-
validateEmail(items: Uint8Array[]): Uint8Array
|
|
28
|
-
validateUuid(items: Uint8Array[]): Uint8Array
|
|
29
|
-
validateIpv4(items: Uint8Array[]): Uint8Array
|
|
30
|
-
validateIpv6(items: Uint8Array[]): Uint8Array
|
|
31
|
-
jsonSumIds(items: Uint8Array[]): BigInt64Array
|
|
32
|
-
queryParse(items: Uint8Array[]): Uint8Array[]
|
|
33
|
-
cookieParse(items: Uint8Array[]): Uint8Array[]
|
|
34
|
-
httpParseRequest(items: Uint8Array[]): Uint8Array[]
|
|
35
|
-
/** Apply N RFC 6902 patches (docs and patches zipped). Fail-fast on error. */
|
|
36
|
-
jsonPatch(docs: Uint8Array[], patches: Uint8Array[]): Uint8Array[]
|
|
37
|
-
/** Encode N items to lowercase hex (packed in → byte results). */
|
|
38
|
-
hexEncode(items: Uint8Array[]): Uint8Array[]
|
|
39
|
-
/** Decode N lowercase/uppercase hex strings to bytes. */
|
|
40
|
-
hexDecode(items: Uint8Array[]): Uint8Array[]
|
|
41
|
-
/** Base64-encode N items (standard by default; url-safe/padding configurable). */
|
|
42
|
-
base64Encode(items: Uint8Array[], urlSafe?: boolean, padding?: boolean): Uint8Array[]
|
|
43
|
-
/** Base64-decode N items (standard by default; url-safe/padding configurable). */
|
|
44
|
-
base64Decode(items: Uint8Array[], urlSafe?: boolean, padding?: boolean): Uint8Array[]
|
|
45
|
-
formParse(items: Uint8Array[]): Uint8Array[]
|
|
46
|
-
/** Sign N cookie values (packed → byte results). */
|
|
47
|
-
signCookie(items: Uint8Array[], secret: Uint8Array): Uint8Array[]
|
|
48
|
-
/** Verify N signed cookies (bitset of valid). */
|
|
49
|
-
verifyCookie(items: Uint8Array[], secret: Uint8Array): Uint8Array
|
|
50
|
-
/** Verify N CSRF tokens (bitset of valid). */
|
|
51
|
-
csrfVerify(items: Uint8Array[], secret: Uint8Array): Uint8Array
|
|
52
|
-
schemaValidate(validator: SchemaValidator, items: Uint8Array[]): Uint8Array
|
|
53
|
-
schemaValidateCount(validator: SchemaValidator, items: Uint8Array[]): number
|
|
54
|
-
/** Hash N items with FNV-1a 64 (packed → unsigned u64 array). */
|
|
55
|
-
fnv1a64(items: Uint8Array[]): BigUint64Array
|
|
56
|
-
/** Generate N ETags (strong by default; weak flag applies to all items). */
|
|
57
|
-
etag(items: Uint8Array[], weak?: boolean | null): Uint8Array[]
|
|
58
|
-
urlEncode(items: Uint8Array[]): Uint8Array[]
|
|
59
|
-
/** Percent-decode N strings (UTF-8 validated; malformed items → empty). */
|
|
60
|
-
urlDecode(items: Uint8Array[]): Uint8Array[]
|
|
61
|
-
/** Strict percent-decode N strings (no UTF-8 validation). */
|
|
62
|
-
urlDecodeBytes(items: Uint8Array[]): Uint8Array[]
|
|
63
|
-
mimeFromExtension(items: Uint8Array[]): Uint8Array[]
|
|
64
|
-
wsAcceptKey(items: Uint8Array[]): Uint8Array[]
|
|
65
|
-
/** Base64url-encode N items (URL-safe, no padding). */
|
|
66
|
-
base64UrlEncode(items: Uint8Array[]): Uint8Array[]
|
|
67
|
-
/** Base64url-decode N items (URL-safe, no padding). */
|
|
68
|
-
base64UrlDecode(items: Uint8Array[]): Uint8Array[]
|
|
69
|
-
|
|
70
|
-
// ── Backend-framework features ──
|
|
71
|
-
passwordHash(
|
|
72
|
-
passwords: Uint8Array[],
|
|
73
|
-
salt: Uint8Array,
|
|
74
|
-
options?: PasswordHashOptions | null,
|
|
75
|
-
): Uint8Array[]
|
|
76
|
-
aeadEncrypt(
|
|
77
|
-
key: Uint8Array,
|
|
78
|
-
nonce: Uint8Array,
|
|
79
|
-
items: Uint8Array[],
|
|
80
|
-
algorithm?: string | null,
|
|
81
|
-
): Uint8Array[]
|
|
82
|
-
aeadDecrypt(
|
|
83
|
-
key: Uint8Array,
|
|
84
|
-
nonce: Uint8Array,
|
|
85
|
-
items: Uint8Array[],
|
|
86
|
-
algorithm?: string | null,
|
|
87
|
-
): Uint8Array[]
|
|
88
|
-
gzipCompress(items: Uint8Array[], level?: number | null): Uint8Array[]
|
|
89
|
-
gzipDecompress(items: Uint8Array[], maxDecompressed?: number | null): Uint8Array[]
|
|
90
|
-
brotliCompress(items: Uint8Array[], quality?: number | null): Uint8Array[]
|
|
91
|
-
brotliDecompress(items: Uint8Array[], maxDecompressed?: number | null): Uint8Array[]
|
|
92
|
-
jwtVerify(tokens: Uint8Array[], secret: Uint8Array, nowSeconds: number): Uint8Array
|
|
93
|
-
/** Sign N messages to lowercase-hex HMAC-SHA256 signatures (packed → byte results). */
|
|
94
|
-
hmacSha256(items: Uint8Array[], key: Uint8Array): Uint8Array[]
|
|
95
|
-
/** Verify N message + hex-signature pairs (two packed lists, zipped) → bitset of valid. */
|
|
96
|
-
hmacSha256Verify(items: Uint8Array[], sigs: Uint8Array[], key: Uint8Array): Uint8Array
|
|
97
|
-
/** Verify N password+PHC pairs (two packed lists, zipped) → bitset of valid. */
|
|
98
|
-
passwordVerify(items: Uint8Array[], phcs: Uint8Array[]): Uint8Array
|
|
99
|
-
/** Resolve N references against N bases (two packed lists, zipped). */
|
|
100
|
-
urlResolve(bases: Uint8Array[], references: Uint8Array[]): Uint8Array[]
|
|
101
|
-
/** Sign N JSON claim documents (packed → signed tokens). */
|
|
102
|
-
jwtSign(
|
|
103
|
-
items: Uint8Array[],
|
|
104
|
-
secret: Uint8Array,
|
|
105
|
-
ttlSeconds?: number | null,
|
|
106
|
-
nowSeconds?: number,
|
|
107
|
-
): Uint8Array[]
|
|
108
|
-
/** Encode N SSE events with shared event/id/retry. */
|
|
109
|
-
sseEncode(
|
|
110
|
-
items: Uint8Array[],
|
|
111
|
-
event?: string | null,
|
|
112
|
-
id?: string | null,
|
|
113
|
-
retry?: number | null,
|
|
114
|
-
): Uint8Array[]
|
|
115
|
-
/** Encode N frames (same opcode/mask/fin) from payloads. */
|
|
116
|
-
wsFrameEncode(items: Uint8Array[], opcode: number, mask: boolean, fin: boolean): Uint8Array[]
|
|
117
|
-
/** Decode N frames → payloads (opcodes/flags dropped; failed items → empty). */
|
|
118
|
-
wsFrameDecode(items: Uint8Array[]): Uint8Array[]
|
|
119
|
-
/** Parse N multipart bodies → array of parts per item (same boundary). */
|
|
120
|
-
multipartParse(items: Uint8Array[], boundary: Uint8Array): MultipartPart[][]
|
|
121
|
-
/**
|
|
122
|
-
* @performance Template render: ~1.7x slower than the JS baseline (1/3 tasks failed) [check:annotate]
|
|
123
|
-
* @deprecated Slower than the native JS baseline (~1.7x) — prefer the JS/Bun baseline. [check:annotate]
|
|
124
|
-
* @remarks Promotion candidate: 2/3 benchmarks won in the latest run (static: not-competitive). [check:annotate]
|
|
125
|
-
* @remarks The allocating render marshals the context via napi DOM (~1.5x loss). Use TemplateRenderer.renderBytes (JSON-bytes context) which avoids it and wins ~1.37x. [check:annotate]
|
|
126
|
-
*/
|
|
127
|
-
templateRender(source: string, contexts: Uint8Array[]): Uint8Array[]
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Native batch fns are process-wide singletons (one lazy addon). `resolvePoolNative`
|
|
131
|
-
// resolves each once (triggering pool init + addon load on first use) and caches
|
|
132
|
-
// it, so the hot path skips the lazy-addon Proxy get on every call — the same
|
|
133
|
-
// cache `resolveNative`/packed use (context.ts), with pool init for the
|
|
134
|
-
// rayon-backed batch surface.
|
|
135
|
-
function nativeFn(ctx: RustClientContext, name: string): (...args: unknown[]) => unknown {
|
|
136
|
-
return resolvePoolNative(ctx, name)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/** Build the `batch` namespace for a client context. */
|
|
140
|
-
export function buildBatch(ctx: RustClientContext): RustBatch {
|
|
141
|
-
return {
|
|
142
|
-
jsonValid(items) {
|
|
143
|
-
return withPackScratch(items, (packed) =>
|
|
144
|
-
unpackBitset(nativeFn(ctx, 'jsonValidBatchPacked')(packed) as Buffer),
|
|
145
|
-
)
|
|
146
|
-
},
|
|
147
|
-
crc32(items) {
|
|
148
|
-
return withPackScratch(items, (packed) =>
|
|
149
|
-
unpackU32Array(nativeFn(ctx, 'crc32BatchPacked')(packed) as Buffer),
|
|
150
|
-
)
|
|
151
|
-
},
|
|
152
|
-
validateEmail(items) {
|
|
153
|
-
return withPackScratch(items, (packed) =>
|
|
154
|
-
unpackBitset(nativeFn(ctx, 'validateEmailBatchPacked')(packed) as Buffer),
|
|
155
|
-
)
|
|
156
|
-
},
|
|
157
|
-
validateUuid(items) {
|
|
158
|
-
return withPackScratch(items, (packed) =>
|
|
159
|
-
unpackBitset(nativeFn(ctx, 'validateUuidBatchPacked')(packed) as Buffer),
|
|
160
|
-
)
|
|
161
|
-
},
|
|
162
|
-
validateIpv4(items) {
|
|
163
|
-
return withPackScratch(items, (packed) =>
|
|
164
|
-
unpackBitset(nativeFn(ctx, 'validateIpv4BatchPacked')(packed) as Buffer),
|
|
165
|
-
)
|
|
166
|
-
},
|
|
167
|
-
validateIpv6(items) {
|
|
168
|
-
return withPackScratch(items, (packed) =>
|
|
169
|
-
unpackBitset(nativeFn(ctx, 'validateIpv6BatchPacked')(packed) as Buffer),
|
|
170
|
-
)
|
|
171
|
-
},
|
|
172
|
-
jsonSumIds(items) {
|
|
173
|
-
return withPackScratch(items, (packed) =>
|
|
174
|
-
unpackI64ArrayAsBigInt(nativeFn(ctx, 'jsonSumBatchPacked')(packed) as Buffer),
|
|
175
|
-
)
|
|
176
|
-
},
|
|
177
|
-
queryParse(items) {
|
|
178
|
-
return withPackScratch(items, (packed) =>
|
|
179
|
-
unpackByteResults(nativeFn(ctx, 'queryParseBatchPacked')(packed) as Buffer),
|
|
180
|
-
)
|
|
181
|
-
},
|
|
182
|
-
cookieParse(items) {
|
|
183
|
-
return withPackScratch(items, (packed) =>
|
|
184
|
-
unpackByteResults(nativeFn(ctx, 'cookieParseBatchPacked')(packed) as Buffer),
|
|
185
|
-
)
|
|
186
|
-
},
|
|
187
|
-
formParse(items) {
|
|
188
|
-
return withPackScratch(items, (packed) =>
|
|
189
|
-
unpackByteResults(nativeFn(ctx, 'formParseBatchPacked')(packed) as Buffer),
|
|
190
|
-
)
|
|
191
|
-
},
|
|
192
|
-
signCookie(items, secret) {
|
|
193
|
-
return withPackScratch(items, (packed) =>
|
|
194
|
-
unpackByteResults(nativeFn(ctx, 'signCookieBatchPacked')(packed, secret) as Buffer),
|
|
195
|
-
)
|
|
196
|
-
},
|
|
197
|
-
verifyCookie(items, secret) {
|
|
198
|
-
return withPackScratch(items, (packed) =>
|
|
199
|
-
unpackBitset(nativeFn(ctx, 'verifyCookieBatchPacked')(packed, secret) as Buffer),
|
|
200
|
-
)
|
|
201
|
-
},
|
|
202
|
-
csrfVerify(items, secret) {
|
|
203
|
-
return withPackScratch(items, (packed) =>
|
|
204
|
-
unpackBitset(nativeFn(ctx, 'csrfVerifyBatchPacked')(packed, secret) as Buffer),
|
|
205
|
-
)
|
|
206
|
-
},
|
|
207
|
-
httpParseRequest(items) {
|
|
208
|
-
return withPackScratch(items, (packed) =>
|
|
209
|
-
unpackByteResults(nativeFn(ctx, 'httpParseRequestBatchPacked')(packed) as Buffer),
|
|
210
|
-
)
|
|
211
|
-
},
|
|
212
|
-
fnv1a64(items) {
|
|
213
|
-
return withPackScratch(items, (packed) =>
|
|
214
|
-
unpackU64ArrayAsBigInt(nativeFn(ctx, 'fnv1A64BatchPacked')(packed) as Buffer),
|
|
215
|
-
)
|
|
216
|
-
},
|
|
217
|
-
etag(items, weak) {
|
|
218
|
-
return withPackScratch(items, (packed) =>
|
|
219
|
-
unpackByteResults(nativeFn(ctx, 'etagBatchPacked')(packed, weak ?? null) as Buffer),
|
|
220
|
-
)
|
|
221
|
-
},
|
|
222
|
-
urlEncode(items) {
|
|
223
|
-
return withPackScratch(items, (packed) =>
|
|
224
|
-
unpackByteResults(nativeFn(ctx, 'urlEncodeBatchPacked')(packed) as Buffer),
|
|
225
|
-
)
|
|
226
|
-
},
|
|
227
|
-
urlDecode(items) {
|
|
228
|
-
return withPackScratch(items, (packed) =>
|
|
229
|
-
unpackByteResults(nativeFn(ctx, 'urlDecodeBatchPacked')(packed) as Buffer),
|
|
230
|
-
)
|
|
231
|
-
},
|
|
232
|
-
urlDecodeBytes(items) {
|
|
233
|
-
return withPackScratch(items, (packed) =>
|
|
234
|
-
unpackByteResults(nativeFn(ctx, 'urlDecodeBytesBatchPacked')(packed) as Buffer),
|
|
235
|
-
)
|
|
236
|
-
},
|
|
237
|
-
mimeFromExtension(items) {
|
|
238
|
-
return withPackScratch(items, (packed) =>
|
|
239
|
-
unpackByteResults(nativeFn(ctx, 'mimeFromExtensionBatchPacked')(packed) as Buffer),
|
|
240
|
-
)
|
|
241
|
-
},
|
|
242
|
-
wsAcceptKey(items) {
|
|
243
|
-
return withPackScratch(items, (packed) =>
|
|
244
|
-
unpackByteResults(nativeFn(ctx, 'wsAcceptKeyBatchPacked')(packed) as Buffer),
|
|
245
|
-
)
|
|
246
|
-
},
|
|
247
|
-
base64UrlEncode(items) {
|
|
248
|
-
return withPackScratch(items, (packed) =>
|
|
249
|
-
unpackByteResults(nativeFn(ctx, 'base64EncodeBatchPacked')(packed, true, false) as Buffer),
|
|
250
|
-
)
|
|
251
|
-
},
|
|
252
|
-
base64UrlDecode(items) {
|
|
253
|
-
return withPackScratch(items, (packed) =>
|
|
254
|
-
unpackByteResults(nativeFn(ctx, 'base64DecodeBatchPacked')(packed, true, false) as Buffer),
|
|
255
|
-
)
|
|
256
|
-
},
|
|
257
|
-
jsonPatch(docs, patches) {
|
|
258
|
-
return withPackScratch2(docs, patches, (packedDocs, packedPatches) =>
|
|
259
|
-
unpackByteResults(
|
|
260
|
-
nativeFn(ctx, 'jsonPatchBatchPacked')(packedDocs, packedPatches) as Buffer,
|
|
261
|
-
),
|
|
262
|
-
)
|
|
263
|
-
},
|
|
264
|
-
hexEncode(items) {
|
|
265
|
-
return withPackScratch(items, (packed) =>
|
|
266
|
-
unpackByteResults(nativeFn(ctx, 'hexEncodeBatchPacked')(packed) as Buffer),
|
|
267
|
-
)
|
|
268
|
-
},
|
|
269
|
-
hexDecode(items) {
|
|
270
|
-
return withPackScratch(items, (packed) =>
|
|
271
|
-
unpackByteResults(nativeFn(ctx, 'hexDecodeBatchPacked')(packed) as Buffer),
|
|
272
|
-
)
|
|
273
|
-
},
|
|
274
|
-
base64Encode(items, urlSafe, padding) {
|
|
275
|
-
return withPackScratch(items, (packed) =>
|
|
276
|
-
unpackByteResults(
|
|
277
|
-
nativeFn(ctx, 'base64EncodeBatchPacked')(
|
|
278
|
-
packed,
|
|
279
|
-
urlSafe ?? null,
|
|
280
|
-
padding ?? null,
|
|
281
|
-
) as Buffer,
|
|
282
|
-
),
|
|
283
|
-
)
|
|
284
|
-
},
|
|
285
|
-
base64Decode(items, urlSafe, padding) {
|
|
286
|
-
return withPackScratch(items, (packed) =>
|
|
287
|
-
unpackByteResults(
|
|
288
|
-
nativeFn(ctx, 'base64DecodeBatchPacked')(
|
|
289
|
-
packed,
|
|
290
|
-
urlSafe ?? null,
|
|
291
|
-
padding ?? null,
|
|
292
|
-
) as Buffer,
|
|
293
|
-
),
|
|
294
|
-
)
|
|
295
|
-
},
|
|
296
|
-
schemaValidate(validator, items) {
|
|
297
|
-
return schemaValidateBatch(validator, items)
|
|
298
|
-
},
|
|
299
|
-
schemaValidateCount(validator, items) {
|
|
300
|
-
return schemaValidateBatchCount(validator, items)
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
// ── Backend-framework features ──
|
|
304
|
-
passwordHash(password, salt, options) {
|
|
305
|
-
return withPackScratch(password, (packed) =>
|
|
306
|
-
unpackByteResults(
|
|
307
|
-
nativeFn(ctx, 'passwordHashBatchPacked')(packed, salt, options ?? null) as Buffer,
|
|
308
|
-
),
|
|
309
|
-
)
|
|
310
|
-
},
|
|
311
|
-
aeadEncrypt(key, nonce, items, algorithm) {
|
|
312
|
-
return withPackScratch(items, (packed) =>
|
|
313
|
-
unpackByteResults(
|
|
314
|
-
nativeFn(ctx, 'aeadEncryptBatchPacked')(packed, key, nonce, algorithm ?? null) as Buffer,
|
|
315
|
-
),
|
|
316
|
-
)
|
|
317
|
-
},
|
|
318
|
-
aeadDecrypt(key, nonce, items, algorithm) {
|
|
319
|
-
return withPackScratch(items, (packed) =>
|
|
320
|
-
unpackByteResults(
|
|
321
|
-
nativeFn(ctx, 'aeadDecryptBatchPacked')(packed, key, nonce, algorithm ?? null) as Buffer,
|
|
322
|
-
),
|
|
323
|
-
)
|
|
324
|
-
},
|
|
325
|
-
gzipCompress(items, level) {
|
|
326
|
-
return withPackScratch(items, (packed) =>
|
|
327
|
-
unpackByteResults(
|
|
328
|
-
nativeFn(ctx, 'gzipCompressBatchPacked')(packed, level ?? null) as Buffer,
|
|
329
|
-
),
|
|
330
|
-
)
|
|
331
|
-
},
|
|
332
|
-
gzipDecompress(items, maxDecompressed) {
|
|
333
|
-
return withPackScratch(items, (packed) =>
|
|
334
|
-
unpackByteResults(
|
|
335
|
-
nativeFn(ctx, 'gzipDecompressBatchPacked')(packed, maxDecompressed ?? null) as Buffer,
|
|
336
|
-
),
|
|
337
|
-
)
|
|
338
|
-
},
|
|
339
|
-
brotliCompress(items, quality) {
|
|
340
|
-
return withPackScratch(items, (packed) =>
|
|
341
|
-
unpackByteResults(
|
|
342
|
-
nativeFn(ctx, 'brotliCompressBatchPacked')(packed, quality ?? null) as Buffer,
|
|
343
|
-
),
|
|
344
|
-
)
|
|
345
|
-
},
|
|
346
|
-
brotliDecompress(items, maxDecompressed) {
|
|
347
|
-
return withPackScratch(items, (packed) =>
|
|
348
|
-
unpackByteResults(
|
|
349
|
-
nativeFn(ctx, 'brotliDecompressBatchPacked')(packed, maxDecompressed ?? null) as Buffer,
|
|
350
|
-
),
|
|
351
|
-
)
|
|
352
|
-
},
|
|
353
|
-
jwtVerify(tokens, secret, nowSeconds) {
|
|
354
|
-
return withPackScratch(tokens, (packed) =>
|
|
355
|
-
unpackBitset(nativeFn(ctx, 'jwtVerifyBatchPacked')(packed, secret, nowSeconds) as Buffer),
|
|
356
|
-
)
|
|
357
|
-
},
|
|
358
|
-
hmacSha256(items, key) {
|
|
359
|
-
return withPackScratch(items, (packed) =>
|
|
360
|
-
unpackByteResults(nativeFn(ctx, 'hmacSha256BatchPacked')(packed, key) as Buffer),
|
|
361
|
-
)
|
|
362
|
-
},
|
|
363
|
-
hmacSha256Verify(items, sigs, key) {
|
|
364
|
-
return withPackScratch2(items, sigs, (packedItems, packedSigs) =>
|
|
365
|
-
unpackBitset(
|
|
366
|
-
nativeFn(ctx, 'hmacSha256VerifyBatchPacked')(packedItems, packedSigs, key) as Buffer,
|
|
367
|
-
),
|
|
368
|
-
)
|
|
369
|
-
},
|
|
370
|
-
templateRender(source, contexts) {
|
|
371
|
-
return withPackScratch(contexts, (packed) =>
|
|
372
|
-
unpackByteResults(nativeFn(ctx, 'templateRenderBatchPacked')(packed, source) as Buffer),
|
|
373
|
-
)
|
|
374
|
-
},
|
|
375
|
-
passwordVerify(items, phcs) {
|
|
376
|
-
return withPackScratch2(items, phcs, (packedItems, packedPhcs) =>
|
|
377
|
-
unpackBitset(nativeFn(ctx, 'passwordVerifyBatchPacked')(packedItems, packedPhcs) as Buffer),
|
|
378
|
-
)
|
|
379
|
-
},
|
|
380
|
-
urlResolve(bases, references) {
|
|
381
|
-
return withPackScratch2(bases, references, (packedBases, packedRefs) =>
|
|
382
|
-
unpackByteResults(
|
|
383
|
-
nativeFn(ctx, 'urlResolveBatchPacked')(packedBases, packedRefs) as Buffer,
|
|
384
|
-
),
|
|
385
|
-
)
|
|
386
|
-
},
|
|
387
|
-
jwtSign(items, secret, ttlSeconds, nowSeconds) {
|
|
388
|
-
return withPackScratch(items, (packed) =>
|
|
389
|
-
unpackByteResults(
|
|
390
|
-
nativeFn(ctx, 'jwtSignBatchPacked')(
|
|
391
|
-
packed,
|
|
392
|
-
secret,
|
|
393
|
-
ttlSeconds ?? null,
|
|
394
|
-
nowSeconds ?? Math.floor(Date.now() / 1000),
|
|
395
|
-
) as Buffer,
|
|
396
|
-
),
|
|
397
|
-
)
|
|
398
|
-
},
|
|
399
|
-
sseEncode(items, event, id, retry) {
|
|
400
|
-
return withPackScratch(items, (packed) =>
|
|
401
|
-
unpackByteResults(
|
|
402
|
-
nativeFn(ctx, 'sseEncodeBatchPacked')(
|
|
403
|
-
packed,
|
|
404
|
-
event ?? null,
|
|
405
|
-
id ?? null,
|
|
406
|
-
retry ?? null,
|
|
407
|
-
) as Buffer,
|
|
408
|
-
),
|
|
409
|
-
)
|
|
410
|
-
},
|
|
411
|
-
wsFrameEncode(items, opcode, mask, fin) {
|
|
412
|
-
return withPackScratch(items, (packed) =>
|
|
413
|
-
unpackByteResults(
|
|
414
|
-
nativeFn(ctx, 'wsFrameEncodeBatchPacked')(packed, opcode, mask, fin) as Buffer,
|
|
415
|
-
),
|
|
416
|
-
)
|
|
417
|
-
},
|
|
418
|
-
wsFrameDecode(items) {
|
|
419
|
-
return withPackScratch(items, (packed) =>
|
|
420
|
-
unpackByteResults(nativeFn(ctx, 'wsFrameDecodeBatchPacked')(packed) as Buffer),
|
|
421
|
-
)
|
|
422
|
-
},
|
|
423
|
-
multipartParse(items, boundary) {
|
|
424
|
-
return withPackScratch(items, (packed) =>
|
|
425
|
-
unpackMultipartParts(
|
|
426
|
-
nativeFn(ctx, 'multipartParseBatchPacked')(packed, boundary) as Buffer,
|
|
427
|
-
),
|
|
428
|
-
)
|
|
429
|
-
},
|
|
430
|
-
}
|
|
431
|
-
}
|