@prisma/param-graph 7.4.0-integration-parameterization.10 → 7.4.0-integration-parameterization.11
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/dist/serialization.d.ts +102 -0
- package/dist/serialization.js +9 -2
- package/dist/serialization.mjs +9 -2
- package/package.json +1 -1
package/dist/serialization.d.ts
CHANGED
|
@@ -4,6 +4,108 @@
|
|
|
4
4
|
* This module handles compact binary encoding/decoding of the param graph structure.
|
|
5
5
|
* The format uses a hybrid approach: JSON string array for field names + binary blob
|
|
6
6
|
* for structural data (nodes, edges, roots).
|
|
7
|
+
*
|
|
8
|
+
* ## Serialized Representation
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* SerializedParamGraph {
|
|
12
|
+
* strings: string[] // String table (field names, enum names, root keys)
|
|
13
|
+
* graph: string // Base64url-encoded binary blob
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* ## Why Hybrid?
|
|
18
|
+
*
|
|
19
|
+
* - **Strings stay as JSON**: V8's JSON.parse is highly optimized for string arrays
|
|
20
|
+
* - **Structure goes binary**: Indices, flags, masks benefit from compact encoding
|
|
21
|
+
* - **Best of both**: Fast parsing + compact size where it matters
|
|
22
|
+
*
|
|
23
|
+
* ## Format Selection
|
|
24
|
+
*
|
|
25
|
+
* Two binary formats based on data size (selected automatically at serialization):
|
|
26
|
+
*
|
|
27
|
+
* - **Compact (0x00)**: 16-bit indices, for graphs with ≤65534 items
|
|
28
|
+
* - **Wide (0x01)**: 32-bit indices, for larger graphs
|
|
29
|
+
*
|
|
30
|
+
* Sentinel values for "none/undefined": 0xFFFF (compact) or 0xFFFFFFFF (wide)
|
|
31
|
+
*
|
|
32
|
+
* ## Binary Blob Layout
|
|
33
|
+
*
|
|
34
|
+
* All multi-byte integers are little-endian.
|
|
35
|
+
*
|
|
36
|
+
* ```
|
|
37
|
+
* ┌───────────────────────────────────────────────────────────────────┐
|
|
38
|
+
* │ HEADER │
|
|
39
|
+
* ├───────────────────────────────────────────────────────────────────┤
|
|
40
|
+
* │ format: u8 │ 0x00 = compact (16-bit), 0x01 = wide │
|
|
41
|
+
* │ padding: 1|3 bytes │ Alignment padding (1 compact, 3 wide) │
|
|
42
|
+
* │ inputNodeCount: word │ Number of input nodes │
|
|
43
|
+
* │ outputNodeCount: word │ Number of output nodes │
|
|
44
|
+
* │ rootCount: word │ Number of root entries │
|
|
45
|
+
* └───────────────────────────────────────────────────────────────────┘
|
|
46
|
+
*
|
|
47
|
+
* ┌───────────────────────────────────────────────────────────────────┐
|
|
48
|
+
* │ INPUT NODES (repeated inputNodeCount times) │
|
|
49
|
+
* ├───────────────────────────────────────────────────────────────────┤
|
|
50
|
+
* │ edgeCount: word │ Number of edges in this node │
|
|
51
|
+
* │ edges[] │ Edge data (see Input Edge below) │
|
|
52
|
+
* └───────────────────────────────────────────────────────────────────┘
|
|
53
|
+
*
|
|
54
|
+
* ┌───────────────────────────────────────────────────────────────────┐
|
|
55
|
+
* │ INPUT EDGE (compact: 10 bytes, wide: 20 bytes) │
|
|
56
|
+
* ├───────────────────────────────────────────────────────────────────┤
|
|
57
|
+
* │ fieldIndex: word │ Index into string table │
|
|
58
|
+
* │ scalarMask: u16 │ Scalar type bitmask (0 if none) │
|
|
59
|
+
* │ [padding: 2 bytes] │ (wide format only, for alignment) │
|
|
60
|
+
* │ childNodeId: word │ Child input node ID (sentinel=none) │
|
|
61
|
+
* │ enumNameIndex: word │ Enum name in string table (sentinel=none) │
|
|
62
|
+
* │ flags: u8 │ Edge capability flags │
|
|
63
|
+
* │ padding: 1|3 bytes │ Alignment padding (1 compact, 3 wide) │
|
|
64
|
+
* └───────────────────────────────────────────────────────────────────┘
|
|
65
|
+
*
|
|
66
|
+
* ┌───────────────────────────────────────────────────────────────────┐
|
|
67
|
+
* │ OUTPUT NODES (repeated outputNodeCount times) │
|
|
68
|
+
* ├───────────────────────────────────────────────────────────────────┤
|
|
69
|
+
* │ edgeCount: word │ Number of edges in this node │
|
|
70
|
+
* │ edges[] │ Edge data (see Output Edge below) │
|
|
71
|
+
* └───────────────────────────────────────────────────────────────────┘
|
|
72
|
+
*
|
|
73
|
+
* ┌───────────────────────────────────────────────────────────────────┐
|
|
74
|
+
* │ OUTPUT EDGE (compact: 6 bytes, wide: 12 bytes) │
|
|
75
|
+
* ├───────────────────────────────────────────────────────────────────┤
|
|
76
|
+
* │ fieldIndex: word │ Index into string table │
|
|
77
|
+
* │ argsNodeId: word │ Args input node ID (sentinel=none) │
|
|
78
|
+
* │ outputNodeId: word │ Child output node ID (sentinel=none) │
|
|
79
|
+
* └───────────────────────────────────────────────────────────────────┘
|
|
80
|
+
*
|
|
81
|
+
* ┌───────────────────────────────────────────────────────────────────┐
|
|
82
|
+
* │ ROOTS (repeated rootCount times) │
|
|
83
|
+
* ├───────────────────────────────────────────────────────────────────┤
|
|
84
|
+
* │ keyIndex: word │ Root key index in string table │
|
|
85
|
+
* │ argsNodeId: word │ Args input node ID (sentinel=none) │
|
|
86
|
+
* │ outputNodeId: word │ Output node ID (sentinel=none) │
|
|
87
|
+
* └───────────────────────────────────────────────────────────────────┘
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* Where "word" is u16 (compact) or u32 (wide).
|
|
91
|
+
*
|
|
92
|
+
* ## Size Summary
|
|
93
|
+
*
|
|
94
|
+
* | Component | Compact | Wide |
|
|
95
|
+
* |----------------|----------|----------|
|
|
96
|
+
* | Header | 8 bytes | 16 bytes |
|
|
97
|
+
* | Input Edge | 10 bytes | 20 bytes |
|
|
98
|
+
* | Output Edge | 6 bytes | 12 bytes |
|
|
99
|
+
* | Root Entry | 6 bytes | 12 bytes |
|
|
100
|
+
*
|
|
101
|
+
* ## Embedding in Generated Client
|
|
102
|
+
*
|
|
103
|
+
* ```js
|
|
104
|
+
* config.parameterizationSchema = {
|
|
105
|
+
* strings: JSON.parse('["where","id","email",...]'),
|
|
106
|
+
* graph: "base64url_encoded_binary_blob..."
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
7
109
|
*/
|
|
8
110
|
import type { ParamGraphData } from './types';
|
|
9
111
|
/**
|
package/dist/serialization.js
CHANGED
|
@@ -99,8 +99,7 @@ class Serializer {
|
|
|
99
99
|
this.#offset += bytes;
|
|
100
100
|
}
|
|
101
101
|
#calculateBufferSize() {
|
|
102
|
-
let size =
|
|
103
|
-
size += this.#useWide ? 12 : 6;
|
|
102
|
+
let size = this.#useWide ? 16 : 8;
|
|
104
103
|
for (const node of this.#data.inputNodes) {
|
|
105
104
|
size += this.#wordSize;
|
|
106
105
|
const edgeCount = Object.keys(node.edges).length;
|
|
@@ -116,6 +115,7 @@ class Serializer {
|
|
|
116
115
|
}
|
|
117
116
|
#writeHeader() {
|
|
118
117
|
this.#writeByte(this.#useWide ? FORMAT_WIDE : FORMAT_COMPACT);
|
|
118
|
+
this.#skip(this.#useWide ? 3 : 1);
|
|
119
119
|
this.#writeWord(this.#data.inputNodes.length);
|
|
120
120
|
this.#writeWord(this.#data.outputNodes.length);
|
|
121
121
|
this.#writeWord(this.#rootKeys.length);
|
|
@@ -154,6 +154,9 @@ class Serializer {
|
|
|
154
154
|
for (const key of this.#rootKeys) {
|
|
155
155
|
const root = this.#data.roots[key];
|
|
156
156
|
const keyIndex = this.#data.strings.indexOf(key);
|
|
157
|
+
if (keyIndex === -1) {
|
|
158
|
+
throw new Error(`Root key "${key}" not found in strings table`);
|
|
159
|
+
}
|
|
157
160
|
this.#writeWord(keyIndex);
|
|
158
161
|
this.#writeOptionalWord(root.argsNodeId);
|
|
159
162
|
this.#writeOptionalWord(root.outputNodeId);
|
|
@@ -217,7 +220,11 @@ class Deserializer {
|
|
|
217
220
|
}
|
|
218
221
|
#readHeader() {
|
|
219
222
|
const format = this.#readByte();
|
|
223
|
+
if (format !== FORMAT_COMPACT && format !== FORMAT_WIDE) {
|
|
224
|
+
throw new Error(`Unknown param graph format: 0x${format.toString(16).padStart(2, "0")}`);
|
|
225
|
+
}
|
|
220
226
|
this.#useWide = format === FORMAT_WIDE;
|
|
227
|
+
this.#skip(this.#useWide ? 3 : 1);
|
|
221
228
|
const inputNodeCount = this.#readWord();
|
|
222
229
|
const outputNodeCount = this.#readWord();
|
|
223
230
|
const rootCount = this.#readWord();
|
package/dist/serialization.mjs
CHANGED
|
@@ -75,8 +75,7 @@ class Serializer {
|
|
|
75
75
|
this.#offset += bytes;
|
|
76
76
|
}
|
|
77
77
|
#calculateBufferSize() {
|
|
78
|
-
let size =
|
|
79
|
-
size += this.#useWide ? 12 : 6;
|
|
78
|
+
let size = this.#useWide ? 16 : 8;
|
|
80
79
|
for (const node of this.#data.inputNodes) {
|
|
81
80
|
size += this.#wordSize;
|
|
82
81
|
const edgeCount = Object.keys(node.edges).length;
|
|
@@ -92,6 +91,7 @@ class Serializer {
|
|
|
92
91
|
}
|
|
93
92
|
#writeHeader() {
|
|
94
93
|
this.#writeByte(this.#useWide ? FORMAT_WIDE : FORMAT_COMPACT);
|
|
94
|
+
this.#skip(this.#useWide ? 3 : 1);
|
|
95
95
|
this.#writeWord(this.#data.inputNodes.length);
|
|
96
96
|
this.#writeWord(this.#data.outputNodes.length);
|
|
97
97
|
this.#writeWord(this.#rootKeys.length);
|
|
@@ -130,6 +130,9 @@ class Serializer {
|
|
|
130
130
|
for (const key of this.#rootKeys) {
|
|
131
131
|
const root = this.#data.roots[key];
|
|
132
132
|
const keyIndex = this.#data.strings.indexOf(key);
|
|
133
|
+
if (keyIndex === -1) {
|
|
134
|
+
throw new Error(`Root key "${key}" not found in strings table`);
|
|
135
|
+
}
|
|
133
136
|
this.#writeWord(keyIndex);
|
|
134
137
|
this.#writeOptionalWord(root.argsNodeId);
|
|
135
138
|
this.#writeOptionalWord(root.outputNodeId);
|
|
@@ -193,7 +196,11 @@ class Deserializer {
|
|
|
193
196
|
}
|
|
194
197
|
#readHeader() {
|
|
195
198
|
const format = this.#readByte();
|
|
199
|
+
if (format !== FORMAT_COMPACT && format !== FORMAT_WIDE) {
|
|
200
|
+
throw new Error(`Unknown param graph format: 0x${format.toString(16).padStart(2, "0")}`);
|
|
201
|
+
}
|
|
196
202
|
this.#useWide = format === FORMAT_WIDE;
|
|
203
|
+
this.#skip(this.#useWide ? 3 : 1);
|
|
197
204
|
const inputNodeCount = this.#readWord();
|
|
198
205
|
const outputNodeCount = this.#readWord();
|
|
199
206
|
const rootCount = this.#readWord();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/param-graph",
|
|
3
|
-
"version": "7.4.0-integration-parameterization.
|
|
3
|
+
"version": "7.4.0-integration-parameterization.11",
|
|
4
4
|
"description": "This package is intended for Prisma's internal use",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|