@pulse-compute/wasm-contracts 0.0.0 → 1.0.0-beta.1

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.
Files changed (96) hide show
  1. package/README.md +34 -2
  2. package/package.json +123 -6
  3. package/src/assets/contracts.js +296 -0
  4. package/src/config/provider-resolution.js +54 -0
  5. package/src/config/runtime-provider-kv.js +73 -0
  6. package/src/config/symbolic-refs.js +192 -0
  7. package/src/crypto/contracts.js +637 -0
  8. package/src/definitions/config-schema.js +30 -0
  9. package/src/definitions/handler-roles.js +66 -0
  10. package/src/definitions/path-grammar.js +11 -0
  11. package/src/definitions/router-api.js +146 -0
  12. package/src/diagnostics/codes.js +42 -0
  13. package/src/diagnostics/reporter.js +20 -0
  14. package/src/diagnostics.js +139 -0
  15. package/src/dispatch-table.js +23 -0
  16. package/src/entities/catalog.d.ts +7 -0
  17. package/src/entities/catalog.js +87 -0
  18. package/src/entities/contracts.d.ts +95 -0
  19. package/src/entities/contracts.js +122 -0
  20. package/src/entities/json-rpc.d.ts +27 -0
  21. package/src/entities/json-rpc.js +69 -0
  22. package/src/entities/runtime.d.ts +67 -0
  23. package/src/entities/runtime.js +288 -0
  24. package/src/events/contracts.js +456 -0
  25. package/src/execution-plan.js +42 -0
  26. package/src/grip/contracts.js +106 -0
  27. package/src/handler/backend-json-request-body.js +58 -0
  28. package/src/handler/beta-lifecycle-golden.js +97 -0
  29. package/src/handler/canonical-native-plan.js +143 -0
  30. package/src/handler/canonical-native-runtime.js +168 -0
  31. package/src/handler/canonical-runtime.js +13 -0
  32. package/src/handler/context.js +131 -0
  33. package/src/handler/ctx-contract.js +71 -0
  34. package/src/handler/doctor-readiness-aggregator.js +67 -0
  35. package/src/handler/effects.js +446 -0
  36. package/src/handler/io-lifecycle.js +134 -0
  37. package/src/handler/lifecycle-authoring-alignment.js +52 -0
  38. package/src/handler/lifecycle-readiness-aggregate.js +93 -0
  39. package/src/handler/reference-node-lifecycle-golden.js +73 -0
  40. package/src/handler/request-json-body.js +147 -0
  41. package/src/handler/runtime-api.js +471 -0
  42. package/src/handler/schema-decode-result.js +135 -0
  43. package/src/handler/schema-response-codec.js +141 -0
  44. package/src/handler/surface-contract.js +594 -0
  45. package/src/handler/types-contract.js +51 -0
  46. package/src/handler-table.js +28 -0
  47. package/src/host/backend-capabilities.js +24 -0
  48. package/src/host/capabilities.js +273 -0
  49. package/src/host/channel-broadcaster.js +60 -0
  50. package/src/host/json-body.js +80 -0
  51. package/src/host/request-result-headers.js +38 -0
  52. package/src/host/streaming-passthrough.js +90 -0
  53. package/src/host/wasm-host-abi.js +154 -0
  54. package/src/index.js +75 -0
  55. package/src/jwt/contracts.js +427 -0
  56. package/src/library/api-surface.js +99 -0
  57. package/src/library/contracts.js +273 -0
  58. package/src/library/manifest.js +317 -0
  59. package/src/library/second-package-owned-lowering.js +39 -0
  60. package/src/library/sidecars.js +147 -0
  61. package/src/logging.js +89 -0
  62. package/src/package/package-contract.js +975 -0
  63. package/src/package/package-contract.schema.json +303 -0
  64. package/src/package/runtime-pulse-live.js +100 -0
  65. package/src/path-table.js +12 -0
  66. package/src/path.js +275 -0
  67. package/src/project/config-factory.js +48 -0
  68. package/src/project/config-plan.js +409 -0
  69. package/src/project/config-runtime.js +46 -0
  70. package/src/project/javascript-application.js +212 -0
  71. package/src/project/javascript-core-capabilities.js +44 -0
  72. package/src/project/native-optimization.js +9 -0
  73. package/src/project/package-ownership.js +242 -0
  74. package/src/project/package-product-projection.js +171 -0
  75. package/src/project/reachable-graph-identity.js +219 -0
  76. package/src/project/reachable-graph-projections.js +279 -0
  77. package/src/project/reachable-graph-resolver.js +303 -0
  78. package/src/project/reachable-graph-v2.js +430 -0
  79. package/src/project/reachable-graph-v2.schema.json +285 -0
  80. package/src/project/reachable-graph.js +199 -0
  81. package/src/project/reachable-graph.schema.json +222 -0
  82. package/src/project/target-support-evidence.js +559 -0
  83. package/src/provider/canonical-provider.js +235 -0
  84. package/src/provider/final-wasm-policy.js +87 -0
  85. package/src/provider/toolchain.js +771 -0
  86. package/src/route-plan.js +43 -0
  87. package/src/schema-json/compile.js +63 -0
  88. package/src/schema-json/contracts.js +10 -0
  89. package/src/schema-json/generic-parser.js +62 -0
  90. package/src/schema-json/registry.js +359 -0
  91. package/src/schema-json/semantic-trace.js +241 -0
  92. package/src/schema-json/v1.js +65 -0
  93. package/src/schema-json/v2.js +110 -0
  94. package/src/sha256.js +104 -0
  95. package/src/spine.js +381 -0
  96. package/src/stable-id.js +142 -0
@@ -0,0 +1,122 @@
1
+ 'use strict';
2
+
3
+ const { sha256Hex, stableStringify } = require('../stable-id.js');
4
+ const { PACKAGE_INTRINSIC_VERSION } = require('../package/package-contract.js');
5
+ const runtime = require('./runtime.js');
6
+
7
+ const ENTITIES_PACKAGE_VERSION = 'pulse.entities-package.v1';
8
+ const ENTITIES_CONTRACT_VERSION = 'pulse.entities-contract.v1';
9
+ const ENTITIES_PLAN_VERSION = 'pulse.entities-lowering-plan.v1';
10
+ const ENTITIES_CATALOG_VERSION = 'pulse.entities-catalog.v1';
11
+ const ENTITIES_DIAGNOSTIC_VERSION = 'pulse.entities-diagnostics.v1';
12
+ const ENTITIES_HANDLER_REFERENCE_VERSION = 'pulse.entities-handler-reference.v1';
13
+ const ENTITIES_REGISTRY_VERSION = 'pulse.entities-registry.v1';
14
+ const ENTITIES_CONTRACT_ID = 'pulse.entities';
15
+ const ENTITIES_PACKAGE_NAME = '@pulse-compute/entities';
16
+ const ENTITIES_LOWERER_ID = 'pulse.entities.compiler-builder.v1';
17
+ const ENTITIES_LOWERER_EXPORT = 'createEntitiesPackageCompilerBuilder';
18
+ const ENTITIES_LOWERER_MANIFEST = './pulsewasm.manifest.cjs';
19
+ const ENTITIES_LOWERABLE_SUBPATH = '@pulse-compute/entities';
20
+ const ENTITIES_PACKAGE_INTRINSIC_VERSION = PACKAGE_INTRINSIC_VERSION;
21
+ const ENTITIES_PUBLIC_SYMBOLS = Object.freeze(['EntityRouter', 'jsonRpc']);
22
+ const ENTITIES_PACKAGE_INTRINSICS = Object.freeze({
23
+ handle: Object.freeze({
24
+ name: 'pulse.entities.handle.v1',
25
+ compilerName: '__pulse_entities_handle',
26
+ valueKind: 'response',
27
+ argumentIndexes: Object.freeze([0])
28
+ })
29
+ });
30
+ const ROUTER_ID_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/;
31
+
32
+ function normalizeHandlerReference(input) {
33
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
34
+ throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.HANDLER_UNRESOLVED, 'Entity handler reference must be an object.');
35
+ }
36
+ const unknown = Object.keys(input).filter((key) => !['version', 'file', 'exportName', 'localName'].includes(key)).sort();
37
+ if (unknown.length > 0) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.HANDLER_UNRESOLVED, `Entity handler reference contains unsupported fields: ${unknown.join(', ')}.`);
38
+ const version = input.version === undefined ? ENTITIES_HANDLER_REFERENCE_VERSION : String(input.version);
39
+ const file = typeof input.file === 'string' ? input.file.replace(/\\/g, '/') : '';
40
+ const exportName = typeof input.exportName === 'string' ? input.exportName : '';
41
+ const localName = input.localName === undefined ? exportName : String(input.localName);
42
+ if (version !== ENTITIES_HANDLER_REFERENCE_VERSION || !file || file.startsWith('/') || file.split('/').includes('..') || !exportName || !localName) {
43
+ throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.HANDLER_UNRESOLVED, 'Entity handler reference must use a portable file and named export.', { version, file, exportName, localName });
44
+ }
45
+ return Object.freeze({ version, file, exportName, localName });
46
+ }
47
+
48
+ function normalizeEntityRegistry(entriesInput, limitsInput = runtime.ENTITIES_DEFAULT_LIMITS) {
49
+ const limits = limitsInput === runtime.ENTITIES_DEFAULT_LIMITS ? limitsInput : runtime.normalizeEntityLimits(limitsInput);
50
+ if (!Array.isArray(entriesInput)) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, 'Entity registry entries must be an array.');
51
+ if (entriesInput.length > limits.maxEntities) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.LIMIT_EXCEEDED, 'Entity registry exceeds its entity limit.', { count: entriesInput.length, maxEntities: limits.maxEntities });
52
+ const seen = new Set();
53
+ const entries = entriesInput.map((entry) => {
54
+ const normalized = runtime.normalizeEntityRegistration(entry, limits);
55
+ if (seen.has(normalized.discriminator)) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DISCRIMINATOR_DUPLICATE, `Entity discriminator ${JSON.stringify(normalized.discriminator)} is already registered.`, { discriminator: normalized.discriminator });
56
+ seen.add(normalized.discriminator);
57
+ return normalized;
58
+ }).sort((left, right) => runtime.compareText(left.discriminator, right.discriminator));
59
+ const metadataBytes = entries.reduce((sum, entry) => sum + (entry.declaration.metadata ? runtime.utf8ByteLength(stableStringify(entry.declaration.metadata)) : 0), 0);
60
+ if (metadataBytes > limits.maxMetadataBytesPerRouter) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.LIMIT_EXCEEDED, 'Entity router metadata exceeds its aggregate byte limit.', { metadataBytes, maxBytes: limits.maxMetadataBytesPerRouter });
61
+ const semantic = entries.map((entry) => ({ discriminator: entry.discriminator, input: entry.declaration.input, output: entry.declaration.output, metadata: entry.declaration.metadata, handler: entry.handler.name }));
62
+ return Object.freeze({ version: ENTITIES_REGISTRY_VERSION, entries: Object.freeze(entries), registryHash: sha256Hex(stableStringify(semantic)), limits });
63
+ }
64
+
65
+ function normalizeEntityPlan(input) {
66
+ if (!input || typeof input !== 'object' || Array.isArray(input) || input.version !== ENTITIES_PLAN_VERSION || input.contractId !== ENTITIES_CONTRACT_ID || !Array.isArray(input.routers)) {
67
+ throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `Entity plan requires ${ENTITIES_PLAN_VERSION} and ${ENTITIES_CONTRACT_ID}.`);
68
+ }
69
+ const unknownPlan = Object.keys(input).filter((key) => !['version', 'contractId', 'routers'].includes(key)).sort();
70
+ if (unknownPlan.length > 0) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `Entity plan contains unsupported fields: ${unknownPlan.join(', ')}.`);
71
+ const routerIds = new Set();
72
+ const routers = input.routers.map((router, routerIndex) => {
73
+ if (!router || typeof router !== 'object' || Array.isArray(router)) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `routers[${routerIndex}] must be an object.`);
74
+ const unknownRouter = Object.keys(router).filter((key) => !['id', 'adapter', 'binding', 'entities'].includes(key)).sort();
75
+ if (unknownRouter.length > 0) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `routers[${routerIndex}] contains unsupported fields: ${unknownRouter.join(', ')}.`);
76
+ const id = String(router.id || '');
77
+ if (!ROUTER_ID_PATTERN.test(id) || routerIds.has(id)) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `Entity router ID is invalid or duplicated: ${id}.`, { id });
78
+ routerIds.add(id);
79
+ if (!router.binding || router.binding.kind !== 'request') throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.BINDING_UNSUPPORTED, 'Entity plan binding must be request.');
80
+ const adapter = runtime.normalizeAdapter(router.adapter);
81
+ if (!Array.isArray(router.entities)) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `routers[${routerIndex}].entities must be an array.`);
82
+ if (router.entities.length > runtime.ENTITIES_DEFAULT_LIMITS.maxEntities) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.LIMIT_EXCEEDED, `Entity plan router ${id} exceeds its entity limit.`);
83
+ const discriminators = new Set();
84
+ const entities = router.entities.map((entity, entityIndex) => {
85
+ if (!entity || typeof entity !== 'object' || Array.isArray(entity)) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `routers[${routerIndex}].entities[${entityIndex}] must be an object.`);
86
+ const unknown = Object.keys(entity).filter((key) => !['discriminator', 'inputSchema', 'outputSchema', 'handler', 'metadata'].includes(key)).sort();
87
+ if (unknown.length > 0) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `Entity contains unsupported fields: ${unknown.join(', ')}.`);
88
+ const discriminator = runtime.normalizeDiscriminator(entity.discriminator);
89
+ if (discriminators.has(discriminator)) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.DISCRIMINATOR_DUPLICATE, `Duplicate entity ${discriminator}.`, { discriminator });
90
+ discriminators.add(discriminator);
91
+ return Object.freeze({ discriminator, inputSchema: runtime.normalizeSchemaId(entity.inputSchema, 'inputSchema'), outputSchema: runtime.normalizeSchemaId(entity.outputSchema, 'outputSchema'), handler: normalizeHandlerReference(entity.handler), ...(entity.metadata === undefined ? {} : { metadata: runtime.normalizeStaticMetadata(entity.metadata) }) });
92
+ }).sort((left, right) => runtime.compareText(left.discriminator, right.discriminator));
93
+ const metadataBytes = entities.reduce((sum, entity) => sum + (entity.metadata ? runtime.utf8ByteLength(stableStringify(entity.metadata)) : 0), 0);
94
+ if (metadataBytes > runtime.ENTITIES_DEFAULT_LIMITS.maxMetadataBytesPerRouter) throw runtime.entitiesContractError(runtime.ENTITIES_DIAGNOSTIC_CODES.LIMIT_EXCEEDED, `Entity plan router ${id} exceeds its metadata limit.`);
95
+ return Object.freeze({ id, adapter, binding: Object.freeze({ kind: 'request' }), entities: Object.freeze(entities) });
96
+ }).sort((left, right) => runtime.compareText(left.id, right.id));
97
+ const normalized = Object.freeze({ version: ENTITIES_PLAN_VERSION, contractId: ENTITIES_CONTRACT_ID, routers: Object.freeze(routers) });
98
+ return Object.freeze({ ...normalized, planHash: sha256Hex(stableStringify(normalized)) });
99
+ }
100
+
101
+ module.exports = Object.freeze({
102
+ ...runtime,
103
+ ENTITIES_PACKAGE_VERSION,
104
+ ENTITIES_CONTRACT_VERSION,
105
+ ENTITIES_PLAN_VERSION,
106
+ ENTITIES_CATALOG_VERSION,
107
+ ENTITIES_DIAGNOSTIC_VERSION,
108
+ ENTITIES_HANDLER_REFERENCE_VERSION,
109
+ ENTITIES_REGISTRY_VERSION,
110
+ ENTITIES_CONTRACT_ID,
111
+ ENTITIES_PACKAGE_NAME,
112
+ ENTITIES_LOWERER_ID,
113
+ ENTITIES_LOWERER_EXPORT,
114
+ ENTITIES_LOWERER_MANIFEST,
115
+ ENTITIES_LOWERABLE_SUBPATH,
116
+ ENTITIES_PACKAGE_INTRINSIC_VERSION,
117
+ ENTITIES_PUBLIC_SYMBOLS,
118
+ ENTITIES_PACKAGE_INTRINSICS,
119
+ normalizeHandlerReference,
120
+ normalizeEntityRegistry,
121
+ normalizeEntityPlan
122
+ });
@@ -0,0 +1,27 @@
1
+ import runtime = require('./runtime.js');
2
+
3
+ declare interface JsonRpcOptions {
4
+ readonly namedParamsOnly?: true;
5
+ readonly acceptEmptyObjectForNoInput?: boolean;
6
+ }
7
+
8
+ declare const jsonRpcContracts: {
9
+ readonly ENTITIES_JSON_RPC_ADAPTER_VERSION: 'pulse.entities-json-rpc-adapter.v1';
10
+ readonly ENTITIES_JSON_RPC_ADAPTER_ID: 'json-rpc';
11
+ readonly ENTITIES_JSON_RPC_PROTOCOL: '2.0';
12
+ readonly ENTITIES_JSON_RPC_OPTIONS: Readonly<{ namedParamsOnly: true; acceptEmptyObjectForNoInput: false }>;
13
+ readonly ENTITIES_JSON_RPC_ERROR_CODES: Readonly<Record<string, number>>;
14
+ readonly ENTITIES_JSON_RPC_FAILURE_MAP: Readonly<Record<string, Readonly<{ code: number; message: string }>>>;
15
+ normalizeJsonRpcOptions(input?: JsonRpcOptions): Readonly<{ namedParamsOnly: true; acceptEmptyObjectForNoInput: boolean }>;
16
+ createJsonRpcAdapter(input?: JsonRpcOptions, limits?: typeof runtime.ENTITIES_DEFAULT_LIMITS): Readonly<{
17
+ version: string;
18
+ id: 'json-rpc';
19
+ adapterVersion: string;
20
+ options: Readonly<{ namedParamsOnly: true; acceptEmptyObjectForNoInput: boolean }>;
21
+ limits: typeof runtime.ENTITIES_DEFAULT_LIMITS;
22
+ }>;
23
+ normalizeJsonRpcId(value: unknown, present?: boolean): Readonly<{ kind: string; value: unknown }>;
24
+ mapEntitiesFailureToJsonRpc(failure: unknown): Readonly<{ code: number; message: string }>;
25
+ };
26
+
27
+ export = jsonRpcContracts;
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ ENTITIES_DEFAULT_LIMITS,
5
+ ENTITIES_DIAGNOSTIC_CODES,
6
+ ENTITIES_FAILURE_VERSION,
7
+ ENTITIES_JSON_RPC_ADAPTER_VERSION,
8
+ ENTITIES_JSON_RPC_OPTIONS,
9
+ entitiesContractError,
10
+ normalizeJsonRpcAdapterOptions,
11
+ createJsonRpcAdapter: createRuntimeJsonRpcAdapter
12
+ } = require('./runtime.js');
13
+
14
+ const ENTITIES_JSON_RPC_ADAPTER_ID = 'json-rpc';
15
+ const ENTITIES_JSON_RPC_PROTOCOL = '2.0';
16
+ const ENTITIES_JSON_RPC_ERROR_CODES = Object.freeze({
17
+ parse: -32700,
18
+ invalidRequest: -32600,
19
+ methodNotFound: -32601,
20
+ invalidParams: -32602,
21
+ internal: -32603
22
+ });
23
+ const ENTITIES_JSON_RPC_FAILURE_MAP = Object.freeze({
24
+ 'invalid-envelope': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.invalidRequest, message: 'Invalid Request' }),
25
+ 'unknown-entity': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.methodNotFound, message: 'Method not found' }),
26
+ 'invalid-input': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.invalidParams, message: 'Invalid params' }),
27
+ 'execution-failed': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.internal, message: 'Internal error' }),
28
+ 'invalid-output': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.internal, message: 'Internal error' }),
29
+ 'input-too-large': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.invalidRequest, message: 'Invalid Request' }),
30
+ 'output-too-large': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.internal, message: 'Internal error' }),
31
+ 'adapter-failed': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.internal, message: 'Internal error' }),
32
+ 'runtime-not-realized': Object.freeze({ code: ENTITIES_JSON_RPC_ERROR_CODES.internal, message: 'Internal error' })
33
+ });
34
+
35
+ function normalizeJsonRpcOptions(input = {}) {
36
+ return normalizeJsonRpcAdapterOptions(input);
37
+ }
38
+
39
+ function createJsonRpcAdapter(options = {}, limitsInput = ENTITIES_DEFAULT_LIMITS) {
40
+ return createRuntimeJsonRpcAdapter(options, limitsInput);
41
+ }
42
+
43
+ function normalizeJsonRpcId(value, present = true) {
44
+ if (present !== true) return Object.freeze({ kind: 'absent', value: undefined });
45
+ if (value === null) return Object.freeze({ kind: 'null', value: null });
46
+ if (typeof value === 'string') return Object.freeze({ kind: 'string', value });
47
+ if (typeof value === 'number' && Number.isSafeInteger(value)) return Object.freeze({ kind: 'number', value });
48
+ throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, 'JSON-RPC ID must be a string, safe integer, null, or absent.', { value });
49
+ }
50
+
51
+ function mapEntitiesFailureToJsonRpc(failure) {
52
+ if (!failure || failure.version !== ENTITIES_FAILURE_VERSION || !Object.prototype.hasOwnProperty.call(ENTITIES_JSON_RPC_FAILURE_MAP, failure.kind)) {
53
+ throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, 'JSON-RPC failure mapping requires a normalized Entities failure.');
54
+ }
55
+ return ENTITIES_JSON_RPC_FAILURE_MAP[failure.kind];
56
+ }
57
+
58
+ module.exports = Object.freeze({
59
+ ENTITIES_JSON_RPC_ADAPTER_VERSION,
60
+ ENTITIES_JSON_RPC_ADAPTER_ID,
61
+ ENTITIES_JSON_RPC_PROTOCOL,
62
+ ENTITIES_JSON_RPC_OPTIONS,
63
+ ENTITIES_JSON_RPC_ERROR_CODES,
64
+ ENTITIES_JSON_RPC_FAILURE_MAP,
65
+ normalizeJsonRpcOptions,
66
+ createJsonRpcAdapter,
67
+ normalizeJsonRpcId,
68
+ mapEntitiesFailureToJsonRpc
69
+ });
@@ -0,0 +1,67 @@
1
+ declare interface EntitiesRuntimeLimits {
2
+ readonly maxEnvelopeBytes: number;
3
+ readonly maxPayloadBytes: number;
4
+ readonly maxMethodBytes: number;
5
+ readonly maxEntities: number;
6
+ readonly maxMetadataBytesPerEntity: number;
7
+ readonly maxMetadataBytesPerRouter: number;
8
+ readonly maxMetadataDepth: number;
9
+ readonly maxMetadataEntries: number;
10
+ readonly maxJsonDepth: number;
11
+ readonly maxOutputBytes: number;
12
+ readonly maxErrorMessageBytes: number;
13
+ }
14
+
15
+ declare const runtime: {
16
+ readonly ENTITIES_ADAPTER_VERSION: 'pulse.entities-adapter.v1';
17
+ readonly ENTITIES_FAILURE_VERSION: 'pulse.entities-failure.v1';
18
+ readonly ENTITIES_JSON_RPC_ADAPTER_VERSION: 'pulse.entities-json-rpc-adapter.v1';
19
+ readonly ENTITIES_JSON_RPC_OPTIONS: Readonly<{ namedParamsOnly: true; acceptEmptyObjectForNoInput: false }>;
20
+ readonly ENTITIES_DEFAULT_LIMITS: EntitiesRuntimeLimits;
21
+ readonly ENTITIES_LIMIT_KEYS: readonly string[];
22
+ readonly ENTITIES_FAILURE_KINDS: readonly string[];
23
+ readonly ENTITIES_FAILURE_CODES: Readonly<Record<string, string>>;
24
+ readonly ENTITIES_DIAGNOSTIC_CODES: Readonly<Record<string, string>>;
25
+ entitiesContractError(code: string, message: string, detail?: Readonly<Record<string, unknown>>): TypeError & {
26
+ readonly code: string;
27
+ readonly detail: Readonly<Record<string, unknown>>;
28
+ };
29
+ utf8ByteLength(value: unknown): number;
30
+ compareText(left: string, right: string): number;
31
+ normalizeEntityLimits(input?: Readonly<Partial<EntitiesRuntimeLimits>>): EntitiesRuntimeLimits;
32
+ normalizeDiscriminator(value: unknown, limits?: EntitiesRuntimeLimits): string;
33
+ normalizeSchemaId(value: unknown, field?: string): string | null;
34
+ normalizeStaticMetadata(value: unknown, limits?: EntitiesRuntimeLimits): Readonly<Record<string, unknown>> | undefined;
35
+ normalizeEntityDeclaration(input: unknown, limits?: EntitiesRuntimeLimits): Readonly<{
36
+ input: string | null;
37
+ output: string | null;
38
+ metadata?: Readonly<Record<string, unknown>>;
39
+ }>;
40
+ normalizeHandler<T extends Function>(handler: T): T;
41
+ normalizeJsonRpcAdapterOptions(input?: Readonly<{ namedParamsOnly?: true; acceptEmptyObjectForNoInput?: boolean }>): Readonly<{
42
+ namedParamsOnly: true;
43
+ acceptEmptyObjectForNoInput: boolean;
44
+ }>;
45
+ normalizeAdapter(input: unknown, limits?: EntitiesRuntimeLimits): Readonly<{
46
+ version: string;
47
+ id: 'json-rpc';
48
+ adapterVersion: string;
49
+ options: Readonly<Record<string, unknown>>;
50
+ limits: EntitiesRuntimeLimits;
51
+ }>;
52
+ createJsonRpcAdapter(input?: Readonly<{ namedParamsOnly?: true; acceptEmptyObjectForNoInput?: boolean }>, limits?: EntitiesRuntimeLimits): Readonly<{
53
+ version: string;
54
+ id: 'json-rpc';
55
+ adapterVersion: string;
56
+ options: Readonly<{ namedParamsOnly: true; acceptEmptyObjectForNoInput: boolean }>;
57
+ limits: EntitiesRuntimeLimits;
58
+ }>;
59
+ normalizeEntityRegistration(input: unknown, limits?: EntitiesRuntimeLimits): Readonly<{
60
+ discriminator: string;
61
+ declaration: Readonly<{ input: string | null; output: string | null; metadata?: Readonly<Record<string, unknown>> }>;
62
+ handler: Function;
63
+ }>;
64
+ normalizeEntityFailure(input: unknown, limits?: EntitiesRuntimeLimits): Readonly<Record<string, unknown>>;
65
+ };
66
+
67
+ export = runtime;
@@ -0,0 +1,288 @@
1
+ 'use strict';
2
+
3
+ const ENTITIES_ADAPTER_VERSION = 'pulse.entities-adapter.v1';
4
+ const ENTITIES_FAILURE_VERSION = 'pulse.entities-failure.v1';
5
+ const ENTITIES_JSON_RPC_ADAPTER_VERSION = 'pulse.entities-json-rpc-adapter.v1';
6
+ const ENTITIES_JSON_RPC_OPTIONS = Object.freeze({
7
+ namedParamsOnly: true,
8
+ acceptEmptyObjectForNoInput: false
9
+ });
10
+ const ENTITIES_DEFAULT_LIMITS = Object.freeze({
11
+ maxEnvelopeBytes: 65_536,
12
+ maxPayloadBytes: 32_768,
13
+ maxMethodBytes: 256,
14
+ maxEntities: 256,
15
+ maxMetadataBytesPerEntity: 4_096,
16
+ maxMetadataBytesPerRouter: 65_536,
17
+ maxMetadataDepth: 8,
18
+ maxMetadataEntries: 128,
19
+ maxJsonDepth: 32,
20
+ maxOutputBytes: 65_536,
21
+ maxErrorMessageBytes: 256
22
+ });
23
+ const ENTITIES_LIMIT_KEYS = Object.freeze(Object.keys(ENTITIES_DEFAULT_LIMITS));
24
+ const ENTITIES_FAILURE_KINDS = Object.freeze([
25
+ 'invalid-envelope',
26
+ 'unknown-entity',
27
+ 'invalid-input',
28
+ 'execution-failed',
29
+ 'invalid-output',
30
+ 'input-too-large',
31
+ 'output-too-large',
32
+ 'adapter-failed',
33
+ 'runtime-not-realized'
34
+ ]);
35
+ const ENTITIES_FAILURE_CODES = Object.freeze({
36
+ 'invalid-envelope': 'PULSE_ENTITIES_INVALID_ENVELOPE',
37
+ 'unknown-entity': 'PULSE_ENTITIES_UNKNOWN_ENTITY',
38
+ 'invalid-input': 'PULSE_ENTITIES_INPUT_INVALID',
39
+ 'execution-failed': 'PULSE_ENTITIES_EXECUTION_FAILED',
40
+ 'invalid-output': 'PULSE_ENTITIES_OUTPUT_INVALID',
41
+ 'input-too-large': 'PULSE_ENTITIES_INPUT_TOO_LARGE',
42
+ 'output-too-large': 'PULSE_ENTITIES_OUTPUT_TOO_LARGE',
43
+ 'adapter-failed': 'PULSE_ENTITIES_ADAPTER_FAILED',
44
+ 'runtime-not-realized': 'PULSE_ENTITIES_RUNTIME_NOT_REALIZED'
45
+ });
46
+ const ENTITIES_DIAGNOSTIC_CODES = Object.freeze({
47
+ ADAPTER_STATIC_REQUIRED: 'PULSE_ENTITIES_ADAPTER_STATIC_REQUIRED',
48
+ ADAPTER_UNSUPPORTED: 'PULSE_ENTITIES_ADAPTER_UNSUPPORTED',
49
+ ADAPTER_OPTIONS_INVALID: 'PULSE_ENTITIES_ADAPTER_OPTIONS_INVALID',
50
+ DISCRIMINATOR_STATIC_REQUIRED: 'PULSE_ENTITIES_DISCRIMINATOR_STATIC_REQUIRED',
51
+ DISCRIMINATOR_INVALID: 'PULSE_ENTITIES_DISCRIMINATOR_INVALID',
52
+ DISCRIMINATOR_DUPLICATE: 'PULSE_ENTITIES_DISCRIMINATOR_DUPLICATE',
53
+ SCHEMA_MISSING: 'PULSE_ENTITIES_SCHEMA_MISSING',
54
+ SCHEMA_ID_INVALID: 'PULSE_ENTITIES_SCHEMA_ID_INVALID',
55
+ DECLARATION_INVALID: 'PULSE_ENTITIES_DECLARATION_INVALID',
56
+ HANDLER_UNRESOLVED: 'PULSE_ENTITIES_HANDLER_UNRESOLVED',
57
+ HANDLER_INVALID: 'PULSE_ENTITIES_HANDLER_INVALID',
58
+ METADATA_INVALID: 'PULSE_ENTITIES_METADATA_INVALID',
59
+ LIMIT_INVALID: 'PULSE_ENTITIES_LIMIT_INVALID',
60
+ LIMIT_EXCEEDED: 'PULSE_ENTITIES_LIMIT_EXCEEDED',
61
+ REGISTRATION_UNSUPPORTED: 'PULSE_ENTITIES_REGISTRATION_UNSUPPORTED',
62
+ BINDING_UNSUPPORTED: 'PULSE_ENTITIES_BINDING_UNSUPPORTED',
63
+ BODY_CONSUMER_CONFLICT: 'PULSE_ENTITIES_BODY_CONSUMER_CONFLICT',
64
+ TARGET_INELIGIBLE: 'PULSE_ENTITIES_TARGET_INELIGIBLE'
65
+ });
66
+ const SCHEMA_ID_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*(?:\.[A-Za-z][A-Za-z0-9_-]*)+$/;
67
+
68
+ function entitiesContractError(code, message, detail = {}) {
69
+ const error = new TypeError(message);
70
+ error.name = 'EntitiesContractError';
71
+ error.code = code;
72
+ error.detail = Object.freeze({ ...detail });
73
+ return error;
74
+ }
75
+
76
+ function plainObject(value) {
77
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
78
+ const prototype = Object.getPrototypeOf(value);
79
+ return prototype === Object.prototype || prototype === null;
80
+ }
81
+
82
+ function assertDataObject(value, field, code = ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID) {
83
+ if (!plainObject(value)) throw entitiesContractError(code, `${field} must be a plain object.`, { field });
84
+ if (Object.getOwnPropertySymbols(value).length > 0) throw entitiesContractError(code, `${field} must not contain symbol keys.`, { field });
85
+ for (const key of Object.keys(value)) {
86
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
87
+ if (!descriptor || !Object.prototype.hasOwnProperty.call(descriptor, 'value')) {
88
+ throw entitiesContractError(code, `${field}.${key} must be an own data property.`, { field, key });
89
+ }
90
+ }
91
+ return value;
92
+ }
93
+
94
+ function assertKnownKeys(value, allowed, field, code = ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID) {
95
+ const unknown = Object.keys(value).filter((key) => !allowed.includes(key)).sort();
96
+ if (unknown.length > 0) throw entitiesContractError(code, `${field} contains unsupported fields: ${unknown.join(', ')}.`, { field, unknown });
97
+ }
98
+
99
+ function utf8ByteLength(value) {
100
+ const text = String(value);
101
+ let bytes = 0;
102
+ for (let index = 0; index < text.length; index += 1) {
103
+ const point = text.codePointAt(index);
104
+ if (point <= 0x7f) bytes += 1;
105
+ else if (point <= 0x7ff) bytes += 2;
106
+ else if (point <= 0xffff) bytes += 3;
107
+ else {
108
+ bytes += 4;
109
+ index += 1;
110
+ }
111
+ }
112
+ return bytes;
113
+ }
114
+
115
+ function deepFreeze(value) {
116
+ if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value;
117
+ for (const child of Object.values(value)) deepFreeze(child);
118
+ return Object.freeze(value);
119
+ }
120
+
121
+ function compareText(left, right) {
122
+ return left < right ? -1 : left > right ? 1 : 0;
123
+ }
124
+
125
+ function normalizeEntityLimits(input = {}) {
126
+ assertDataObject(input, 'limits', ENTITIES_DIAGNOSTIC_CODES.LIMIT_INVALID);
127
+ assertKnownKeys(input, ENTITIES_LIMIT_KEYS, 'limits', ENTITIES_DIAGNOSTIC_CODES.LIMIT_INVALID);
128
+ const output = {};
129
+ for (const name of ENTITIES_LIMIT_KEYS) {
130
+ const value = input[name] === undefined ? ENTITIES_DEFAULT_LIMITS[name] : Number(input[name]);
131
+ if (!Number.isSafeInteger(value) || value <= 0) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.LIMIT_INVALID, `limits.${name} must be a positive safe integer.`, { name, value });
132
+ output[name] = value;
133
+ }
134
+ if (output.maxPayloadBytes > output.maxEnvelopeBytes) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.LIMIT_INVALID, 'maxPayloadBytes cannot exceed maxEnvelopeBytes.');
135
+ if (output.maxMetadataBytesPerEntity > output.maxMetadataBytesPerRouter) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.LIMIT_INVALID, 'Per-entity metadata bytes cannot exceed the router metadata limit.');
136
+ return Object.freeze(output);
137
+ }
138
+
139
+ function normalizeDiscriminator(value, limitsInput = ENTITIES_DEFAULT_LIMITS) {
140
+ const limits = limitsInput === ENTITIES_DEFAULT_LIMITS ? limitsInput : normalizeEntityLimits(limitsInput);
141
+ if (typeof value !== 'string' || value.trim() === '') throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.DISCRIMINATOR_INVALID, 'Entity discriminator must be a non-empty string.', { value });
142
+ const bytes = utf8ByteLength(value);
143
+ if (bytes > limits.maxMethodBytes) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.DISCRIMINATOR_INVALID, 'Entity discriminator exceeds its UTF-8 byte limit.', { bytes, maxBytes: limits.maxMethodBytes });
144
+ return value;
145
+ }
146
+
147
+ function normalizeSchemaId(value, field = 'schemaId') {
148
+ if (value === null) return null;
149
+ if (typeof value !== 'string' || !SCHEMA_ID_PATTERN.test(value)) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.SCHEMA_ID_INVALID, `${field} must be a dotted schema ID or null.`, { field, value });
150
+ return value;
151
+ }
152
+
153
+ function normalizeStaticMetadata(input, limitsInput = ENTITIES_DEFAULT_LIMITS) {
154
+ if (input === undefined) return undefined;
155
+ const limits = limitsInput === ENTITIES_DEFAULT_LIMITS ? limitsInput : normalizeEntityLimits(limitsInput);
156
+ let entries = 0;
157
+ const ancestors = new Set();
158
+ function visit(value, field, depth) {
159
+ if (depth > limits.maxMetadataDepth) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.METADATA_INVALID, 'Entity metadata exceeds its nesting limit.', { field, depth, maxDepth: limits.maxMetadataDepth });
160
+ if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;
161
+ if (typeof value === 'number') {
162
+ if (!Number.isFinite(value)) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.METADATA_INVALID, `${field} must be finite.`, { field });
163
+ return value;
164
+ }
165
+ if (typeof value !== 'object') throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.METADATA_INVALID, `${field} must be static JSON.`, { field, kind: typeof value });
166
+ if (ancestors.has(value)) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.METADATA_INVALID, 'Entity metadata must not contain cycles.', { field });
167
+ ancestors.add(value);
168
+ let output;
169
+ if (Array.isArray(value)) {
170
+ entries += value.length;
171
+ output = value.map((entry, index) => visit(entry, `${field}[${index}]`, depth + 1));
172
+ } else {
173
+ assertDataObject(value, field, ENTITIES_DIAGNOSTIC_CODES.METADATA_INVALID);
174
+ const keys = Object.keys(value).sort();
175
+ entries += keys.length;
176
+ output = Object.fromEntries(keys.map((key) => [key, visit(value[key], `${field}.${key}`, depth + 1)]));
177
+ }
178
+ ancestors.delete(value);
179
+ if (entries > limits.maxMetadataEntries) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.METADATA_INVALID, 'Entity metadata exceeds its entry limit.', { entries, maxEntries: limits.maxMetadataEntries });
180
+ return output;
181
+ }
182
+ if (!plainObject(input)) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.METADATA_INVALID, 'Entity metadata root must be a plain object.');
183
+ const normalized = deepFreeze(visit(input, 'metadata', 0));
184
+ const bytes = utf8ByteLength(JSON.stringify(normalized));
185
+ if (bytes > limits.maxMetadataBytesPerEntity) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.METADATA_INVALID, 'Entity metadata exceeds its byte limit.', { bytes, maxBytes: limits.maxMetadataBytesPerEntity });
186
+ return normalized;
187
+ }
188
+
189
+ function normalizeEntityDeclaration(input, limitsInput = ENTITIES_DEFAULT_LIMITS) {
190
+ const limits = limitsInput === ENTITIES_DEFAULT_LIMITS ? limitsInput : normalizeEntityLimits(limitsInput);
191
+ assertDataObject(input, 'declaration');
192
+ assertKnownKeys(input, ['input', 'output', 'metadata'], 'declaration');
193
+ if (!Object.prototype.hasOwnProperty.call(input, 'input') || !Object.prototype.hasOwnProperty.call(input, 'output')) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, 'Entity declaration requires explicit input and output fields.');
194
+ return Object.freeze({
195
+ input: normalizeSchemaId(input.input, 'declaration.input'),
196
+ output: normalizeSchemaId(input.output, 'declaration.output'),
197
+ ...(input.metadata === undefined ? {} : { metadata: normalizeStaticMetadata(input.metadata, limits) })
198
+ });
199
+ }
200
+
201
+ function normalizeHandler(handler) {
202
+ if (typeof handler !== 'function' || typeof handler.name !== 'string' || handler.name.trim() === '') throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.HANDLER_INVALID, 'Entity handler must be a named function reference.');
203
+ return handler;
204
+ }
205
+
206
+ function normalizeJsonRpcAdapterOptions(input = {}) {
207
+ assertDataObject(input, 'adapter.options', ENTITIES_DIAGNOSTIC_CODES.ADAPTER_OPTIONS_INVALID);
208
+ assertKnownKeys(input, Object.keys(ENTITIES_JSON_RPC_OPTIONS), 'adapter.options', ENTITIES_DIAGNOSTIC_CODES.ADAPTER_OPTIONS_INVALID);
209
+ const namedParamsOnly = input.namedParamsOnly === undefined ? true : input.namedParamsOnly;
210
+ const acceptEmptyObjectForNoInput = input.acceptEmptyObjectForNoInput === undefined ? false : input.acceptEmptyObjectForNoInput;
211
+ if (namedParamsOnly !== true) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.ADAPTER_OPTIONS_INVALID, 'jsonRpc namedParamsOnly must remain true in the first contract.');
212
+ if (typeof acceptEmptyObjectForNoInput !== 'boolean') throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.ADAPTER_OPTIONS_INVALID, 'jsonRpc acceptEmptyObjectForNoInput must be boolean.');
213
+ return Object.freeze({ namedParamsOnly: true, acceptEmptyObjectForNoInput });
214
+ }
215
+
216
+ function normalizeAdapter(input, limitsInput = ENTITIES_DEFAULT_LIMITS) {
217
+ const limits = limitsInput === ENTITIES_DEFAULT_LIMITS ? limitsInput : normalizeEntityLimits(limitsInput);
218
+ assertDataObject(input, 'adapter', ENTITIES_DIAGNOSTIC_CODES.ADAPTER_STATIC_REQUIRED);
219
+ assertKnownKeys(input, ['version', 'id', 'adapterVersion', 'options', 'limits'], 'adapter', ENTITIES_DIAGNOSTIC_CODES.ADAPTER_OPTIONS_INVALID);
220
+ if (input.version !== ENTITIES_ADAPTER_VERSION || input.id !== 'json-rpc' || input.adapterVersion !== ENTITIES_JSON_RPC_ADAPTER_VERSION) {
221
+ throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.ADAPTER_UNSUPPORTED, 'Only the first-party json-rpc adapter is supported.', { version: input.version, id: input.id, adapterVersion: input.adapterVersion });
222
+ }
223
+ return deepFreeze({
224
+ version: ENTITIES_ADAPTER_VERSION,
225
+ id: 'json-rpc',
226
+ adapterVersion: ENTITIES_JSON_RPC_ADAPTER_VERSION,
227
+ options: normalizeJsonRpcAdapterOptions(input.options),
228
+ limits: input.limits === undefined ? limits : normalizeEntityLimits(input.limits)
229
+ });
230
+ }
231
+
232
+ function createJsonRpcAdapter(options = {}, limitsInput = ENTITIES_DEFAULT_LIMITS) {
233
+ return Object.freeze({
234
+ version: ENTITIES_ADAPTER_VERSION,
235
+ id: 'json-rpc',
236
+ adapterVersion: ENTITIES_JSON_RPC_ADAPTER_VERSION,
237
+ options: normalizeJsonRpcAdapterOptions(options),
238
+ limits: limitsInput === ENTITIES_DEFAULT_LIMITS ? ENTITIES_DEFAULT_LIMITS : normalizeEntityLimits(limitsInput)
239
+ });
240
+ }
241
+
242
+ function normalizeEntityRegistration(input, limitsInput = ENTITIES_DEFAULT_LIMITS) {
243
+ const limits = limitsInput === ENTITIES_DEFAULT_LIMITS ? limitsInput : normalizeEntityLimits(limitsInput);
244
+ assertDataObject(input, 'registration');
245
+ assertKnownKeys(input, ['discriminator', 'declaration', 'handler'], 'registration');
246
+ return Object.freeze({
247
+ discriminator: normalizeDiscriminator(input.discriminator, limits),
248
+ declaration: normalizeEntityDeclaration(input.declaration, limits),
249
+ handler: normalizeHandler(input.handler)
250
+ });
251
+ }
252
+
253
+ function normalizeEntityFailure(input, limitsInput = ENTITIES_DEFAULT_LIMITS) {
254
+ const limits = limitsInput === ENTITIES_DEFAULT_LIMITS ? limitsInput : normalizeEntityLimits(limitsInput);
255
+ assertDataObject(input, 'failure');
256
+ assertKnownKeys(input, ['version', 'kind', 'message'], 'failure');
257
+ const kind = String(input.kind || '');
258
+ if (!ENTITIES_FAILURE_KINDS.includes(kind)) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.DECLARATION_INVALID, `Unsupported Entities failure kind ${kind}.`, { kind });
259
+ const message = String(input.message || 'Entity operation failed.');
260
+ if (utf8ByteLength(message) > limits.maxErrorMessageBytes) throw entitiesContractError(ENTITIES_DIAGNOSTIC_CODES.LIMIT_EXCEEDED, 'Entities failure message exceeds its byte limit.');
261
+ return Object.freeze({ version: ENTITIES_FAILURE_VERSION, kind, code: ENTITIES_FAILURE_CODES[kind], message });
262
+ }
263
+
264
+ module.exports = Object.freeze({
265
+ ENTITIES_ADAPTER_VERSION,
266
+ ENTITIES_FAILURE_VERSION,
267
+ ENTITIES_JSON_RPC_ADAPTER_VERSION,
268
+ ENTITIES_JSON_RPC_OPTIONS,
269
+ ENTITIES_DEFAULT_LIMITS,
270
+ ENTITIES_LIMIT_KEYS,
271
+ ENTITIES_FAILURE_KINDS,
272
+ ENTITIES_FAILURE_CODES,
273
+ ENTITIES_DIAGNOSTIC_CODES,
274
+ entitiesContractError,
275
+ utf8ByteLength,
276
+ compareText,
277
+ normalizeEntityLimits,
278
+ normalizeDiscriminator,
279
+ normalizeSchemaId,
280
+ normalizeStaticMetadata,
281
+ normalizeEntityDeclaration,
282
+ normalizeHandler,
283
+ normalizeJsonRpcAdapterOptions,
284
+ normalizeAdapter,
285
+ createJsonRpcAdapter,
286
+ normalizeEntityRegistration,
287
+ normalizeEntityFailure
288
+ });