@xnetjs/runtime 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +26 -2
- package/dist/index.js +39 -8
- package/package.json +10 -10
package/dist/index.d.ts
CHANGED
|
@@ -187,6 +187,14 @@ interface SyncManager {
|
|
|
187
187
|
track(nodeId: string, schemaId: string): void;
|
|
188
188
|
/** Stop tracking a Node */
|
|
189
189
|
untrack(nodeId: string): void;
|
|
190
|
+
/**
|
|
191
|
+
* Subscribe (receive-only) to a share room — e.g. a channel's
|
|
192
|
+
* `xnet-channel-<id>` — so grant-covered nodes the hub fans in reach the
|
|
193
|
+
* local store (exploration 0298). Idempotent. No-op without a node store.
|
|
194
|
+
*/
|
|
195
|
+
subscribeShareRoom(room: string): void;
|
|
196
|
+
/** Stop receiving a share room's changes. */
|
|
197
|
+
unsubscribeShareRoom(room: string): void;
|
|
190
198
|
/** Acquire a Y.Doc (used by useNode) */
|
|
191
199
|
acquire(nodeId: string): Promise<Y.Doc>;
|
|
192
200
|
/** Release a Y.Doc (component unmounted) */
|
|
@@ -944,6 +952,13 @@ declare function createMultiHubSyncManager(config: MultiHubSyncManagerConfig): M
|
|
|
944
952
|
* genuine backlog can't trip the hub's per-connection rate limiter (1008).
|
|
945
953
|
*/
|
|
946
954
|
|
|
955
|
+
/**
|
|
956
|
+
* The share room that carries a channel's nodes to its grantees (0298). Must
|
|
957
|
+
* match the hub's `channelShareRoom` so `topicToResource` resolves the grant.
|
|
958
|
+
*/
|
|
959
|
+
declare const channelShareRoom: (channelId: string) => string;
|
|
960
|
+
/** The share room that carries a workspace (bench) node to its grantees (0298). */
|
|
961
|
+
declare const workspaceShareRoom: (workspaceId: string) => string;
|
|
947
962
|
type SerializedNodeChange = {
|
|
948
963
|
id: string;
|
|
949
964
|
type: string;
|
|
@@ -984,6 +999,7 @@ type SyncBlockedListener = (reason: SyncBlockedReason, detail: string) => void;
|
|
|
984
999
|
declare class NodeStoreSyncProvider {
|
|
985
1000
|
private store;
|
|
986
1001
|
private room;
|
|
1002
|
+
private subscribeOnly;
|
|
987
1003
|
/** Confirmed, persisted high-water mark (advanced from the hub's response). */
|
|
988
1004
|
private lastSyncedLamport;
|
|
989
1005
|
/** Optimistic in-memory cursor: lamport of the last change actually sent. */
|
|
@@ -1005,7 +1021,15 @@ declare class NodeStoreSyncProvider {
|
|
|
1005
1021
|
private outboundHalted;
|
|
1006
1022
|
private clearResolver;
|
|
1007
1023
|
private firstRemoteApplyMarked;
|
|
1008
|
-
|
|
1024
|
+
/**
|
|
1025
|
+
* Subscribe-only providers (channel share rooms, 0298) RECEIVE and apply a
|
|
1026
|
+
* room's changes but never publish local changes into it (the hub owns
|
|
1027
|
+
* fan-out) and never advance the cursor from a live broadcast's author
|
|
1028
|
+
* lamport — a share room's cursor is a per-room `seq` carried opaquely in the
|
|
1029
|
+
* sync-response high-water mark, and author lamports across members are not
|
|
1030
|
+
* mutually ordered.
|
|
1031
|
+
*/
|
|
1032
|
+
constructor(store: NodeStore, room: string, subscribeOnly?: boolean);
|
|
1009
1033
|
/**
|
|
1010
1034
|
* Mark the first remote apply once. Platform-agnostic and defensive: a
|
|
1011
1035
|
* missing `performance` global, or a throw, is a no-op — instrumentation
|
|
@@ -1313,4 +1337,4 @@ declare function negotiateProtocolVersion(ours: readonly string[], theirs: reado
|
|
|
1313
1337
|
*/
|
|
1314
1338
|
declare function isProtocolCompatible(theirs: readonly string[]): boolean;
|
|
1315
1339
|
|
|
1316
|
-
export { type AdapterConformanceCheck, AdapterConformanceError, type AdapterConformanceResult, type BlobStoreForSync, type ConformanceClientFactory, type ConnectionManager, type ConnectionManagerConfig, type ConnectionStatus, type CreateXNetClientOptions, type HubConnection, type HubTransport, type InitialSyncManager, type InitialSyncMessage, type LiveQuery, type LiveQueryValue, METABRIDGE_ORIGIN, METABRIDGE_SEED_ORIGIN, type MetaBridge, type MultiHubConnectionManagerConfig, type MultiHubSyncManager, type MultiHubSyncManagerConfig, type NodePool, type NodePoolConfig, NodeStoreSyncProvider, type NodeSyncResponse, type OfflineQueue, type OfflineQueueConfig, type PlannedHub, type PoolEntryState, type ProgressListener, type QueueEntry, type Registry, type RegistryConfig, type RegistryStorage, type ReplicaTrust, type ReplicationDestinationSpec, type ReplicationScopeNode, type ScopedRoomHandle, type SerializedNodeChange, type SpaceReplicationPolicy, type SyncBlockedListener, type SyncBlockedReason, type SyncManager, type SyncManagerConfig, type SyncPhase, type SyncProgress, type SyncReconciliationOptions, type SyncReconciliationReport, type SyncStatus, type TrackedNode, WebSocketSyncProvider, type WebSocketSyncProviderOptions, XNET_AWARENESS_VERSION, XNET_DATA_MODEL_VERSION, XNET_PROTOCOL_VERSION, XNET_SCHEMA_VERSION, XNET_SUPPORTED_PROTOCOL_VERSIONS, XNET_SYNC_ENVELOPE_VERSION, XNET_UCAN_PROFILE, type XNetClient, type XNetClientBridgeMode, type XNetClientPluginOptions, type XNetClientRuntimePhase, type XNetClientRuntimeStatus, type XNetClientSyncOptions, type XNetClientTelemetry, type XNetClientUndoOptions, type XNetProtocolBundle, createConnectionManager, createInitialSyncManager, createMetaBridge, createMultiHubConnectionManager, createMultiHubSyncManager, createNodePool, createOfflineQueue, createRegistry, createSyncManager, createXNetClient, isProtocolCompatible, liveQuery, namespaceForNode, negotiateProtocolVersion, replicationConfigFromPolicies, runAdapterConformance, spaceNamespace, systemNamespace };
|
|
1340
|
+
export { type AdapterConformanceCheck, AdapterConformanceError, type AdapterConformanceResult, type BlobStoreForSync, type ConformanceClientFactory, type ConnectionManager, type ConnectionManagerConfig, type ConnectionStatus, type CreateXNetClientOptions, type HubConnection, type HubTransport, type InitialSyncManager, type InitialSyncMessage, type LiveQuery, type LiveQueryValue, METABRIDGE_ORIGIN, METABRIDGE_SEED_ORIGIN, type MetaBridge, type MultiHubConnectionManagerConfig, type MultiHubSyncManager, type MultiHubSyncManagerConfig, type NodePool, type NodePoolConfig, NodeStoreSyncProvider, type NodeSyncResponse, type OfflineQueue, type OfflineQueueConfig, type PlannedHub, type PoolEntryState, type ProgressListener, type QueueEntry, type Registry, type RegistryConfig, type RegistryStorage, type ReplicaTrust, type ReplicationDestinationSpec, type ReplicationScopeNode, type ScopedRoomHandle, type SerializedNodeChange, type SpaceReplicationPolicy, type SyncBlockedListener, type SyncBlockedReason, type SyncManager, type SyncManagerConfig, type SyncPhase, type SyncProgress, type SyncReconciliationOptions, type SyncReconciliationReport, type SyncStatus, type TrackedNode, WebSocketSyncProvider, type WebSocketSyncProviderOptions, XNET_AWARENESS_VERSION, XNET_DATA_MODEL_VERSION, XNET_PROTOCOL_VERSION, XNET_SCHEMA_VERSION, XNET_SUPPORTED_PROTOCOL_VERSIONS, XNET_SYNC_ENVELOPE_VERSION, XNET_UCAN_PROFILE, type XNetClient, type XNetClientBridgeMode, type XNetClientPluginOptions, type XNetClientRuntimePhase, type XNetClientRuntimeStatus, type XNetClientSyncOptions, type XNetClientTelemetry, type XNetClientUndoOptions, type XNetProtocolBundle, channelShareRoom, createConnectionManager, createInitialSyncManager, createMetaBridge, createMultiHubConnectionManager, createMultiHubSyncManager, createNodePool, createOfflineQueue, createRegistry, createSyncManager, createXNetClient, isProtocolCompatible, liveQuery, namespaceForNode, negotiateProtocolVersion, replicationConfigFromPolicies, runAdapterConformance, spaceNamespace, systemNamespace, workspaceShareRoom };
|
package/dist/index.js
CHANGED
|
@@ -901,11 +901,22 @@ function nowMs2() {
|
|
|
901
901
|
function yieldToEventLoop() {
|
|
902
902
|
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
903
903
|
}
|
|
904
|
+
var channelShareRoom = (channelId) => `xnet-channel-${channelId}`;
|
|
905
|
+
var workspaceShareRoom = (workspaceId) => `xnet-workspace-${workspaceId}`;
|
|
904
906
|
var CAPACITY_REJECTION_CODES = /* @__PURE__ */ new Set(["QUOTA_EXCEEDED", "STORAGE_FULL"]);
|
|
905
907
|
var NodeStoreSyncProvider = class {
|
|
906
|
-
|
|
908
|
+
/**
|
|
909
|
+
* Subscribe-only providers (channel share rooms, 0298) RECEIVE and apply a
|
|
910
|
+
* room's changes but never publish local changes into it (the hub owns
|
|
911
|
+
* fan-out) and never advance the cursor from a live broadcast's author
|
|
912
|
+
* lamport — a share room's cursor is a per-room `seq` carried opaquely in the
|
|
913
|
+
* sync-response high-water mark, and author lamports across members are not
|
|
914
|
+
* mutually ordered.
|
|
915
|
+
*/
|
|
916
|
+
constructor(store, room, subscribeOnly = false) {
|
|
907
917
|
this.store = store;
|
|
908
918
|
this.room = room;
|
|
919
|
+
this.subscribeOnly = subscribeOnly;
|
|
909
920
|
}
|
|
910
921
|
/** Confirmed, persisted high-water mark (advanced from the hub's response). */
|
|
911
922
|
lastSyncedLamport = 0;
|
|
@@ -990,10 +1001,12 @@ var NodeStoreSyncProvider = class {
|
|
|
990
1001
|
this.onDisconnected();
|
|
991
1002
|
}
|
|
992
1003
|
});
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1004
|
+
if (!this.subscribeOnly) {
|
|
1005
|
+
this.storeCleanup = this.store.subscribe((event) => {
|
|
1006
|
+
if (event.isRemote) return;
|
|
1007
|
+
this.enqueueChange(event.change);
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
997
1010
|
if (connection.status === "connected") {
|
|
998
1011
|
void this.onConnected();
|
|
999
1012
|
}
|
|
@@ -1026,7 +1039,7 @@ var NodeStoreSyncProvider = class {
|
|
|
1026
1039
|
if (!this.connection || this.connection.status !== "connected") return;
|
|
1027
1040
|
this.requestSync();
|
|
1028
1041
|
await this.waitForSyncResponse();
|
|
1029
|
-
await this.syncLocalChanges();
|
|
1042
|
+
if (!this.subscribeOnly) await this.syncLocalChanges();
|
|
1030
1043
|
}
|
|
1031
1044
|
onDisconnected() {
|
|
1032
1045
|
this.clearSendQueue();
|
|
@@ -1180,7 +1193,7 @@ var NodeStoreSyncProvider = class {
|
|
|
1180
1193
|
}
|
|
1181
1194
|
async handleRemoteChange(serialized, peerId = "unknown") {
|
|
1182
1195
|
const change = this.deserializeChange(serialized);
|
|
1183
|
-
if (serialized.lamportTime > this.lastSyncedLamport) {
|
|
1196
|
+
if (!this.subscribeOnly && serialized.lamportTime > this.lastSyncedLamport) {
|
|
1184
1197
|
this.lastSyncedLamport = serialized.lamportTime;
|
|
1185
1198
|
}
|
|
1186
1199
|
if (!KNOWN_CHANGE_TYPES.has(change.type)) {
|
|
@@ -1798,6 +1811,7 @@ function createSyncManager(config) {
|
|
|
1798
1811
|
});
|
|
1799
1812
|
let offlineQueueReady = Promise.resolve();
|
|
1800
1813
|
const nodeSyncProvider = config.nodeSyncRoom ? new NodeStoreSyncProvider(config.nodeStore, config.nodeSyncRoom) : null;
|
|
1814
|
+
const shareRoomProviders = /* @__PURE__ */ new Map();
|
|
1801
1815
|
let blobSync = null;
|
|
1802
1816
|
if (config.blobStore) {
|
|
1803
1817
|
const underlyingStore = config.blobStore;
|
|
@@ -2269,6 +2283,7 @@ function createSyncManager(config) {
|
|
|
2269
2283
|
log2("Connecting to signaling server...");
|
|
2270
2284
|
connection.connect();
|
|
2271
2285
|
nodeSyncProvider?.attach(connection);
|
|
2286
|
+
for (const provider of shareRoomProviders.values()) provider.attach(connection);
|
|
2272
2287
|
blobSync?.start();
|
|
2273
2288
|
const tracked = registry.getTracked();
|
|
2274
2289
|
log2("Joining rooms for", tracked.length, "tracked nodes");
|
|
@@ -2286,6 +2301,8 @@ function createSyncManager(config) {
|
|
|
2286
2301
|
});
|
|
2287
2302
|
blobSync?.stop();
|
|
2288
2303
|
nodeSyncProvider?.detach();
|
|
2304
|
+
for (const provider of shareRoomProviders.values()) provider.detach();
|
|
2305
|
+
shareRoomProviders.clear();
|
|
2289
2306
|
for (const nodeId of Array.from(roomCleanups.keys())) {
|
|
2290
2307
|
leaveNodeRoom(nodeId);
|
|
2291
2308
|
}
|
|
@@ -2314,6 +2331,18 @@ function createSyncManager(config) {
|
|
|
2314
2331
|
scheduleRegistrySave();
|
|
2315
2332
|
leaveNodeRoom(nodeId);
|
|
2316
2333
|
},
|
|
2334
|
+
subscribeShareRoom(room) {
|
|
2335
|
+
if (shareRoomProviders.has(room)) return;
|
|
2336
|
+
const provider = new NodeStoreSyncProvider(config.nodeStore, room, true);
|
|
2337
|
+
shareRoomProviders.set(room, provider);
|
|
2338
|
+
provider.attach(connection);
|
|
2339
|
+
},
|
|
2340
|
+
unsubscribeShareRoom(room) {
|
|
2341
|
+
const provider = shareRoomProviders.get(room);
|
|
2342
|
+
if (!provider) return;
|
|
2343
|
+
provider.detach();
|
|
2344
|
+
shareRoomProviders.delete(room);
|
|
2345
|
+
},
|
|
2317
2346
|
async acquire(nodeId) {
|
|
2318
2347
|
log2("Acquiring doc for node:", nodeId);
|
|
2319
2348
|
registry.touch(nodeId);
|
|
@@ -3492,6 +3521,7 @@ export {
|
|
|
3492
3521
|
XNET_SUPPORTED_PROTOCOL_VERSIONS,
|
|
3493
3522
|
XNET_SYNC_ENVELOPE_VERSION,
|
|
3494
3523
|
XNET_UCAN_PROFILE,
|
|
3524
|
+
channelShareRoom,
|
|
3495
3525
|
createConnectionManager,
|
|
3496
3526
|
createInitialSyncManager,
|
|
3497
3527
|
createMetaBridge,
|
|
@@ -3509,5 +3539,6 @@ export {
|
|
|
3509
3539
|
replicationConfigFromPolicies,
|
|
3510
3540
|
runAdapterConformance,
|
|
3511
3541
|
spaceNamespace,
|
|
3512
|
-
systemNamespace
|
|
3542
|
+
systemNamespace,
|
|
3543
|
+
workspaceShareRoom
|
|
3513
3544
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xnetjs/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Framework-agnostic xNet runtime: createXNetClient() and sync orchestration, usable from any framework, a CLI, a worker, or a Node service",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"y-protocols": "^1.0.6",
|
|
30
30
|
"yjs": "^13.6.24",
|
|
31
|
-
"@xnetjs/core": "0.
|
|
32
|
-
"@xnetjs/
|
|
33
|
-
"@xnetjs/
|
|
34
|
-
"@xnetjs/data-bridge": "0.
|
|
35
|
-
"@xnetjs/history": "0.
|
|
36
|
-
"@xnetjs/identity": "0.
|
|
37
|
-
"@xnetjs/plugins": "0.
|
|
38
|
-
"@xnetjs/storage": "0.
|
|
39
|
-
"@xnetjs/sync": "0.
|
|
31
|
+
"@xnetjs/core": "0.11.0",
|
|
32
|
+
"@xnetjs/data": "0.11.0",
|
|
33
|
+
"@xnetjs/crypto": "0.11.0",
|
|
34
|
+
"@xnetjs/data-bridge": "0.11.0",
|
|
35
|
+
"@xnetjs/history": "0.11.0",
|
|
36
|
+
"@xnetjs/identity": "0.11.0",
|
|
37
|
+
"@xnetjs/plugins": "0.11.0",
|
|
38
|
+
"@xnetjs/storage": "0.11.0",
|
|
39
|
+
"@xnetjs/sync": "0.11.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"jsdom": "^26.0.0",
|