Resolve TS snapshot filters by schema alias
This commit is contained in:
parent
bff2e552c8
commit
2738f4c2db
2 changed files with 85 additions and 2 deletions
|
|
@ -159,7 +159,7 @@ export class CultNetDocumentRegistry {
|
|||
const binding = this.#requireBinding(envelope.type);
|
||||
const schemaId = schemaIdForEnvelope(envelope, binding);
|
||||
|
||||
if (requestedSchemaIds && !requestedSchemaIds.has(schemaId)) {
|
||||
if (requestedSchemaIds && !schemaMatchesBinding(schemaId, binding, requestedSchemaIds)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +196,7 @@ export class CultNetDocumentRegistry {
|
|||
const binding = this.#requireBinding(envelope.type);
|
||||
const schemaId = schemaIdForEnvelope(envelope, binding);
|
||||
|
||||
if (requestedSchemaIds && !requestedSchemaIds.has(schemaId)) {
|
||||
if (requestedSchemaIds && !schemaMatchesBinding(schemaId, binding, requestedSchemaIds)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -340,6 +340,39 @@ function schemaIdForBinding(binding: CultNetDocumentBinding): string {
|
|||
return binding.definition.schemaId ?? binding.definition.type;
|
||||
}
|
||||
|
||||
function schemaMatchesBinding(
|
||||
schemaId: string,
|
||||
binding: CultNetDocumentBinding,
|
||||
requestedSchemaIds: Set<string>,
|
||||
): boolean {
|
||||
if (requestedSchemaIds.has(schemaId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const definition = binding.definition;
|
||||
if (definition.schemaId && requestedSchemaIds.has(definition.schemaId)) {
|
||||
return true;
|
||||
}
|
||||
if (definition.schemaName && requestedSchemaIds.has(definition.schemaName)) {
|
||||
return true;
|
||||
}
|
||||
if (definition.compatibleSchemaIds?.some(candidate => requestedSchemaIds.has(candidate))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Array.from(requestedSchemaIds)
|
||||
.some(candidate => inferSchemaName(candidate) === definition.schemaName);
|
||||
}
|
||||
|
||||
function inferSchemaName(schemaId: string): string | undefined {
|
||||
const marker = schemaId.lastIndexOf(".v");
|
||||
if (marker <= 0 || marker + 2 >= schemaId.length) {
|
||||
return undefined;
|
||||
}
|
||||
const version = schemaId.slice(marker + 2);
|
||||
return /^\d+$/u.test(version) ? schemaId.slice(0, marker) : undefined;
|
||||
}
|
||||
|
||||
function schemaIdForEnvelope(
|
||||
envelope: CultCacheEnvelope,
|
||||
binding: CultNetDocumentBinding,
|
||||
|
|
|
|||
|
|
@ -1266,6 +1266,56 @@ test("CultNet raw replication applies compatible foreign-schema snapshots", asyn
|
|||
}
|
||||
});
|
||||
|
||||
test("CultNet document registry filters snapshots by schema aliases", async () => {
|
||||
const tempDir = mkdtempSync(join(tmpdir(), "cultnetts-alias-snapshot-"));
|
||||
|
||||
try {
|
||||
const documentDefinition = defineDocumentType({
|
||||
type: "cultnet.alias_note",
|
||||
schemaId: "sha256:cultnet-alias-note",
|
||||
schemaName: "cultnet.alias_note",
|
||||
schemaVersion: "cultnet.alias_note.v1",
|
||||
schema: z.object({
|
||||
schema_version: z.string(),
|
||||
noteId: z.string(),
|
||||
body: z.string(),
|
||||
}),
|
||||
name: "noteId",
|
||||
});
|
||||
const registry = new CultNetDocumentRegistry([
|
||||
defineCultNetDocumentBinding({ definition: documentDefinition }),
|
||||
]);
|
||||
const cache = CultCache.builder()
|
||||
.withDocumentType(documentDefinition)
|
||||
.withGenericStore(new SingleFileMessagePackBackingStore(join(tempDir, "alias.msgpack")))
|
||||
.build();
|
||||
|
||||
await cache.put(documentDefinition, "note:alias", {
|
||||
schema_version: "cultnet.alias_note.v1",
|
||||
noteId: "note:alias",
|
||||
body: "filtered by alias",
|
||||
});
|
||||
|
||||
const typedSnapshot = registry.createSnapshotResponse(cache, "typed-alias", {
|
||||
schemaVersion: "cultnet.snapshot_request.v0",
|
||||
messageId: "typed-alias",
|
||||
schemaIds: ["cultnet.alias_note.v1"],
|
||||
});
|
||||
const rawSnapshot = registry.createRawSnapshotResponse(cache, "raw-alias", {
|
||||
schemaVersion: "cultnet.snapshot_request.v0",
|
||||
messageId: "raw-alias",
|
||||
schemaIds: ["cultnet.alias_note.v1"],
|
||||
});
|
||||
|
||||
assert.equal(typedSnapshot.documents[0]?.schemaId, "sha256:cultnet-alias-note");
|
||||
assert.equal(typedSnapshot.documents[0]?.recordKey, "note:alias");
|
||||
assert.equal(rawSnapshot.documents[0]?.schemaId, "sha256:cultnet-alias-note");
|
||||
assert.equal(rawSnapshot.documents[0]?.recordKey, "note:alias");
|
||||
} finally {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("CultNet interop slot compatibility defaults missing trailing fields and rejects mismatched slots", () => {
|
||||
const note: InteropNote = {
|
||||
schemaVersion: INTEROP_SCHEMA_VERSION,
|
||||
|
|
|
|||
Loading…
Reference in a new issue