Add TS configured publication document handles
This commit is contained in:
parent
a6537a2d93
commit
47941b5fb3
3 changed files with 169 additions and 3 deletions
|
|
@ -321,6 +321,10 @@ The same typed-definition overload is available for
|
|||
`CultMesh.documentFromStore(...)` and `CultMesh.documentFromSingleFile(...)`, so
|
||||
local schema publications can be read as typed reactive documents without
|
||||
manually pulling records, decoding MessagePack, or parsing the payload.
|
||||
When the caller wants source selection to be configuration, use
|
||||
`CultMesh.documentFromPublication(...)` with a `single-file`, `store`, or
|
||||
`peer-snapshot` source; it returns the same typed handle while hiding whether
|
||||
sync came from local persistence or a remote CultNet snapshot.
|
||||
|
||||
## Streaming Mode
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,21 @@ export interface CultMeshRouteRecord {
|
|||
readonly description: string;
|
||||
}
|
||||
|
||||
export type CultMeshDocumentPublicationSource =
|
||||
| {
|
||||
readonly kind: "single-file";
|
||||
readonly path: string;
|
||||
}
|
||||
| {
|
||||
readonly kind: "store";
|
||||
readonly store: CacheBackingStore;
|
||||
}
|
||||
| {
|
||||
readonly kind: "peer-snapshot";
|
||||
readonly peer: CultNetPeer | (() => CultNetPeer | Promise<CultNetPeer>);
|
||||
readonly endpoint?: string;
|
||||
};
|
||||
|
||||
export interface CultMeshAuthorityClaim {
|
||||
readonly role: string;
|
||||
readonly shardId?: string;
|
||||
|
|
@ -2129,6 +2144,102 @@ export function cultMeshDocumentFromPeerSnapshot(
|
|||
);
|
||||
}
|
||||
|
||||
export function cultMeshDocumentFromPublication(
|
||||
source: CultMeshDocumentPublicationSource,
|
||||
schemaId: string,
|
||||
recordKey: string,
|
||||
options?: {
|
||||
documentId?: string;
|
||||
routeHint?: CultMeshRouteHint;
|
||||
sourceId?: string;
|
||||
timeoutMs?: number;
|
||||
pollMs?: number;
|
||||
messageIdPrefix?: string;
|
||||
},
|
||||
): CultMeshDocumentHandle<unknown>;
|
||||
export function cultMeshDocumentFromPublication<TDefinition extends AnyCultCacheDocumentDefinition>(
|
||||
source: CultMeshDocumentPublicationSource,
|
||||
definition: TDefinition,
|
||||
recordKey: string,
|
||||
options?: {
|
||||
documentId?: string;
|
||||
routeHint?: CultMeshRouteHint;
|
||||
sourceId?: string;
|
||||
timeoutMs?: number;
|
||||
pollMs?: number;
|
||||
messageIdPrefix?: string;
|
||||
},
|
||||
): CultMeshDocumentHandle<CultCacheDocumentValue<TDefinition>>;
|
||||
export function cultMeshDocumentFromPublication(
|
||||
source: CultMeshDocumentPublicationSource,
|
||||
schemaOrDefinition: string | AnyCultCacheDocumentDefinition,
|
||||
recordKey: string,
|
||||
options: {
|
||||
documentId?: string;
|
||||
routeHint?: CultMeshRouteHint;
|
||||
sourceId?: string;
|
||||
timeoutMs?: number;
|
||||
pollMs?: number;
|
||||
messageIdPrefix?: string;
|
||||
} = {},
|
||||
): CultMeshDocumentHandle<unknown> {
|
||||
if (!source) {
|
||||
throw new Error("CultMesh publication source is required.");
|
||||
}
|
||||
requireNonEmpty(recordKey, "recordKey");
|
||||
|
||||
switch (source.kind) {
|
||||
case "single-file":
|
||||
return typeof schemaOrDefinition === "string"
|
||||
? cultMeshDocumentFromSingleFile(source.path, schemaOrDefinition, {
|
||||
documentId: options.documentId ?? recordKey,
|
||||
routeHint: options.routeHint,
|
||||
sourceId: options.sourceId ?? recordKey,
|
||||
pollMs: options.pollMs,
|
||||
})
|
||||
: cultMeshDocumentFromSingleFile(source.path, schemaOrDefinition, {
|
||||
documentId: options.documentId ?? recordKey,
|
||||
routeHint: options.routeHint,
|
||||
sourceId: options.sourceId ?? recordKey,
|
||||
pollMs: options.pollMs,
|
||||
});
|
||||
case "store":
|
||||
return typeof schemaOrDefinition === "string"
|
||||
? cultMeshDocumentFromStore(source.store, schemaOrDefinition, {
|
||||
documentId: options.documentId ?? recordKey,
|
||||
routeHint: options.routeHint,
|
||||
sourceId: options.sourceId ?? recordKey,
|
||||
pollMs: options.pollMs,
|
||||
})
|
||||
: cultMeshDocumentFromStore(source.store, schemaOrDefinition, {
|
||||
documentId: options.documentId ?? recordKey,
|
||||
routeHint: options.routeHint,
|
||||
sourceId: options.sourceId ?? recordKey,
|
||||
pollMs: options.pollMs,
|
||||
});
|
||||
case "peer-snapshot":
|
||||
return typeof schemaOrDefinition === "string"
|
||||
? cultMeshDocumentFromPeerSnapshot(source.peer, schemaOrDefinition, recordKey, {
|
||||
documentId: options.documentId ?? recordKey,
|
||||
routeHint: options.routeHint ?? cultMeshRouteHint("network", source.endpoint ?? "CultNet snapshot"),
|
||||
sourceId: options.sourceId ?? recordKey,
|
||||
timeoutMs: options.timeoutMs,
|
||||
pollMs: options.pollMs,
|
||||
messageIdPrefix: options.messageIdPrefix,
|
||||
})
|
||||
: cultMeshDocumentFromPeerSnapshot(source.peer, schemaOrDefinition, recordKey, {
|
||||
documentId: options.documentId ?? recordKey,
|
||||
routeHint: options.routeHint ?? cultMeshRouteHint("network", source.endpoint ?? "CultNet snapshot"),
|
||||
sourceId: options.sourceId ?? recordKey,
|
||||
timeoutMs: options.timeoutMs,
|
||||
pollMs: options.pollMs,
|
||||
messageIdPrefix: options.messageIdPrefix,
|
||||
});
|
||||
default:
|
||||
throw new Error(`Unsupported CultMesh publication source kind '${(source as { kind?: string }).kind}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
export function cultMeshGlobalDocumentFromCache<TDefinition extends AnyCultCacheDocumentDefinition>(
|
||||
cache: CultCache,
|
||||
definition: TDefinition,
|
||||
|
|
@ -3925,6 +4036,50 @@ export class CultMesh {
|
|||
: cultMeshDocumentFromPeerSnapshot(peer, schemaOrDefinition, recordKey, options);
|
||||
}
|
||||
|
||||
public static documentFromPublication(
|
||||
source: CultMeshDocumentPublicationSource,
|
||||
schemaId: string,
|
||||
recordKey: string,
|
||||
options?: {
|
||||
documentId?: string;
|
||||
routeHint?: CultMeshRouteHint;
|
||||
sourceId?: string;
|
||||
timeoutMs?: number;
|
||||
pollMs?: number;
|
||||
messageIdPrefix?: string;
|
||||
},
|
||||
): CultMeshDocumentHandle<unknown>;
|
||||
public static documentFromPublication<TDefinition extends AnyCultCacheDocumentDefinition>(
|
||||
source: CultMeshDocumentPublicationSource,
|
||||
definition: TDefinition,
|
||||
recordKey: string,
|
||||
options?: {
|
||||
documentId?: string;
|
||||
routeHint?: CultMeshRouteHint;
|
||||
sourceId?: string;
|
||||
timeoutMs?: number;
|
||||
pollMs?: number;
|
||||
messageIdPrefix?: string;
|
||||
},
|
||||
): CultMeshDocumentHandle<CultCacheDocumentValue<TDefinition>>;
|
||||
public static documentFromPublication(
|
||||
source: CultMeshDocumentPublicationSource,
|
||||
schemaOrDefinition: string | AnyCultCacheDocumentDefinition,
|
||||
recordKey: string,
|
||||
options: {
|
||||
documentId?: string;
|
||||
routeHint?: CultMeshRouteHint;
|
||||
sourceId?: string;
|
||||
timeoutMs?: number;
|
||||
pollMs?: number;
|
||||
messageIdPrefix?: string;
|
||||
} = {},
|
||||
): CultMeshDocumentHandle<unknown> {
|
||||
return typeof schemaOrDefinition === "string"
|
||||
? cultMeshDocumentFromPublication(source, schemaOrDefinition, recordKey, options)
|
||||
: cultMeshDocumentFromPublication(source, schemaOrDefinition, recordKey, options);
|
||||
}
|
||||
|
||||
public static globalDocumentFromCache<TDefinition extends AnyCultCacheDocumentDefinition>(
|
||||
cache: CultCache,
|
||||
definition: TDefinition,
|
||||
|
|
|
|||
|
|
@ -196,7 +196,10 @@ test("CultMesh TS document handles read schema publications from single-file sto
|
|||
});
|
||||
await node.flush();
|
||||
|
||||
const document = CultMesh.documentFromSingleFile(filePath, noteDocument, {
|
||||
const document = CultMesh.documentFromPublication({
|
||||
kind: "single-file",
|
||||
path: filePath,
|
||||
}, noteDocument, "note:publication", {
|
||||
documentId: "daemon:cultmesh.note.latest",
|
||||
sourceId: "daemon:cultmesh.note.latest.v0",
|
||||
pollMs: 50,
|
||||
|
|
@ -1949,8 +1952,12 @@ test("CultMesh TS reads remote RUDP snapshots through document handles", async (
|
|||
},
|
||||
);
|
||||
|
||||
const document = CultMesh.documentFromPeerSnapshot(
|
||||
peer,
|
||||
const document = CultMesh.documentFromPublication(
|
||||
{
|
||||
kind: "peer-snapshot",
|
||||
peer,
|
||||
endpoint: `rudp://127.0.0.1:${server.bind.port}`,
|
||||
},
|
||||
noteDocument,
|
||||
"note:remote",
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue