Add CultNet operation service envelopes
This commit is contained in:
parent
bf9629000a
commit
2272aeff08
4 changed files with 106 additions and 2 deletions
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://github.com/GameCult/cultnet-ts/contracts/cultnet.operation-request.schema.json",
|
||||
"title": "CultNet Operation Request",
|
||||
"type": "object",
|
||||
"required": ["schemaVersion", "messageId", "serviceId", "operation", "payloadSchema", "payload"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"schemaVersion": { "const": "cultnet.operation_request.v0" },
|
||||
"messageId": { "type": "string", "minLength": 1 },
|
||||
"serviceId": { "type": "string", "minLength": 1 },
|
||||
"operation": { "type": "string", "minLength": 1 },
|
||||
"payloadSchema": { "type": "string", "minLength": 1 },
|
||||
"payloadEncoding": { "const": "messagepack-base64" },
|
||||
"payload": { "type": "string", "minLength": 1, "contentEncoding": "base64" },
|
||||
"sourceRuntimeId": { "type": "string", "minLength": 1 },
|
||||
"targetRuntimeId": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://github.com/GameCult/cultnet-ts/contracts/cultnet.operation-response.schema.json",
|
||||
"title": "CultNet Operation Response",
|
||||
"type": "object",
|
||||
"required": ["schemaVersion", "messageId", "serviceId", "operation", "status", "payloadSchema", "payload"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"schemaVersion": { "const": "cultnet.operation_response.v0" },
|
||||
"messageId": { "type": "string", "minLength": 1 },
|
||||
"serviceId": { "type": "string", "minLength": 1 },
|
||||
"operation": { "type": "string", "minLength": 1 },
|
||||
"status": { "type": "string", "minLength": 1 },
|
||||
"payloadSchema": { "type": "string", "minLength": 1 },
|
||||
"payloadEncoding": { "const": "messagepack-base64" },
|
||||
"payload": { "type": "string", "minLength": 1, "contentEncoding": "base64" },
|
||||
"diagnostics": { "type": "array", "items": { "type": "string" } },
|
||||
"sourceRuntimeId": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,8 @@ import schemaCatalogRequestSchema from "../contracts/cultnet.schema-catalog-requ
|
|||
import schemaCatalogResponseSchema from "../contracts/cultnet.schema-catalog-response.schema.json";
|
||||
import shardCatalogRequestSchema from "../contracts/cultnet.shard-catalog-request.schema.json";
|
||||
import shardCatalogResponseSchema from "../contracts/cultnet.shard-catalog-response.schema.json";
|
||||
import operationRequestSchema from "../contracts/cultnet.operation-request.schema.json";
|
||||
import operationResponseSchema from "../contracts/cultnet.operation-response.schema.json";
|
||||
import ghostlightAgentStateSchema from "../contracts/ghostlight.agent-state.schema.json";
|
||||
|
||||
export type CultNetWireContract = "cultnet.schema.v0" | "gamecult.networking.v0";
|
||||
|
|
@ -45,7 +47,9 @@ export type CultNetSchemaVersion =
|
|||
| "cultnet.schema_catalog_request.v0"
|
||||
| "cultnet.schema_catalog_response.v0"
|
||||
| "cultnet.shard_catalog_request.v0"
|
||||
| "cultnet.shard_catalog_response.v0";
|
||||
| "cultnet.shard_catalog_response.v0"
|
||||
| "cultnet.operation_request.v0"
|
||||
| "cultnet.operation_response.v0";
|
||||
|
||||
export type CultNetSchemaKind = "wire_message" | "document_payload" | "shared_contract";
|
||||
export type CultNetRawPayloadEncoding = "messagepack";
|
||||
|
|
@ -265,6 +269,31 @@ export interface CultNetShardCatalogResponseMessage {
|
|||
shards: CultNetShardDescriptor[];
|
||||
}
|
||||
|
||||
export interface CultNetOperationRequestMessage {
|
||||
schemaVersion: "cultnet.operation_request.v0";
|
||||
messageId: string;
|
||||
serviceId: string;
|
||||
operation: string;
|
||||
payloadSchema: string;
|
||||
payloadEncoding?: "messagepack-base64";
|
||||
payload: string;
|
||||
sourceRuntimeId?: string;
|
||||
targetRuntimeId?: string;
|
||||
}
|
||||
|
||||
export interface CultNetOperationResponseMessage {
|
||||
schemaVersion: "cultnet.operation_response.v0";
|
||||
messageId: string;
|
||||
serviceId: string;
|
||||
operation: string;
|
||||
status: string;
|
||||
payloadSchema: string;
|
||||
payloadEncoding?: "messagepack-base64";
|
||||
payload: string;
|
||||
diagnostics?: string[];
|
||||
sourceRuntimeId?: string;
|
||||
}
|
||||
|
||||
export interface GhostlightPressure {
|
||||
pressure_id: string;
|
||||
label: string;
|
||||
|
|
@ -509,7 +538,9 @@ export type CultNetMessage =
|
|||
| CultNetSchemaCatalogRequestMessage
|
||||
| CultNetSchemaCatalogResponseMessage
|
||||
| CultNetShardCatalogRequestMessage
|
||||
| CultNetShardCatalogResponseMessage;
|
||||
| CultNetShardCatalogResponseMessage
|
||||
| CultNetOperationRequestMessage
|
||||
| CultNetOperationResponseMessage;
|
||||
|
||||
const ajv = new Ajv2020({
|
||||
allErrors: true,
|
||||
|
|
@ -535,6 +566,8 @@ const CULTNET_MESSAGE_SCHEMAS = [
|
|||
schemaCatalogResponseSchema,
|
||||
shardCatalogRequestSchema,
|
||||
shardCatalogResponseSchema,
|
||||
operationRequestSchema,
|
||||
operationResponseSchema,
|
||||
] as const;
|
||||
|
||||
const cultNetValidators = new Map<CultNetSchemaVersion, ValidateFunction>();
|
||||
|
|
@ -1064,5 +1097,7 @@ export const cultNetSchemas = {
|
|||
schemaCatalogResponseSchema,
|
||||
shardCatalogRequestSchema,
|
||||
shardCatalogResponseSchema,
|
||||
operationRequestSchema,
|
||||
operationResponseSchema,
|
||||
ghostlightAgentStateSchema,
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -1221,6 +1221,36 @@ test("CultNet raw replication preserves CultCache payload bytes for bit-compatib
|
|||
}
|
||||
});
|
||||
|
||||
test("operation envelopes preserve typed service routing and payload correlation", () => {
|
||||
const request = parseCultNetMessage({
|
||||
schemaVersion: "cultnet.operation_request.v0",
|
||||
messageId: "plugin-42",
|
||||
serviceId: "sai.vn",
|
||||
operation: "project",
|
||||
payloadSchema: "gamecult.eve.plugin_abi.request.v1",
|
||||
payloadEncoding: "messagepack-base64",
|
||||
payload: "gaZzY2hlbWHEJ2dhbWVjdWx0LmV2ZS5wbHVnaW5fYWJpLnJlcXVlc3QudjE=",
|
||||
sourceRuntimeId: "eve-unity",
|
||||
});
|
||||
assert.equal(request.schemaVersion, "cultnet.operation_request.v0");
|
||||
assert.equal(request.messageId, "plugin-42");
|
||||
assert.equal(request.serviceId, "sai.vn");
|
||||
|
||||
const response = parseCultNetMessage({
|
||||
schemaVersion: "cultnet.operation_response.v0",
|
||||
messageId: "plugin-42",
|
||||
serviceId: "sai.vn",
|
||||
operation: "project",
|
||||
status: "ok",
|
||||
payloadSchema: "gamecult.eve.plugin_abi.response.v1",
|
||||
payloadEncoding: "messagepack-base64",
|
||||
payload: "gaZzdGF0dXOkb2s=",
|
||||
diagnostics: [],
|
||||
});
|
||||
assert.equal(response.schemaVersion, "cultnet.operation_response.v0");
|
||||
assert.equal(response.messageId, request.messageId);
|
||||
});
|
||||
|
||||
test("rudp sequence-neutral acknowledgements interoperate with ordered receivers", () => {
|
||||
const sender = new CultNetRudpSession({ connectionId: 125, initialSequence: 1 });
|
||||
const receiver = new CultNetRudpSession({ connectionId: 125, initialSequence: 100 });
|
||||
|
|
|
|||
Loading…
Reference in a new issue