Add TS CultMesh catalog factories
This commit is contained in:
parent
e65c0d0fc6
commit
da48d58df7
5 changed files with 126 additions and 2 deletions
|
|
@ -312,7 +312,11 @@ Current progress:
|
|||
ergonomics as the other runtimes: sorted local views, direct `get(...)`
|
||||
lookup, unsubscribe-able `watch(...)` callbacks for Verse and peer catalogs,
|
||||
watch callbacks for authority leases and stream declarations/frame cursors,
|
||||
plus lease listing and lookup beside the authority check.
|
||||
plus lease listing and lookup beside the authority check. The branded
|
||||
`CultMesh` facade also creates schema catalogs, built-in schema catalogs, and
|
||||
shard catalogs by delegating to the existing `cultnet-ts` owners, so callers
|
||||
do not have to leave the CultMesh entrypoint for schema discovery or shard
|
||||
topology.
|
||||
- TypeScript now also has a `CultNetSchemaCatalog` for remote schema
|
||||
descriptors plus `CultNetPeer` request/fetch/sync helpers for
|
||||
`cultnet.schema_catalog_request.v0` / `cultnet.schema_catalog_response.v0`.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ CultMesh.
|
|||
| --- | --- | --- | --- |
|
||||
| C# | Reference implementation and production game/server substrate | CultCache typed documents and SoA, CultNet schema-v0, LiteNetLib production path with adapter profile, shared transport profiles, shared RUDP socket transport, RUDP reconnect policy/controller and reconnect-loop helper, LiteNetLib client reconnect-controller adoption, schema-client transport port for service request/response clients, CultMesh node/session/catalog/stream/simulation surfaces | No need to abandon LiteNetLib before the CultNet adapter fully owns production service adoption |
|
||||
| Python | Package runtime, local daemon endpoint, raw interop peer, typed state participant | CultCache/CultNet/CultMesh package surface, schema catalogs, shard catalogs/logs, schema-transport factory for raw client request/subscription flows, local TCP CultMesh server, session/prediction/simulation fact helpers, authority leases, streams, RUDP codec/session/socket transport, RUDP reconnect policy/controller and reconnect-loop helper, schema-v0 MessagePack over RUDP evidence, benchmark evidence against C# cache paths | Universal C# throughput, full C# daemon/server stack, and RUDP as the only public service pipe |
|
||||
| TypeScript | Node/browser-adjacent projection and interop runtime | CultCache parity tests, CultNet schema-v0 peer, advertised schema/shard catalog wire contracts plus request/sync helpers, transport profiles, TCP-framed transport port and peer helper, shared RUDP socket transport, RUDP reconnect policy/controller, RUDP reconnect-loop helper, local CultMesh node/catalog/authority/stream ergonomics | Full C# game session/server stack |
|
||||
| TypeScript | Node/browser-adjacent projection and interop runtime | CultCache parity tests, CultNet schema-v0 peer, advertised schema/shard catalog wire contracts plus request/sync helpers, transport profiles, TCP-framed transport port and peer helper, shared RUDP socket transport, RUDP reconnect policy/controller, RUDP reconnect-loop helper, branded CultMesh node/schema/shard/Verse/peer/authority/stream ergonomics | Full C# game session/server stack |
|
||||
| Rust | Low-level cache/transport/runtime substrate | CultCache/CultNet interop lane, schema and shard catalog helpers, transport profiles, TCP-framed port, shared RUDP codec/session/socket transport, RUDP reconnect policy/controller and reconnect-loop helper, schema-v0 MessagePack over RUDP evidence, small CultMesh facade for peer cards, authority leases, RUDP endpoint parsing, and peer-card RUDP client construction | Full CultMesh game-session/server facade, stream catalog, or production game-session server |
|
||||
| Kotlin | JVM/Android client substrate | Typed MessagePack cache, built-in schema catalog advertisement, schema/shard catalogs with shared schema-message transport fetch/sync helpers, authority leases, stream catalog, branded `CultMesh` facade, WebSocket transport profile/connection helper, RUDP client/server sugar, RUDP reconnect policy/controller and reconnect-loop helper, schema-v0 MessagePack over RUDP evidence | C# SoA store, full C# server daemon, or Unity hot-loop memory layout |
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,29 @@ leases.upsert({
|
|||
expiresAt: new Date(Date.now() + 60_000),
|
||||
});
|
||||
stopWatchingLeases();
|
||||
|
||||
const schemas = CultMesh.createBuiltInSchemaCatalog();
|
||||
const shardCatalogRequest = schemas.get("cultnet.shard_catalog_request.v0");
|
||||
|
||||
const shards = CultMesh.createShardCatalog();
|
||||
shards.upsert({
|
||||
shardId: "notes-a",
|
||||
ownerRuntimeId: "ts-peer",
|
||||
epoch: 1,
|
||||
schemaIds: ["cultmesh.note.v0"],
|
||||
keyPrefix: "note:",
|
||||
});
|
||||
|
||||
const noteShards = shards.list({
|
||||
schemaIds: ["cultmesh.note.v0"],
|
||||
recordKeys: ["note:intro"],
|
||||
});
|
||||
```
|
||||
|
||||
Schema and shard catalog factories delegate to `cultnet-ts`; the branded
|
||||
`CultMesh` entrypoint does not create a second owner for schema discovery or
|
||||
topology truth.
|
||||
|
||||
## Streaming Mode
|
||||
|
||||
CultMesh streaming mode is for audio, video, tensor, and opaque byte frames that
|
||||
|
|
|
|||
|
|
@ -7,8 +7,12 @@ import {
|
|||
} from "cultcache-ts";
|
||||
import {
|
||||
CultNetDocumentRegistry,
|
||||
CultNetSchemaCatalog,
|
||||
CultNetShardCatalog,
|
||||
cultNetBuiltinSchemaRegistry,
|
||||
defineCultNetDocumentBinding,
|
||||
type CultNetDocumentBinding,
|
||||
type CultNetSchemaCatalogOptions,
|
||||
} from "cultnet-ts";
|
||||
|
||||
export interface CultMeshNodeOptions {
|
||||
|
|
@ -470,6 +474,28 @@ export class CultMesh {
|
|||
public static createStreamCatalog(): CultMeshStreamCatalog {
|
||||
return new CultMeshStreamCatalog();
|
||||
}
|
||||
|
||||
public static createSchemaCatalog(): CultNetSchemaCatalog {
|
||||
return new CultNetSchemaCatalog();
|
||||
}
|
||||
|
||||
public static createBuiltInSchemaCatalog(
|
||||
options: CultNetSchemaCatalogOptions = {},
|
||||
): CultNetSchemaCatalog {
|
||||
const catalog = new CultNetSchemaCatalog();
|
||||
catalog.applyResponse(cultNetBuiltinSchemaRegistry.createCatalogResponse({
|
||||
schemaVersion: "cultnet.schema_catalog_request.v0",
|
||||
messageId: "cultmesh-ts-builtins",
|
||||
includeSchemaJson: options.includeSchemaJson,
|
||||
schemaIds: options.schemaIds ? [...options.schemaIds] : undefined,
|
||||
kinds: options.kinds ? [...options.kinds] : undefined,
|
||||
}));
|
||||
return catalog;
|
||||
}
|
||||
|
||||
public static createShardCatalog(): CultNetShardCatalog {
|
||||
return new CultNetShardCatalog();
|
||||
}
|
||||
}
|
||||
|
||||
function requireNonEmpty(value: string, name: string): void {
|
||||
|
|
|
|||
|
|
@ -115,6 +115,79 @@ test("CultMesh TS local Verse catalog exposes sorted views and watch ergonomics"
|
|||
);
|
||||
});
|
||||
|
||||
test("CultMesh TS branded facade exposes schema and shard catalogs", () => {
|
||||
const schemaCatalog = CultMesh.createSchemaCatalog();
|
||||
const schemaUpdates: string[] = [];
|
||||
const unsubscribeSchema = schemaCatalog.watch((descriptor) => {
|
||||
schemaUpdates.push(descriptor.schemaId);
|
||||
});
|
||||
schemaCatalog.upsert({
|
||||
schemaId: "cultmesh.ts.note.v1",
|
||||
kind: "document_payload",
|
||||
documentType: "cultmesh.ts-note",
|
||||
wireContracts: ["cultnet.schema.v0"],
|
||||
contentHash: "note-hash",
|
||||
});
|
||||
unsubscribeSchema();
|
||||
schemaCatalog.upsert({
|
||||
schemaId: "cultmesh.ts.other.v1",
|
||||
kind: "document_payload",
|
||||
documentType: "cultmesh.ts-other",
|
||||
wireContracts: ["cultnet.schema.v0"],
|
||||
contentHash: "other-hash",
|
||||
});
|
||||
|
||||
assert.deepEqual(schemaUpdates, ["cultmesh.ts.note.v1"]);
|
||||
assert.equal(
|
||||
schemaCatalog.get("cultmesh.ts.note.v1")?.documentType,
|
||||
"cultmesh.ts-note",
|
||||
);
|
||||
|
||||
const builtIns = CultMesh.createBuiltInSchemaCatalog();
|
||||
assert.equal(
|
||||
builtIns.get("cultnet.shard_catalog_request.v0")?.schemaVersion,
|
||||
"cultnet.shard_catalog_request.v0",
|
||||
);
|
||||
assert.equal(
|
||||
builtIns.get("cultnet.shard_catalog_response.v0")?.kind,
|
||||
"wire_message",
|
||||
);
|
||||
assert.equal(
|
||||
builtIns.get(
|
||||
"https://github.com/GameCult/cultnet-ts/contracts/cultnet.transport-profile.schema.json",
|
||||
)?.schemaVersion,
|
||||
"cultnet.transport_profile.v0",
|
||||
);
|
||||
|
||||
const shardCatalog = CultMesh.createShardCatalog();
|
||||
const shardUpdates: string[] = [];
|
||||
const unsubscribeShard = shardCatalog.watch((descriptor) => {
|
||||
shardUpdates.push(descriptor.shardId);
|
||||
});
|
||||
shardCatalog.upsert({
|
||||
shardId: "notes-a",
|
||||
ownerRuntimeId: "ts-runtime",
|
||||
epoch: 7,
|
||||
schemaIds: ["cultmesh.ts.note.v1"],
|
||||
keyPrefix: "note:",
|
||||
});
|
||||
unsubscribeShard();
|
||||
shardCatalog.upsert({
|
||||
shardId: "notes-b",
|
||||
ownerRuntimeId: "ts-runtime",
|
||||
epoch: 8,
|
||||
});
|
||||
|
||||
assert.deepEqual(shardUpdates, ["notes-a"]);
|
||||
assert.equal(shardCatalog.get("notes-a")?.ownerRuntimeId, "ts-runtime");
|
||||
assert.deepEqual(
|
||||
shardCatalog
|
||||
.list({ schemaIds: ["cultmesh.ts.note.v1"], recordKeys: ["note:1"] })
|
||||
.map((shard) => shard.shardId),
|
||||
["notes-a"],
|
||||
);
|
||||
});
|
||||
|
||||
test("CultMesh TS negotiates streaming frame body transports explicitly", () => {
|
||||
const streams = CultMesh.createStreamCatalog();
|
||||
const streamUpdates: string[] = [];
|
||||
|
|
|
|||
Loading…
Reference in a new issue