cultnet-ts: drop unset optional keys from createDocumentPutMessage #13
2 changed files with 24 additions and 4 deletions
|
|
@ -127,10 +127,11 @@ export class CultNetDocumentRegistry {
|
|||
recordKey: documentKey,
|
||||
storedAt: options.storedAt ?? new Date().toISOString(),
|
||||
payload: parsed,
|
||||
sourceRuntimeId: options.sourceRuntimeId,
|
||||
sourceAgentId: options.sourceAgentId,
|
||||
sourceRole: options.sourceRole,
|
||||
tags: options.tags,
|
||||
// Absent optional fields must be omitted, not set to undefined: MessagePack encodes undefined as nil and the peer rejects it.
|
||||
...(options.sourceRuntimeId !== undefined && { sourceRuntimeId: options.sourceRuntimeId }),
|
||||
...(options.sourceAgentId !== undefined && { sourceAgentId: options.sourceAgentId }),
|
||||
...(options.sourceRole !== undefined && { sourceRole: options.sourceRole }),
|
||||
...(options.tags !== undefined && { tags: options.tags }),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3059,3 +3059,22 @@ test("RUDP operation service admits a restarted client on the same address", asy
|
|||
await server.close();
|
||||
}
|
||||
});
|
||||
|
||||
// MessagePack encodes undefined as nil, and a peer rejects a document whose optional source fields are nil.
|
||||
test("document put message omits unset optional keys so the encoded wire has no nil", () => {
|
||||
const definition = defineDocumentType({ type: "putnil.doc", schema: z.object({ body: z.string() }) });
|
||||
const binding = defineCultNetDocumentBinding({ definition });
|
||||
const registry = new CultNetDocumentRegistry([binding]);
|
||||
|
||||
const bare = registry.createDocumentPutMessage(binding, "m", "k", { body: "x" });
|
||||
assert.deepEqual(Object.keys(bare.document).sort(), ["payload", "recordKey", "schemaId", "storedAt"]);
|
||||
const decodedBare = decodeMsgpack(encode(bare)) as { document: Record<string, unknown> };
|
||||
assert.ok(Object.values(decodedBare.document).every(value => value !== null), "no nil values on the wire");
|
||||
assert.ok(!("sourceRuntimeId" in decodedBare.document));
|
||||
|
||||
const stamped = registry.createDocumentPutMessage(binding, "m", "k", { body: "x" },
|
||||
{ sourceRuntimeId: "r", sourceAgentId: "a", sourceRole: "role", tags: ["t"] });
|
||||
assert.deepEqual(decodeMsgpack(encode(stamped)), stamped);
|
||||
assert.equal(stamped.document.sourceRuntimeId, "r");
|
||||
assert.deepEqual(stamped.document.tags, ["t"]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue