@pulse-compute/wasm-contracts 1.0.0-beta.3 → 1.0.0-beta.5
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 +2 -2
- package/package.json +2 -2
- package/src/diagnostics.js +1 -1
- package/src/handler/canonical-native-plan.js +8 -1
- package/src/handler/canonical-native-runtime.js +5 -0
- package/src/handler/ctx-contract.js +3 -3
- package/src/handler/runtime-api.js +13 -3
- package/src/handler/surface-contract.js +35 -0
- package/src/handler/types-contract.js +1 -1
- package/src/provider/canonical-provider.js +2 -0
- package/src/s3/contracts.js +1 -1
- package/src/schema-json/registry.js +24 -12
- package/src/schema-json/semantic-trace.js +7 -3
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
> **Supported entry points:** `@pulse-compute/wasm-contracts/provider/toolchain`<br>
|
|
8
8
|
> **Stability:** The provider toolchain contract is versioned and supported for the Beta; other protocol and proof interfaces remain internal.<br>
|
|
9
9
|
> **npm:** [`@pulse-compute/wasm-contracts`](https://www.npmjs.com/package/@pulse-compute/wasm-contracts)<br>
|
|
10
|
-
> **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.
|
|
10
|
+
> **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.5/packages/implementation-packages/)
|
|
11
11
|
>
|
|
12
|
-
> This release-status block is generated from the synchronized `Pulse 1.0.0-beta.
|
|
12
|
+
> This release-status block is generated from the synchronized `Pulse 1.0.0-beta.5` package policy.
|
|
13
13
|
<!-- pulse-package-status:end -->
|
|
14
14
|
|
|
15
15
|
This package owns stable data contracts shared by the compiler, runtime, and providers.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pulse-compute/wasm-contracts",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.5",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^22.14.0 || ^24.0.0"
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"url": "git+https://github.com/pulse-compute/pulse.git",
|
|
127
127
|
"directory": "wasm/packages/contracts"
|
|
128
128
|
},
|
|
129
|
-
"homepage": "https://pulsecompute.io/v1.0.0-beta.
|
|
129
|
+
"homepage": "https://pulsecompute.io/v1.0.0-beta.5/packages/implementation-packages/",
|
|
130
130
|
"bugs": {
|
|
131
131
|
"url": "https://github.com/pulse-compute/pulse/issues"
|
|
132
132
|
}
|
package/src/diagnostics.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
|
|
5
|
-
const PACKAGE_VERSION = 'pulsewasm-route-extractor@1.0.0-beta.
|
|
5
|
+
const PACKAGE_VERSION = 'pulsewasm-route-extractor@1.0.0-beta.5';
|
|
6
6
|
const DIAGNOSTICS_VERSION = 'pulsewasm.diagnostics.v1';
|
|
7
7
|
|
|
8
8
|
function stableFileName(fileName, cwd) {
|
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
const CANONICAL_NATIVE_PLAN_VERSION = 'pulse.canonical-native-plan.v2';
|
|
4
4
|
const CANONICAL_NATIVE_PLAN_HASH_ALGORITHM = 'sha256';
|
|
5
5
|
const CANONICAL_NATIVE_PLAN_OWNERSHIP_VERSION = 'pulse.canonical-native-ownership.v1';
|
|
6
|
+
const CANONICAL_PURE_LOOP_LIMITS = Object.freeze({ maxIterations: 1024, maxNestedIterations: 65536 });
|
|
6
7
|
|
|
7
8
|
const CANONICAL_NATIVE_STATEMENT_KINDS = Object.freeze([
|
|
8
9
|
'local',
|
|
9
10
|
'effect',
|
|
10
11
|
'effect-group',
|
|
11
12
|
'if',
|
|
13
|
+
'pure-loop',
|
|
14
|
+
'break',
|
|
15
|
+
'continue',
|
|
12
16
|
'return',
|
|
13
17
|
'expression'
|
|
14
18
|
]);
|
|
@@ -46,6 +50,8 @@ const CANONICAL_NATIVE_INTRINSICS = Object.freeze([
|
|
|
46
50
|
'request.text',
|
|
47
51
|
'request.json',
|
|
48
52
|
'response.json',
|
|
53
|
+
'schema.encode.text',
|
|
54
|
+
'schema.decode.text',
|
|
49
55
|
'response.text',
|
|
50
56
|
'response.custom',
|
|
51
57
|
'kv.namespace',
|
|
@@ -118,7 +124,7 @@ const CANONICAL_NATIVE_PLAN_POLICY = Object.freeze({
|
|
|
118
124
|
javascriptRuntime: false,
|
|
119
125
|
promiseSemantics: false,
|
|
120
126
|
asyncify: false,
|
|
121
|
-
controlFlow: 'structured
|
|
127
|
+
controlFlow: 'structured statements, if/else, and literal-capped pure for loops; no effect iteration',
|
|
122
128
|
suspension: 'explicit effect and effect-group statements with stable continuation IDs',
|
|
123
129
|
values: 'versioned JSON expression tree with stable local identities',
|
|
124
130
|
logging: 'compile-time threshold pruning plus synchronous provider-adapter emission',
|
|
@@ -129,6 +135,7 @@ const CANONICAL_NATIVE_PLAN_POLICY = Object.freeze({
|
|
|
129
135
|
|
|
130
136
|
module.exports = Object.freeze({
|
|
131
137
|
CANONICAL_NATIVE_PLAN_VERSION,
|
|
138
|
+
CANONICAL_PURE_LOOP_LIMITS,
|
|
132
139
|
CANONICAL_NATIVE_PLAN_HASH_ALGORITHM,
|
|
133
140
|
CANONICAL_NATIVE_PLAN_OWNERSHIP_VERSION,
|
|
134
141
|
CANONICAL_NATIVE_STATEMENT_KINDS,
|
|
@@ -63,6 +63,7 @@ const CANONICAL_NATIVE_IMPORTS = Object.freeze([
|
|
|
63
63
|
['value_unary', ['i32', 'i32'], ['i32']],
|
|
64
64
|
['value_truthy', ['i32'], ['i32']],
|
|
65
65
|
['value_nullish', ['i32'], ['i32']],
|
|
66
|
+
['value_string_trim', ['i32'], ['i32']],
|
|
66
67
|
['log', ['i32', 'i32'], []],
|
|
67
68
|
['request_method', [], ['i32']],
|
|
68
69
|
['request_url', [], ['i32']],
|
|
@@ -73,7 +74,11 @@ const CANONICAL_NATIVE_IMPORTS = Object.freeze([
|
|
|
73
74
|
['request_json', ['i32'], ['i32']],
|
|
74
75
|
['router_match', ['i32', 'i32'], ['i32']],
|
|
75
76
|
['router_param', ['i32', 'i32', 'i32'], ['i32']],
|
|
77
|
+
// 0: no failure; positive: application error handle; negative: terminal failure.
|
|
78
|
+
['router_error_take', [], ['i32']],
|
|
76
79
|
['response_json', ['i32', 'i32'], ['i32']],
|
|
80
|
+
['schema_encode', ['i32', 'i32'], ['i32']],
|
|
81
|
+
['schema_decode', ['i32', 'i32'], ['i32']],
|
|
77
82
|
['response_text', ['i32', 'i32'], ['i32']],
|
|
78
83
|
['response_custom', ['i32'], ['i32']],
|
|
79
84
|
['grip_is_websocket', [], ['i32']],
|
|
@@ -6,8 +6,8 @@ const CTX_CONTRACT_VERSION = 'pulse.ctx-contract.v4';
|
|
|
6
6
|
const CTX_CONTRACT_ID = 'pulse.ctx';
|
|
7
7
|
const CTX_SURFACE_IDS = Object.freeze([
|
|
8
8
|
'ctx.param','ctx.req.method','ctx.req.url','ctx.req.path','ctx.req.header','ctx.req.headers',
|
|
9
|
-
'ctx.state.get','ctx.state.set','ctx.json','ctx.text','ctx.response','ctx.req.text','ctx.req.json.schema',
|
|
10
|
-
'ctx.req.json.generic','ctx.fetch.projected','ctx.fetch.opaque-return','ctx.config.get','ctx.secret.get',
|
|
9
|
+
'ctx.state.get','ctx.state.set','ctx.encodeJson','ctx.decodeJson','ctx.json','ctx.text','ctx.response','ctx.req.text','ctx.req.json.schema',
|
|
10
|
+
'ctx.req.json.generic','ctx.fetch.projected','ctx.fetch.opaque-return','ctx.time.now','ctx.config.get','ctx.secret.get',
|
|
11
11
|
'ctx.kv.get','ctx.kv.put','ctx.kv.getVersioned','ctx.kv.insertIfAbsent','ctx.kv.compareAndSwap','ctx.emit','package.operation'
|
|
12
12
|
]);
|
|
13
13
|
const surfaceById = new Map(HANDLER_SURFACE_DEFINITIONS.map((entry) => [entry.id, entry]));
|
|
@@ -33,7 +33,7 @@ function defaultCtxContract() {
|
|
|
33
33
|
handlerSurfaceVersion: HANDLER_SURFACE_CONTRACT_VERSION,
|
|
34
34
|
surfaces: CTX_SURFACES,
|
|
35
35
|
planes: Object.freeze({
|
|
36
|
-
sharedAuthoring: Object.freeze(['state', 'log', 'fetch', 'parallel', 'config', 'secret', 'kv', 'emit']),
|
|
36
|
+
sharedAuthoring: Object.freeze(['state', 'log', 'time', 'fetch', 'parallel', 'config', 'secret', 'kv', 'emit', 'encodeJson', 'decodeJson']),
|
|
37
37
|
httpAuthoring: Object.freeze(['req', 'json', 'text', 'response']),
|
|
38
38
|
routeAuthoring: Object.freeze(['param']),
|
|
39
39
|
eventAuthoring: Object.freeze(['event.type', 'event.payload']),
|
|
@@ -12,6 +12,7 @@ const ERROR_KINDS = Object.freeze({
|
|
|
12
12
|
fetchTimeout: 'FetchTimeoutError',
|
|
13
13
|
bodyTooLarge: 'BodyTooLargeError',
|
|
14
14
|
bodyDecode: 'BodyDecodeError',
|
|
15
|
+
requestBodyInvalidUtf8: 'RequestBodyInvalidUtf8Error',
|
|
15
16
|
bodyUnavailable: 'BodyUnavailableError',
|
|
16
17
|
opaqueBodyInspection: 'OpaqueBodyInspectionError',
|
|
17
18
|
responseEncode: 'ResponseEncodeError',
|
|
@@ -113,7 +114,7 @@ function readInputBody(input) {
|
|
|
113
114
|
: Object.prototype.hasOwnProperty.call(source, 'text')
|
|
114
115
|
? source.text
|
|
115
116
|
: source.jsonText;
|
|
116
|
-
return { available: true,
|
|
117
|
+
return { available: true, value };
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
function createStructuredBodyValue(input = {}, options = {}) {
|
|
@@ -124,7 +125,8 @@ function createStructuredBodyValue(input = {}, options = {}) {
|
|
|
124
125
|
const contentClass = classifyContentType(contentType);
|
|
125
126
|
const forceStructured = options.forceStructured === true;
|
|
126
127
|
const body = readInputBody(input);
|
|
127
|
-
const
|
|
128
|
+
const raw = body.value instanceof Uint8Array ? body.value : undefined;
|
|
129
|
+
const bytes = raw ? raw.byteLength : utf8ByteLength(body.value);
|
|
128
130
|
const counters = { bodyCopies: 0, textTransforms: 0, jsonTransforms: 0, errors: 0 };
|
|
129
131
|
let textMemo;
|
|
130
132
|
let jsonMemo;
|
|
@@ -156,12 +158,20 @@ function createStructuredBodyValue(input = {}, options = {}) {
|
|
|
156
158
|
textMemo = rejected;
|
|
157
159
|
return textMemo;
|
|
158
160
|
}
|
|
161
|
+
let value;
|
|
162
|
+
try {
|
|
163
|
+
value = raw ? new TextDecoder('utf-8', { fatal: options.strictUtf8 === true, ignoreBOM: true }).decode(raw) : String(body.value ?? '');
|
|
164
|
+
} catch (_) {
|
|
165
|
+
counters.errors += 1;
|
|
166
|
+
textMemo = runtimeValueError(ERROR_KINDS.requestBodyInvalidUtf8, 'Pulse request text must be well-formed UTF-8.');
|
|
167
|
+
return textMemo;
|
|
168
|
+
}
|
|
159
169
|
counters.bodyCopies += 1;
|
|
160
170
|
counters.textTransforms += 1;
|
|
161
171
|
textMemo = deepFreeze({
|
|
162
172
|
ok: true,
|
|
163
173
|
kind: 'structured-text',
|
|
164
|
-
value
|
|
174
|
+
value,
|
|
165
175
|
bytes,
|
|
166
176
|
contentType: String(contentType || ''),
|
|
167
177
|
contentClass,
|
|
@@ -212,6 +212,30 @@ const HANDLER_SURFACE_DEFINITIONS = Object.freeze([
|
|
|
212
212
|
nativeBehavior: 'construct-canonical-result',
|
|
213
213
|
status: 'existing-alias-normalization'
|
|
214
214
|
}),
|
|
215
|
+
surface({
|
|
216
|
+
id: 'ctx.decodeJson',
|
|
217
|
+
class: 'sync',
|
|
218
|
+
canonicalOperation: 'schema.decode.text',
|
|
219
|
+
publicForms: ["ctx.decodeJson<T>(text, 'schema.id')"],
|
|
220
|
+
awaitPolicy: 'optional-redundant-warning',
|
|
221
|
+
validPositions: ['expression', 'return', 'condition'],
|
|
222
|
+
targetSupport: { javascript: true, native: true },
|
|
223
|
+
nativeBehavior: 'decode-bounded-schema-text',
|
|
224
|
+
schemaPolicy: 'literal-schema-required',
|
|
225
|
+
status: 'supported'
|
|
226
|
+
}),
|
|
227
|
+
surface({
|
|
228
|
+
id: 'ctx.encodeJson',
|
|
229
|
+
class: 'sync',
|
|
230
|
+
canonicalOperation: 'schema.encode.text',
|
|
231
|
+
publicForms: ["ctx.encodeJson(value, 'schema.id')"],
|
|
232
|
+
awaitPolicy: 'optional-redundant-warning',
|
|
233
|
+
validPositions: ['expression', 'statement', 'return'],
|
|
234
|
+
targetSupport: { javascript: true, native: true },
|
|
235
|
+
nativeBehavior: 'schema-validated-bounded-json-text',
|
|
236
|
+
schemaPolicy: 'literal-schema-required',
|
|
237
|
+
status: 'supported'
|
|
238
|
+
}),
|
|
215
239
|
surface({
|
|
216
240
|
id: 'ctx.text',
|
|
217
241
|
class: 'sync',
|
|
@@ -303,6 +327,17 @@ const HANDLER_SURFACE_DEFINITIONS = Object.freeze([
|
|
|
303
327
|
nativeBehavior: 'emit-terminal-fetch-effect',
|
|
304
328
|
status: 'supported'
|
|
305
329
|
}),
|
|
330
|
+
surface({
|
|
331
|
+
id: 'ctx.time.now',
|
|
332
|
+
class: 'effect',
|
|
333
|
+
canonicalOperation: 'effect.time.now',
|
|
334
|
+
publicForms: ['ctx.time.now()'],
|
|
335
|
+
awaitPolicy: 'required-when-consumed',
|
|
336
|
+
validPositions: ['await-expression', 'parallel-member'],
|
|
337
|
+
targetSupport: { javascript: true, native: true },
|
|
338
|
+
nativeBehavior: 'emit-provider-wall-clock-effect-and-continuation',
|
|
339
|
+
status: 'supported'
|
|
340
|
+
}),
|
|
306
341
|
surface({
|
|
307
342
|
id: 'ctx.config.get',
|
|
308
343
|
class: 'effect',
|
|
@@ -20,7 +20,7 @@ function defaultHandlerTypesContract() {
|
|
|
20
20
|
set: 'void'
|
|
21
21
|
}),
|
|
22
22
|
executionContexts: Object.freeze({
|
|
23
|
-
shared: Object.freeze(['state', 'log', 'fetch', 'parallel', 'config', 'secret', 'kv', 'emit']),
|
|
23
|
+
shared: Object.freeze(['state', 'log', 'time', 'fetch', 'parallel', 'config', 'secret', 'kv', 'emit', 'encodeJson', 'decodeJson']),
|
|
24
24
|
http: Object.freeze(['req', 'json', 'text', 'response']),
|
|
25
25
|
route: Object.freeze(['param']),
|
|
26
26
|
event: Object.freeze(['event.type', 'event.payload']),
|
package/src/s3/contracts.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const S3_CONTRACT_ID = 'pulse.s3';
|
|
4
4
|
const S3_PACKAGE = '@pulse-compute/s3';
|
|
5
5
|
const S3_LOWERING_PLAN_VERSION = 'pulse.s3-lowering-plan.v1';
|
|
6
|
-
const S3_LIMITS = Object.freeze({ keyBytes: 1024, textBytes: 32768, metadataBytes: 1024, headerBytes: 16384, envelopeBytes:
|
|
6
|
+
const S3_LIMITS = Object.freeze({ keyBytes: 1024, textBytes: 2097152, defaultTextBytes: 32768, metadataBytes: 1024, headerBytes: 16384, envelopeBytes: 12648448 });
|
|
7
7
|
const S3_OPERATIONS = Object.freeze(Object.fromEntries(['head', 'getText', 'putText'].map((name) => [name, Object.freeze({
|
|
8
8
|
kind: `s3.${name}`, capability: `s3.${name}`, result: name === 'head' ? 's3-head-result' : name === 'getText' ? 's3-get-text-result' : 's3-put-text-result'
|
|
9
9
|
})])));
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const { sha256Hex, stableStringify } = require('../stable-id.js');
|
|
4
4
|
|
|
5
|
-
const SCHEMA_REGISTRY_IR_VERSION = 'pulse.schema-registry-ir.
|
|
6
|
-
const SCHEMA_CODEC_INPUTS_VERSION = 'pulse.schema-codec-inputs.
|
|
5
|
+
const SCHEMA_REGISTRY_IR_VERSION = 'pulse.schema-registry-ir.v2';
|
|
6
|
+
const SCHEMA_CODEC_INPUTS_VERSION = 'pulse.schema-codec-inputs.v2';
|
|
7
7
|
const SCHEMA_AUTHORING_VERSION = 'pulse.schema-authoring.v1';
|
|
8
8
|
const SCHEMA_ID_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*(?:\.[A-Za-z][A-Za-z0-9_-]*)+$/;
|
|
9
9
|
const RESPONSE_CASE_ID_PATTERN = SCHEMA_ID_PATTERN;
|
|
@@ -106,15 +106,15 @@ function normalizeSchemaNode(input, field = 'schema.root', stack = []) {
|
|
|
106
106
|
throw schemaContractError('PULSE_SCHEMA_IR_FIELD_DUPLICATE', `${field} declares field ${name} more than once.`, { field, name });
|
|
107
107
|
}
|
|
108
108
|
names.add(name);
|
|
109
|
-
if (entry.required !==
|
|
110
|
-
throw schemaContractError('
|
|
109
|
+
if (typeof entry.required !== 'boolean') {
|
|
110
|
+
throw schemaContractError('PULSE_SCHEMA_IR_FIELD_REQUIRED', `${field}.${name}.required must be a boolean.`, {
|
|
111
111
|
field,
|
|
112
112
|
name
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
return Object.freeze({
|
|
116
116
|
name,
|
|
117
|
-
required:
|
|
117
|
+
required: entry.required,
|
|
118
118
|
value: normalizeSchemaNode(entry.value, `${field}.fields[${index}].value`, [...stack, name]),
|
|
119
119
|
source: entry.source ? normalizeSource(entry.source, `${field}.fields[${index}].source`) : undefined
|
|
120
120
|
});
|
|
@@ -193,7 +193,9 @@ function normalizeSchemaRegistry(input) {
|
|
|
193
193
|
responses,
|
|
194
194
|
policies: deepFreeze({
|
|
195
195
|
objectRoots: true,
|
|
196
|
-
requiredFieldsOnly:
|
|
196
|
+
requiredFieldsOnly: false,
|
|
197
|
+
optionalFields: 'omit-absent-own-properties',
|
|
198
|
+
presentUndefined: 'reject',
|
|
197
199
|
unknownInputFields: 'drop',
|
|
198
200
|
outputFields: 'declared-only',
|
|
199
201
|
outputFieldOrder: 'declaration',
|
|
@@ -248,7 +250,7 @@ function collectNativeClasses(schema, node, symbols, classes, pathParts = []) {
|
|
|
248
250
|
fields: Object.freeze(node.fields.map((field) => Object.freeze({
|
|
249
251
|
name: field.name,
|
|
250
252
|
type: assemblyScriptType(field.value, symbols, [...pathParts, field.name]),
|
|
251
|
-
required:
|
|
253
|
+
required: field.required,
|
|
252
254
|
constraints: field.value.kind === 'string-enum'
|
|
253
255
|
? Object.freeze({ enum: field.value.values })
|
|
254
256
|
: Object.freeze({})
|
|
@@ -256,18 +258,27 @@ function collectNativeClasses(schema, node, symbols, classes, pathParts = []) {
|
|
|
256
258
|
}));
|
|
257
259
|
}
|
|
258
260
|
|
|
261
|
+
function schemaHasOptionalProperties(node) {
|
|
262
|
+
if (node.kind === 'nullable') return schemaHasOptionalProperties(node.value);
|
|
263
|
+
if (node.kind === 'array') return schemaHasOptionalProperties(node.element);
|
|
264
|
+
return node.kind === 'object' && node.fields.some(field => !field.required || schemaHasOptionalProperties(field.value));
|
|
265
|
+
}
|
|
266
|
+
|
|
259
267
|
function codecInputsForRegistry(registryInput) {
|
|
260
268
|
const registry = normalizeSchemaRegistry(registryInput);
|
|
261
269
|
const nativeSchemas = registry.schemas.map((schema) => {
|
|
262
270
|
const schemaClasses = [];
|
|
263
271
|
const symbols = new Map();
|
|
264
|
-
|
|
272
|
+
const presence = schemaHasOptionalProperties(schema.root);
|
|
273
|
+
if (!presence) collectNativeClasses(schema, schema.root, symbols, schemaClasses);
|
|
274
|
+
const rootClass = presence ? 'JSON.Value' : symbols.get('');
|
|
265
275
|
return Object.freeze({
|
|
266
276
|
id: schema.id,
|
|
267
|
-
rootClass
|
|
277
|
+
rootClass,
|
|
278
|
+
representation: presence ? 'schema-projected-json-value' : 'required-struct',
|
|
268
279
|
classes: Object.freeze(schemaClasses),
|
|
269
|
-
parse: `JSON.parse<${
|
|
270
|
-
stringify: `JSON.stringify<${
|
|
280
|
+
parse: `JSON.parse<${rootClass}>`,
|
|
281
|
+
stringify: `JSON.stringify<${rootClass}>`
|
|
271
282
|
});
|
|
272
283
|
});
|
|
273
284
|
return deepFreeze({
|
|
@@ -333,7 +344,7 @@ function defaultSchemaRegistryContract() {
|
|
|
333
344
|
stableStringIds: true,
|
|
334
345
|
exactLiteralIdsAtBoundaries: true,
|
|
335
346
|
oldSchemasJsonSupported: false,
|
|
336
|
-
optionalPropertiesSupported:
|
|
347
|
+
optionalPropertiesSupported: true,
|
|
337
348
|
recursiveSchemasSupported: false,
|
|
338
349
|
publicJsonAsImportsSupported: false,
|
|
339
350
|
automaticFallback: false
|
|
@@ -354,6 +365,7 @@ module.exports = Object.freeze({
|
|
|
354
365
|
normalizeSchemaNode,
|
|
355
366
|
normalizeSchemaRegistry,
|
|
356
367
|
codecInputsForRegistry,
|
|
368
|
+
schemaHasOptionalProperties,
|
|
357
369
|
defaultSchemaBoundaryPolicy,
|
|
358
370
|
defaultSchemaRegistryContract
|
|
359
371
|
});
|
|
@@ -7,12 +7,14 @@ const JSON_SEMANTIC_TRACE_VERSION = 'pulse.json-semantic-trace.v1';
|
|
|
7
7
|
const JSON_TRACE_EVENT_KINDS = Object.freeze([
|
|
8
8
|
'json.decode.request',
|
|
9
9
|
'json.decode.fetch',
|
|
10
|
+
'json.decode.text',
|
|
10
11
|
'json.encode.response',
|
|
11
12
|
'json.encode.fetch',
|
|
13
|
+
'json.encode.value',
|
|
12
14
|
'json.decode.error',
|
|
13
15
|
'json.encode.error'
|
|
14
16
|
]);
|
|
15
|
-
const JSON_BOUNDARIES = Object.freeze(['request', 'fetch-response', 'application-response', 'fetch-request']);
|
|
17
|
+
const JSON_BOUNDARIES = Object.freeze(['request', 'fetch-response', 'application-response', 'fetch-request', 'application-value', 'application-text']);
|
|
16
18
|
const JSON_BODY_OWNERSHIP = Object.freeze([
|
|
17
19
|
'request-snapshot',
|
|
18
20
|
'fetched-response-snapshot',
|
|
@@ -22,10 +24,12 @@ const JSON_BODY_OWNERSHIP = Object.freeze([
|
|
|
22
24
|
const JSON_EVENT_BOUNDARIES = Object.freeze({
|
|
23
25
|
'json.decode.request': Object.freeze(['request']),
|
|
24
26
|
'json.decode.fetch': Object.freeze(['fetch-response']),
|
|
27
|
+
'json.decode.text': Object.freeze(['application-text']),
|
|
25
28
|
'json.encode.response': Object.freeze(['application-response']),
|
|
26
29
|
'json.encode.fetch': Object.freeze(['fetch-request']),
|
|
27
|
-
'json.
|
|
28
|
-
'json.
|
|
30
|
+
'json.encode.value': Object.freeze(['application-value']),
|
|
31
|
+
'json.decode.error': Object.freeze(['request', 'fetch-response', 'application-text']),
|
|
32
|
+
'json.encode.error': Object.freeze(['application-response', 'fetch-request', 'application-value'])
|
|
29
33
|
});
|
|
30
34
|
|
|
31
35
|
function traceError(code, message, details = {}) {
|