@crowdedkingdoms/crowdy-dsh 0.3.3 → 0.3.4-dev.1
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/dsh-web/BUILD.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "@crowdedkingdoms/crowdy-dsh",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"builtAt": "2026-09-
|
|
3
|
+
"version": "0.3.4",
|
|
4
|
+
"builtAt": "2026-09-21T13:56:33.466Z",
|
|
5
5
|
"source": {
|
|
6
6
|
"repository": "CrowdedKingdoms/crowdy-dsh",
|
|
7
|
-
"commit": "
|
|
7
|
+
"commit": "82dfc27359cf226fd25238720d09807282c31118",
|
|
8
8
|
"dirty": false
|
|
9
9
|
},
|
|
10
10
|
"upstream": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"crowdyjs": {
|
|
17
17
|
"name": "@crowdedkingdoms/crowdyjs",
|
|
18
|
-
"version": "17.
|
|
18
|
+
"version": "17.6.0-dev.1",
|
|
19
19
|
"source": "node_modules"
|
|
20
20
|
},
|
|
21
21
|
"files": {
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"manifest.webmanifest": "sha256:9b54d57eea00f2fdd1affe6e7999a4209a515755f12ac1a3299da2d55e178d4c",
|
|
113
113
|
"preview/bootstrap-CYECZNXt.js": "sha256:9f303a0485c0badfdd19fad0c357ef050c5b9a343744ab5bf0c70015e7d95092",
|
|
114
114
|
"preview/crowdy-boot-Cklh1qNl.js": "sha256:b21e8eb126e1cd8a52159d2d577e610df6c8af36a436f9ed5028cfabd11a85ff",
|
|
115
|
-
"preview/vfs-image.tar.gz": "sha256:
|
|
115
|
+
"preview/vfs-image.tar.gz": "sha256:f35752ca934b215b2634204b8532a81263c807a620af929c1c1806656e186af5",
|
|
116
116
|
"preview/worker-C8-_ANaz.js": "sha256:81099e5732dfe0c32bacd5897316b7956c5a0a22da01b4a0c6e21d0a3b9d9aa1"
|
|
117
117
|
}
|
|
118
118
|
}
|
|
Binary file
|
|
@@ -5889,6 +5889,11 @@ function packMessageBundle(members) {
|
|
|
5889
5889
|
}
|
|
5890
5890
|
var WireMessageType = {
|
|
5891
5891
|
MESSAGE_BUNDLE: 2,
|
|
5892
|
+
// Buddy v0.30.0: the client advertises what it can read; a session that
|
|
5893
|
+
// advertised BUNDLE_SIGNED receives its bundles with ONE trailing HMAC over the
|
|
5894
|
+
// datagram and members without per-member HMACs (containsAuth = 0).
|
|
5895
|
+
CLIENT_CAPABILITIES: 29,
|
|
5896
|
+
MESSAGE_BUNDLE_SIGNED: 30,
|
|
5892
5897
|
GENERIC_ERROR_MESSAGE: 3,
|
|
5893
5898
|
CHANNEL_MESSAGE_REQUEST: 17,
|
|
5894
5899
|
CHANNEL_MESSAGE_NOTIFICATION: 18,
|
|
@@ -6016,6 +6021,16 @@ async function serializeSpatial(ctx, messageType, appId, chunk, distance, decayR
|
|
|
6016
6021
|
tailView.setUint8(dataLen + HMAC_SIZE + 8, sequenceNumber & 255);
|
|
6017
6022
|
return out;
|
|
6018
6023
|
}
|
|
6024
|
+
var ClientCapability = {
|
|
6025
|
+
/** This client parses MESSAGE_BUNDLE_SIGNED (one HMAC per downlink bundle). */
|
|
6026
|
+
BUNDLE_SIGNED: 1
|
|
6027
|
+
};
|
|
6028
|
+
var SDK_CAPABILITIES = ClientCapability.BUNDLE_SIGNED;
|
|
6029
|
+
function serializeClientCapabilities(ctx, appId, flags = SDK_CAPABILITIES, sequenceNumber = 0) {
|
|
6030
|
+
const payload = new Uint8Array(4);
|
|
6031
|
+
new DataView(payload.buffer).setUint32(0, flags >>> 0, true);
|
|
6032
|
+
return serializeSpatial(ctx, WireMessageType.CLIENT_CAPABILITIES, appId, { x: 0, y: 0, z: 0 }, 0, 0, "", payload, sequenceNumber);
|
|
6033
|
+
}
|
|
6019
6034
|
function serializeActorUpdate(ctx, input) {
|
|
6020
6035
|
return serializeSpatial(ctx, WireMessageType.ACTOR_UPDATE_REQUEST_2, input.appId, input.chunk, input.distance ?? 8, input.decayRate ?? 1, input.uuid, decodeBase64(input.state ?? ""), input.sequenceNumber ?? 0);
|
|
6021
6036
|
}
|
|
@@ -6278,23 +6293,12 @@ function parseRelayFrame(bytes) {
|
|
|
6278
6293
|
if (bytes.length < 1)
|
|
6279
6294
|
return [];
|
|
6280
6295
|
if (bytes[0] === WireMessageType.MESSAGE_BUNDLE) {
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
if (off + len > bytes.length)
|
|
6288
|
-
break;
|
|
6289
|
-
try {
|
|
6290
|
-
const parsed = parseOne(bytes.subarray(off, off + len));
|
|
6291
|
-
if (parsed)
|
|
6292
|
-
out.push(parsed);
|
|
6293
|
-
} catch {
|
|
6294
|
-
}
|
|
6295
|
-
off += len;
|
|
6296
|
-
}
|
|
6297
|
-
return out;
|
|
6296
|
+
return walkBundleMembers(bytes, bytes.length);
|
|
6297
|
+
}
|
|
6298
|
+
if (bytes[0] === WireMessageType.MESSAGE_BUNDLE_SIGNED) {
|
|
6299
|
+
if (bytes.length <= 1 + HMAC_SIZE)
|
|
6300
|
+
return [];
|
|
6301
|
+
return walkBundleMembers(bytes, bytes.length - HMAC_SIZE);
|
|
6298
6302
|
}
|
|
6299
6303
|
try {
|
|
6300
6304
|
const parsed = parseOne(bytes);
|
|
@@ -6303,6 +6307,25 @@ function parseRelayFrame(bytes) {
|
|
|
6303
6307
|
return [];
|
|
6304
6308
|
}
|
|
6305
6309
|
}
|
|
6310
|
+
function walkBundleMembers(bytes, end) {
|
|
6311
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
6312
|
+
const out = [];
|
|
6313
|
+
let off = 1;
|
|
6314
|
+
while (off + 2 <= end) {
|
|
6315
|
+
const len = view.getUint16(off, true);
|
|
6316
|
+
off += 2;
|
|
6317
|
+
if (off + len > end)
|
|
6318
|
+
break;
|
|
6319
|
+
try {
|
|
6320
|
+
const parsed = parseOne(bytes.subarray(off, off + len));
|
|
6321
|
+
if (parsed)
|
|
6322
|
+
out.push(parsed);
|
|
6323
|
+
} catch {
|
|
6324
|
+
}
|
|
6325
|
+
off += len;
|
|
6326
|
+
}
|
|
6327
|
+
return out;
|
|
6328
|
+
}
|
|
6306
6329
|
|
|
6307
6330
|
var RELAY_SUBPROTOCOL = "crowdy-relay-v1";
|
|
6308
6331
|
var BEARER_PREFIX = "bearer.";
|
|
@@ -6344,6 +6367,7 @@ var BinaryRelayTransport = class {
|
|
|
6344
6367
|
this.everReady = false;
|
|
6345
6368
|
this.retryTimer = null;
|
|
6346
6369
|
this.generation = 0;
|
|
6370
|
+
this.capsTimer = null;
|
|
6347
6371
|
this.pendingMembers = [];
|
|
6348
6372
|
this.pendingBytes = 0;
|
|
6349
6373
|
this.bundleTimer = null;
|
|
@@ -6361,6 +6385,8 @@ var BinaryRelayTransport = class {
|
|
|
6361
6385
|
this.retryMaxDelayMs = config.retryMaxDelayMs ?? 5e3;
|
|
6362
6386
|
this.bundleSends = config.bundleSends ?? true;
|
|
6363
6387
|
this.bundleWindowMs = Math.max(0, config.bundleWindowMs ?? 1);
|
|
6388
|
+
this.advertiseCapabilities = config.advertiseCapabilities ?? true;
|
|
6389
|
+
this.capabilitiesIntervalMs = Math.max(1e3, config.capabilitiesIntervalMs ?? 15e3);
|
|
6364
6390
|
}
|
|
6365
6391
|
/** Snapshot of the uplink counters. */
|
|
6366
6392
|
stats() {
|
|
@@ -6389,9 +6415,11 @@ var BinaryRelayTransport = class {
|
|
|
6389
6415
|
this.retryTimer = null;
|
|
6390
6416
|
}
|
|
6391
6417
|
this.generation += 1;
|
|
6418
|
+
this.stopCapabilities();
|
|
6392
6419
|
const ws = this.ws;
|
|
6393
6420
|
this.ws = null;
|
|
6394
6421
|
this.signContext = null;
|
|
6422
|
+
this.stopCapabilities();
|
|
6395
6423
|
if (ws) {
|
|
6396
6424
|
try {
|
|
6397
6425
|
ws.close(1e3, "client-disconnect");
|
|
@@ -6513,6 +6541,7 @@ var BinaryRelayTransport = class {
|
|
|
6513
6541
|
ws.binaryType = "arraybuffer";
|
|
6514
6542
|
this.ws = ws;
|
|
6515
6543
|
this.signContext = null;
|
|
6544
|
+
this.stopCapabilities();
|
|
6516
6545
|
let sawReady = false;
|
|
6517
6546
|
ws.onmessage = (event) => {
|
|
6518
6547
|
if (generation !== this.generation)
|
|
@@ -6543,6 +6572,8 @@ var BinaryRelayTransport = class {
|
|
|
6543
6572
|
this.ws = null;
|
|
6544
6573
|
const hadReady = this.signContext != null || sawReady;
|
|
6545
6574
|
this.signContext = null;
|
|
6575
|
+
this.stopCapabilities();
|
|
6576
|
+
this.stopCapabilities();
|
|
6546
6577
|
if (!this.desired) {
|
|
6547
6578
|
this.callbacks.onStatus("disconnected");
|
|
6548
6579
|
return;
|
|
@@ -6586,6 +6617,44 @@ var BinaryRelayTransport = class {
|
|
|
6586
6617
|
this.preReadyFailures = 0;
|
|
6587
6618
|
this.retries = 0;
|
|
6588
6619
|
this.callbacks.onStatus("connected");
|
|
6620
|
+
this.startCapabilities();
|
|
6621
|
+
}
|
|
6622
|
+
/**
|
|
6623
|
+
* Advertise this build's capabilities now and on a timer while ready. The
|
|
6624
|
+
* server binds them to the router serving our flow; a token refresh or a
|
|
6625
|
+
* relay-side Buddy migration silently resets that, and until the next
|
|
6626
|
+
* advertisement we are served in the older per-member form, which we parse too.
|
|
6627
|
+
*/
|
|
6628
|
+
startCapabilities() {
|
|
6629
|
+
this.stopCapabilities();
|
|
6630
|
+
if (!this.advertiseCapabilities)
|
|
6631
|
+
return;
|
|
6632
|
+
void this.sendCapabilities();
|
|
6633
|
+
const timer = setInterval(() => {
|
|
6634
|
+
void this.sendCapabilities();
|
|
6635
|
+
}, this.capabilitiesIntervalMs);
|
|
6636
|
+
timer.unref?.();
|
|
6637
|
+
this.capsTimer = timer;
|
|
6638
|
+
}
|
|
6639
|
+
stopCapabilities() {
|
|
6640
|
+
if (this.capsTimer) {
|
|
6641
|
+
clearInterval(this.capsTimer);
|
|
6642
|
+
this.capsTimer = null;
|
|
6643
|
+
}
|
|
6644
|
+
}
|
|
6645
|
+
async sendCapabilities() {
|
|
6646
|
+
const ctx = this.signContext;
|
|
6647
|
+
if (!ctx || this.appId == null || !this.isReady())
|
|
6648
|
+
return;
|
|
6649
|
+
try {
|
|
6650
|
+
const frame = await serializeClientCapabilities(ctx, this.appId);
|
|
6651
|
+
if (this.signContext !== ctx)
|
|
6652
|
+
return;
|
|
6653
|
+
this.sendFrame(frame);
|
|
6654
|
+
this.flushSends();
|
|
6655
|
+
} catch (error) {
|
|
6656
|
+
this.logger.debug?.(`capabilities not sent: ${String(error)}`);
|
|
6657
|
+
}
|
|
6589
6658
|
}
|
|
6590
6659
|
/**
|
|
6591
6660
|
* The server wants this client on a different instance.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crowdedkingdoms/crowdy-dsh",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4-dev.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -94,11 +94,11 @@
|
|
|
94
94
|
"crowdyDsh": {
|
|
95
95
|
"build": {
|
|
96
96
|
"package": "@crowdedkingdoms/crowdy-dsh",
|
|
97
|
-
"version": "0.3.
|
|
98
|
-
"builtAt": "2026-09-
|
|
97
|
+
"version": "0.3.4",
|
|
98
|
+
"builtAt": "2026-09-21T13:56:33.466Z",
|
|
99
99
|
"source": {
|
|
100
100
|
"repository": "CrowdedKingdoms/crowdy-dsh",
|
|
101
|
-
"commit": "
|
|
101
|
+
"commit": "82dfc27359cf226fd25238720d09807282c31118",
|
|
102
102
|
"dirty": false
|
|
103
103
|
},
|
|
104
104
|
"upstream": {
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
},
|
|
110
110
|
"crowdyjs": {
|
|
111
111
|
"name": "@crowdedkingdoms/crowdyjs",
|
|
112
|
-
"version": "17.
|
|
112
|
+
"version": "17.6.0-dev.1",
|
|
113
113
|
"source": "node_modules"
|
|
114
114
|
},
|
|
115
115
|
"files": {
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
"manifest.webmanifest": "sha256:9b54d57eea00f2fdd1affe6e7999a4209a515755f12ac1a3299da2d55e178d4c",
|
|
207
207
|
"preview/bootstrap-CYECZNXt.js": "sha256:9f303a0485c0badfdd19fad0c357ef050c5b9a343744ab5bf0c70015e7d95092",
|
|
208
208
|
"preview/crowdy-boot-Cklh1qNl.js": "sha256:b21e8eb126e1cd8a52159d2d577e610df6c8af36a436f9ed5028cfabd11a85ff",
|
|
209
|
-
"preview/vfs-image.tar.gz": "sha256:
|
|
209
|
+
"preview/vfs-image.tar.gz": "sha256:f35752ca934b215b2634204b8532a81263c807a620af929c1c1806656e186af5",
|
|
210
210
|
"preview/worker-C8-_ANaz.js": "sha256:81099e5732dfe0c32bacd5897316b7956c5a0a22da01b4a0c6e21d0a3b9d9aa1"
|
|
211
211
|
}
|
|
212
212
|
}
|