@net-mesh/browser 0.44.1 → 0.45.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/CHANGELOG.md +20 -0
- package/dist/net_leaf.d.ts +21 -10
- package/dist/net_leaf.js +63 -35
- package/dist/net_leaf_bg.wasm +0 -0
- package/dist/net_leaf_bg.wasm.d.ts +11 -10
- package/dist/netcode/client.js +41 -6
- package/dist/stream.d.ts +8 -1
- package/dist/stream.js +8 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,26 @@ missing method at the call site rather than at install time. Unlike
|
|
|
14
14
|
`@net-mesh/sdk`, this package never depends on `@net-mesh/core` — see
|
|
15
15
|
the README on why it is a sibling package rather than a sub-path.
|
|
16
16
|
|
|
17
|
+
## 0.45.1 — a closed stream keeps hearing its peer
|
|
18
|
+
|
|
19
|
+
- **Closing a stream no longer silences its peer.** After `close()`, frames
|
|
20
|
+
the peer still sends on that label reach `node.onEvent` as `stream_data`,
|
|
21
|
+
exactly as for a stream the page never opened. Before, the node dropped
|
|
22
|
+
them (counted `drops.stream_closed`) until the page reopened the stream,
|
|
23
|
+
so closing a stream was worse than never opening it. `stream_closed` is
|
|
24
|
+
no longer counted and reads 0.
|
|
25
|
+
- **A timed-out netcode player can rejoin.** `hostNetcode` closes a
|
|
26
|
+
player's stream when it times the player out, and only learns about a
|
|
27
|
+
player from its frames, so the change above was what locked a timed-out
|
|
28
|
+
player out for good. It is now re-admitted when heard again and carries
|
|
29
|
+
on from where it was applied.
|
|
30
|
+
- **A player cut off from its host stays quiet.** `joinNetcode` keeps at
|
|
31
|
+
most the newest 64 unacknowledged inputs (older ones were never sent
|
|
32
|
+
again anyway), keeps every input frame under one event (8,000 bytes) so
|
|
33
|
+
it never rides as fragments, and while the host has said nothing for a
|
|
34
|
+
second repeats its inputs only at the ping rate instead of with every
|
|
35
|
+
input. A cut-off player used to upload about 700 kB/s.
|
|
36
|
+
|
|
17
37
|
## 0.44.0 — sharded matches, compact snapshots
|
|
18
38
|
|
|
19
39
|
- **`joinShards` merges a match split across several hosts** (topology A:
|
package/dist/net_leaf.d.ts
CHANGED
|
@@ -19,6 +19,16 @@ export class LeafNode {
|
|
|
19
19
|
* `transport:rtc`; `reflex_addr` and `rtc_addr` stay absent.
|
|
20
20
|
*/
|
|
21
21
|
announce(capabilities: string[]): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Apply one signed grant-revocation bundle, and say how many grants
|
|
24
|
+
* it newly revoked.
|
|
25
|
+
*
|
|
26
|
+
* The grant twin of [`Self::apply_org_revocation_bundle`]: the
|
|
27
|
+
* bundle is verified in-leaf before anything moves, an org can
|
|
28
|
+
* revoke only grants it issued, and every live served call that
|
|
29
|
+
* rode on a revoked grant retires with the `Revoked` terminal.
|
|
30
|
+
*/
|
|
31
|
+
apply_org_grant_revocation_bundle(bundle_hex: string): number;
|
|
22
32
|
/**
|
|
23
33
|
* Apply one signed revocation bundle from the control-plane
|
|
24
34
|
* feed, and say how many floors it raised.
|
|
@@ -1345,6 +1355,7 @@ export interface InitOutput {
|
|
|
1345
1355
|
readonly __wbg_proxystream_free: (a: number, b: number) => void;
|
|
1346
1356
|
readonly leafnode_anchor_id_hex: (a: number, b: number) => void;
|
|
1347
1357
|
readonly leafnode_announce: (a: number, b: number, c: number) => number;
|
|
1358
|
+
readonly leafnode_apply_org_grant_revocation_bundle: (a: number, b: number, c: number, d: number) => void;
|
|
1348
1359
|
readonly leafnode_apply_org_revocation_bundle: (a: number, b: number, c: number, d: number) => void;
|
|
1349
1360
|
readonly leafnode_arm_network_retry: (a: number, b: number) => void;
|
|
1350
1361
|
readonly leafnode_call: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
|
|
@@ -1451,16 +1462,16 @@ export interface InitOutput {
|
|
|
1451
1462
|
readonly proxystream_send: (a: number, b: number) => number;
|
|
1452
1463
|
readonly proxystream_stream_id_hex: (a: number, b: number) => void;
|
|
1453
1464
|
readonly start: () => void;
|
|
1454
|
-
readonly
|
|
1455
|
-
readonly
|
|
1456
|
-
readonly
|
|
1457
|
-
readonly
|
|
1458
|
-
readonly
|
|
1459
|
-
readonly
|
|
1460
|
-
readonly
|
|
1461
|
-
readonly
|
|
1462
|
-
readonly
|
|
1463
|
-
readonly
|
|
1465
|
+
readonly __wasm_bindgen_func_elem_6615: (a: number, b: number, c: number, d: number) => void;
|
|
1466
|
+
readonly __wasm_bindgen_func_elem_6617: (a: number, b: number, c: number, d: number) => void;
|
|
1467
|
+
readonly __wasm_bindgen_func_elem_2432: (a: number, b: number, c: number) => number;
|
|
1468
|
+
readonly __wasm_bindgen_func_elem_2433: (a: number, b: number, c: number) => void;
|
|
1469
|
+
readonly __wasm_bindgen_func_elem_2433_113: (a: number, b: number, c: number) => void;
|
|
1470
|
+
readonly __wasm_bindgen_func_elem_2433_114: (a: number, b: number, c: number) => void;
|
|
1471
|
+
readonly __wasm_bindgen_func_elem_2433_115: (a: number, b: number, c: number) => void;
|
|
1472
|
+
readonly __wasm_bindgen_func_elem_2433_116: (a: number, b: number, c: number) => void;
|
|
1473
|
+
readonly __wasm_bindgen_func_elem_2433_117: (a: number, b: number, c: number) => void;
|
|
1474
|
+
readonly __wasm_bindgen_func_elem_2433_118: (a: number, b: number, c: number) => void;
|
|
1464
1475
|
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
1465
1476
|
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
1466
1477
|
readonly __wbindgen_export3: (a: number) => void;
|
package/dist/net_leaf.js
CHANGED
|
@@ -54,6 +54,34 @@ export class LeafNode {
|
|
|
54
54
|
const ret = wasm.leafnode_announce(this.__wbg_ptr, ptr0, len0);
|
|
55
55
|
return takeObject(ret);
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Apply one signed grant-revocation bundle, and say how many grants
|
|
59
|
+
* it newly revoked.
|
|
60
|
+
*
|
|
61
|
+
* The grant twin of [`Self::apply_org_revocation_bundle`]: the
|
|
62
|
+
* bundle is verified in-leaf before anything moves, an org can
|
|
63
|
+
* revoke only grants it issued, and every live served call that
|
|
64
|
+
* rode on a revoked grant retires with the `Revoked` terminal.
|
|
65
|
+
* @param {string} bundle_hex
|
|
66
|
+
* @returns {number}
|
|
67
|
+
*/
|
|
68
|
+
apply_org_grant_revocation_bundle(bundle_hex) {
|
|
69
|
+
try {
|
|
70
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
71
|
+
const ptr0 = passStringToWasm0(bundle_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
72
|
+
const len0 = WASM_VECTOR_LEN;
|
|
73
|
+
wasm.leafnode_apply_org_grant_revocation_bundle(retptr, this.__wbg_ptr, ptr0, len0);
|
|
74
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
75
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
76
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
77
|
+
if (r2) {
|
|
78
|
+
throw takeObject(r1);
|
|
79
|
+
}
|
|
80
|
+
return r0 >>> 0;
|
|
81
|
+
} finally {
|
|
82
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
57
85
|
/**
|
|
58
86
|
* Apply one signed revocation bundle from the control-plane
|
|
59
87
|
* feed, and say how many floors it raised.
|
|
@@ -2712,13 +2740,13 @@ function __wbg_get_imports() {
|
|
|
2712
2740
|
const ret = getObject(arg0).errorCode;
|
|
2713
2741
|
return ret;
|
|
2714
2742
|
},
|
|
2743
|
+
__wbg_error_0b48a92af341cfbc: function(arg0, arg1) {
|
|
2744
|
+
console.error(getStringFromWasm0(arg0, arg1));
|
|
2745
|
+
},
|
|
2715
2746
|
__wbg_error_3da0c81bd4184d52: function(arg0) {
|
|
2716
2747
|
const ret = getObject(arg0).error;
|
|
2717
2748
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
2718
2749
|
},
|
|
2719
|
-
__wbg_error_5f3dc2db8f851959: function(arg0, arg1) {
|
|
2720
|
-
console.error(getStringFromWasm0(arg0, arg1));
|
|
2721
|
-
},
|
|
2722
2750
|
__wbg_error_6a23b57453026a47: function() { return handleError(function (arg0) {
|
|
2723
2751
|
const ret = getObject(arg0).error;
|
|
2724
2752
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
@@ -2912,7 +2940,7 @@ function __wbg_get_imports() {
|
|
|
2912
2940
|
const a = state0.a;
|
|
2913
2941
|
state0.a = 0;
|
|
2914
2942
|
try {
|
|
2915
|
-
return
|
|
2943
|
+
return __wasm_bindgen_func_elem_6617(a, state0.b, arg0, arg1);
|
|
2916
2944
|
} finally {
|
|
2917
2945
|
state0.a = a;
|
|
2918
2946
|
}
|
|
@@ -2954,7 +2982,7 @@ function __wbg_get_imports() {
|
|
|
2954
2982
|
const a = state0.a;
|
|
2955
2983
|
state0.a = 0;
|
|
2956
2984
|
try {
|
|
2957
|
-
return
|
|
2985
|
+
return __wasm_bindgen_func_elem_6617(a, state0.b, arg0, arg1);
|
|
2958
2986
|
} finally {
|
|
2959
2987
|
state0.a = a;
|
|
2960
2988
|
}
|
|
@@ -3264,47 +3292,47 @@ function __wbg_get_imports() {
|
|
|
3264
3292
|
},
|
|
3265
3293
|
__wbindgen_generic_0000000000000001: function(arg0, arg1) {
|
|
3266
3294
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 34, ret: Externref, inner_ret: Some(Externref) }, mutable: true }) -> Externref`.
|
|
3267
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3295
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2432);
|
|
3268
3296
|
return addHeapObject(ret);
|
|
3269
3297
|
},
|
|
3270
3298
|
__wbindgen_generic_0000000000000002: function(arg0, arg1) {
|
|
3271
3299
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3272
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3300
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2433);
|
|
3273
3301
|
return addHeapObject(ret);
|
|
3274
3302
|
},
|
|
3275
3303
|
__wbindgen_generic_0000000000000003: function(arg0, arg1) {
|
|
3276
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx:
|
|
3277
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3304
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 864, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
3305
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_6615);
|
|
3278
3306
|
return addHeapObject(ret);
|
|
3279
3307
|
},
|
|
3280
3308
|
__wbindgen_generic_0000000000000004: function(arg0, arg1) {
|
|
3281
3309
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("CloseEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3282
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3310
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2433_113);
|
|
3283
3311
|
return addHeapObject(ret);
|
|
3284
3312
|
},
|
|
3285
3313
|
__wbindgen_generic_0000000000000005: function(arg0, arg1) {
|
|
3286
3314
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3287
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3315
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2433_114);
|
|
3288
3316
|
return addHeapObject(ret);
|
|
3289
3317
|
},
|
|
3290
3318
|
__wbindgen_generic_0000000000000006: function(arg0, arg1) {
|
|
3291
3319
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("MessageEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3292
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3320
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2433_115);
|
|
3293
3321
|
return addHeapObject(ret);
|
|
3294
3322
|
},
|
|
3295
3323
|
__wbindgen_generic_0000000000000007: function(arg0, arg1) {
|
|
3296
3324
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCDataChannelEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3297
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3325
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2433_116);
|
|
3298
3326
|
return addHeapObject(ret);
|
|
3299
3327
|
},
|
|
3300
3328
|
__wbindgen_generic_0000000000000008: function(arg0, arg1) {
|
|
3301
3329
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCPeerConnectionIceErrorEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3302
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3330
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2433_117);
|
|
3303
3331
|
return addHeapObject(ret);
|
|
3304
3332
|
},
|
|
3305
3333
|
__wbindgen_generic_0000000000000009: function(arg0, arg1) {
|
|
3306
3334
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCPeerConnectionIceEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3307
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3335
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2433_118);
|
|
3308
3336
|
return addHeapObject(ret);
|
|
3309
3337
|
},
|
|
3310
3338
|
__wbindgen_generic_000000000000000a: function(arg0) {
|
|
@@ -3331,47 +3359,47 @@ function __wbg_get_imports() {
|
|
|
3331
3359
|
};
|
|
3332
3360
|
}
|
|
3333
3361
|
|
|
3334
|
-
function
|
|
3335
|
-
wasm.
|
|
3362
|
+
function __wasm_bindgen_func_elem_2433(arg0, arg1, arg2) {
|
|
3363
|
+
wasm.__wasm_bindgen_func_elem_2433(arg0, arg1, addHeapObject(arg2));
|
|
3336
3364
|
}
|
|
3337
3365
|
|
|
3338
|
-
function
|
|
3339
|
-
wasm.
|
|
3366
|
+
function __wasm_bindgen_func_elem_2433_113(arg0, arg1, arg2) {
|
|
3367
|
+
wasm.__wasm_bindgen_func_elem_2433_113(arg0, arg1, addHeapObject(arg2));
|
|
3340
3368
|
}
|
|
3341
3369
|
|
|
3342
|
-
function
|
|
3343
|
-
wasm.
|
|
3370
|
+
function __wasm_bindgen_func_elem_2433_114(arg0, arg1, arg2) {
|
|
3371
|
+
wasm.__wasm_bindgen_func_elem_2433_114(arg0, arg1, addHeapObject(arg2));
|
|
3344
3372
|
}
|
|
3345
3373
|
|
|
3346
|
-
function
|
|
3347
|
-
wasm.
|
|
3374
|
+
function __wasm_bindgen_func_elem_2433_115(arg0, arg1, arg2) {
|
|
3375
|
+
wasm.__wasm_bindgen_func_elem_2433_115(arg0, arg1, addHeapObject(arg2));
|
|
3348
3376
|
}
|
|
3349
3377
|
|
|
3350
|
-
function
|
|
3351
|
-
wasm.
|
|
3378
|
+
function __wasm_bindgen_func_elem_2433_116(arg0, arg1, arg2) {
|
|
3379
|
+
wasm.__wasm_bindgen_func_elem_2433_116(arg0, arg1, addHeapObject(arg2));
|
|
3352
3380
|
}
|
|
3353
3381
|
|
|
3354
|
-
function
|
|
3355
|
-
wasm.
|
|
3382
|
+
function __wasm_bindgen_func_elem_2433_117(arg0, arg1, arg2) {
|
|
3383
|
+
wasm.__wasm_bindgen_func_elem_2433_117(arg0, arg1, addHeapObject(arg2));
|
|
3356
3384
|
}
|
|
3357
3385
|
|
|
3358
|
-
function
|
|
3359
|
-
wasm.
|
|
3386
|
+
function __wasm_bindgen_func_elem_2433_118(arg0, arg1, arg2) {
|
|
3387
|
+
wasm.__wasm_bindgen_func_elem_2433_118(arg0, arg1, addHeapObject(arg2));
|
|
3360
3388
|
}
|
|
3361
3389
|
|
|
3362
|
-
function
|
|
3363
|
-
const ret = wasm.
|
|
3390
|
+
function __wasm_bindgen_func_elem_2432(arg0, arg1, arg2) {
|
|
3391
|
+
const ret = wasm.__wasm_bindgen_func_elem_2432(arg0, arg1, addHeapObject(arg2));
|
|
3364
3392
|
return takeObject(ret);
|
|
3365
3393
|
}
|
|
3366
3394
|
|
|
3367
|
-
function
|
|
3368
|
-
wasm.
|
|
3395
|
+
function __wasm_bindgen_func_elem_6617(arg0, arg1, arg2, arg3) {
|
|
3396
|
+
wasm.__wasm_bindgen_func_elem_6617(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
|
|
3369
3397
|
}
|
|
3370
3398
|
|
|
3371
|
-
function
|
|
3399
|
+
function __wasm_bindgen_func_elem_6615(arg0, arg1, arg2) {
|
|
3372
3400
|
try {
|
|
3373
3401
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
3374
|
-
wasm.
|
|
3402
|
+
wasm.__wasm_bindgen_func_elem_6615(retptr, arg0, arg1, addHeapObject(arg2));
|
|
3375
3403
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
3376
3404
|
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
3377
3405
|
if (r1) {
|
package/dist/net_leaf_bg.wasm
CHANGED
|
Binary file
|
|
@@ -13,6 +13,7 @@ export const __wbg_orguploadcallhandle_free: (a: number, b: number) => void;
|
|
|
13
13
|
export const __wbg_proxystream_free: (a: number, b: number) => void;
|
|
14
14
|
export const leafnode_anchor_id_hex: (a: number, b: number) => void;
|
|
15
15
|
export const leafnode_announce: (a: number, b: number, c: number) => number;
|
|
16
|
+
export const leafnode_apply_org_grant_revocation_bundle: (a: number, b: number, c: number, d: number) => void;
|
|
16
17
|
export const leafnode_apply_org_revocation_bundle: (a: number, b: number, c: number, d: number) => void;
|
|
17
18
|
export const leafnode_arm_network_retry: (a: number, b: number) => void;
|
|
18
19
|
export const leafnode_call: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
|
|
@@ -119,16 +120,16 @@ export const proxystream_peer_node_hex: (a: number, b: number) => void;
|
|
|
119
120
|
export const proxystream_send: (a: number, b: number) => number;
|
|
120
121
|
export const proxystream_stream_id_hex: (a: number, b: number) => void;
|
|
121
122
|
export const start: () => void;
|
|
122
|
-
export const
|
|
123
|
-
export const
|
|
124
|
-
export const
|
|
125
|
-
export const
|
|
126
|
-
export const
|
|
127
|
-
export const
|
|
128
|
-
export const
|
|
129
|
-
export const
|
|
130
|
-
export const
|
|
131
|
-
export const
|
|
123
|
+
export const __wasm_bindgen_func_elem_6615: (a: number, b: number, c: number, d: number) => void;
|
|
124
|
+
export const __wasm_bindgen_func_elem_6617: (a: number, b: number, c: number, d: number) => void;
|
|
125
|
+
export const __wasm_bindgen_func_elem_2432: (a: number, b: number, c: number) => number;
|
|
126
|
+
export const __wasm_bindgen_func_elem_2433: (a: number, b: number, c: number) => void;
|
|
127
|
+
export const __wasm_bindgen_func_elem_2433_113: (a: number, b: number, c: number) => void;
|
|
128
|
+
export const __wasm_bindgen_func_elem_2433_114: (a: number, b: number, c: number) => void;
|
|
129
|
+
export const __wasm_bindgen_func_elem_2433_115: (a: number, b: number, c: number) => void;
|
|
130
|
+
export const __wasm_bindgen_func_elem_2433_116: (a: number, b: number, c: number) => void;
|
|
131
|
+
export const __wasm_bindgen_func_elem_2433_117: (a: number, b: number, c: number) => void;
|
|
132
|
+
export const __wasm_bindgen_func_elem_2433_118: (a: number, b: number, c: number) => void;
|
|
132
133
|
export const __wbindgen_export: (a: number, b: number) => number;
|
|
133
134
|
export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
134
135
|
export const __wbindgen_export3: (a: number) => void;
|
package/dist/netcode/client.js
CHANGED
|
@@ -34,6 +34,20 @@ export class NetcodeError extends Error {
|
|
|
34
34
|
* ticks, and a host skips the gap the earlier frame would have filled.
|
|
35
35
|
*/
|
|
36
36
|
const MAX_INPUT_BACKLOG = 64;
|
|
37
|
+
/**
|
|
38
|
+
* Largest input frame, bytes. Under one event, as the host's snapshot
|
|
39
|
+
* default is, so an input frame never rides as fragments: on the lossy
|
|
40
|
+
* carrier one lost fragment loses the whole frame. A backlog that does not
|
|
41
|
+
* fit sends its newest inputs.
|
|
42
|
+
*/
|
|
43
|
+
const MAX_INPUT_FRAME_BYTES = 8000;
|
|
44
|
+
/**
|
|
45
|
+
* How long the host may say nothing before input frames stop going out at
|
|
46
|
+
* the input rate, ms. While it is silent, unacknowledged inputs are repeated
|
|
47
|
+
* only on the ping timer: a player cut off from its host used to send its
|
|
48
|
+
* whole backlog, as fragments, with every input (~700 kB/s, net-fps report).
|
|
49
|
+
*/
|
|
50
|
+
const HOST_SILENT_MS = 1000;
|
|
37
51
|
/** A fresh {@link InputSequencer}: `seq` 0, nothing pending. */
|
|
38
52
|
export function createInputSequencer() {
|
|
39
53
|
return { seq: 0, pending: [] };
|
|
@@ -121,11 +135,23 @@ export function joinNetcode(options) {
|
|
|
121
135
|
let lastSnapshotAt = null;
|
|
122
136
|
const inputEpoch = () => (options.epoch === undefined ? {} : { ep: options.epoch() });
|
|
123
137
|
// The newest `redundancy` inputs — or, past that, the whole backlog up to
|
|
124
|
-
// MAX_INPUT_BACKLOG, in one frame.
|
|
138
|
+
// MAX_INPUT_BACKLOG, in one frame of at most MAX_INPUT_FRAME_BYTES. A
|
|
139
|
+
// backlog too big for one frame sends its newest inputs: a host skips
|
|
140
|
+
// whatever an earlier frame would have filled anyway.
|
|
125
141
|
const sendInputs = () => {
|
|
126
|
-
|
|
127
|
-
|
|
142
|
+
let count = Math.min(inputs.pending.length, inputs.pending.length > redundancy ? MAX_INPUT_BACKLOG : redundancy);
|
|
143
|
+
for (;;) {
|
|
144
|
+
const bytes = encodeFrame({ n: label, k: 'i', i: inputs.pending.slice(-count), ...inputEpoch() });
|
|
145
|
+
if (bytes.byteLength <= MAX_INPUT_FRAME_BYTES || count <= 1) {
|
|
146
|
+
sendBytes(bytes);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
count = Math.max(1, Math.min(count - 1, Math.floor((count * MAX_INPUT_FRAME_BYTES) / bytes.byteLength)));
|
|
150
|
+
}
|
|
128
151
|
};
|
|
152
|
+
// When the host was last heard from: any frame of this label, or binary.
|
|
153
|
+
let hostHeardAt = now();
|
|
154
|
+
const hostSilent = () => now() - hostHeardAt > HOST_SILENT_MS;
|
|
129
155
|
const offset = () => clock.estimate()?.offsetMs ?? null;
|
|
130
156
|
const hostNow = () => {
|
|
131
157
|
const o = offset();
|
|
@@ -191,7 +217,8 @@ export function joinNetcode(options) {
|
|
|
191
217
|
// replaced (a reconnect, a relayed → direct upgrade) and a stream handle
|
|
192
218
|
// is fenced to the session it was opened on. The protocol repeats what
|
|
193
219
|
// was lost, so reopening is all recovery needs.
|
|
194
|
-
const send = (frame) =>
|
|
220
|
+
const send = (frame) => sendBytes(encodeFrame(frame));
|
|
221
|
+
const sendBytes = (payload) => {
|
|
195
222
|
const current = stream;
|
|
196
223
|
if (current === null) {
|
|
197
224
|
void open();
|
|
@@ -211,7 +238,7 @@ export function joinNetcode(options) {
|
|
|
211
238
|
}
|
|
212
239
|
};
|
|
213
240
|
try {
|
|
214
|
-
void Promise.resolve(current.send(
|
|
241
|
+
void Promise.resolve(current.send(payload)).catch(retire);
|
|
215
242
|
}
|
|
216
243
|
catch (error) {
|
|
217
244
|
retire(error);
|
|
@@ -223,12 +250,14 @@ export function joinNetcode(options) {
|
|
|
223
250
|
if (eventPeer(event.peerNode) !== host)
|
|
224
251
|
return;
|
|
225
252
|
if (isBinaryFrame(event.payload)) {
|
|
253
|
+
hostHeardAt = now();
|
|
226
254
|
onBinary(event.payload);
|
|
227
255
|
return;
|
|
228
256
|
}
|
|
229
257
|
const frame = decodeFrame(event.payload, label);
|
|
230
258
|
if (frame === null)
|
|
231
259
|
return;
|
|
260
|
+
hostHeardAt = now();
|
|
232
261
|
if (frame.k === 'q') {
|
|
233
262
|
clock.add(frame.t0, frame.t1, frame.t2, now());
|
|
234
263
|
return;
|
|
@@ -492,12 +521,18 @@ export function joinNetcode(options) {
|
|
|
492
521
|
const seq = inputs.seq;
|
|
493
522
|
const seen = (hostNow() ?? now()) - delay;
|
|
494
523
|
inputs.pending.push({ seq, seen, data });
|
|
524
|
+
// Only the newest MAX_INPUT_BACKLOG are ever sent again, so older
|
|
525
|
+
// ones are dropped rather than held (and replayed) until an ack.
|
|
526
|
+
if (inputs.pending.length > MAX_INPUT_BACKLOG)
|
|
527
|
+
inputs.pending.splice(0, inputs.pending.length - MAX_INPUT_BACKLOG);
|
|
495
528
|
if (options.local && predicted !== null) {
|
|
496
529
|
predicted = options.local.predict(predicted, data);
|
|
497
530
|
if (correcting !== null)
|
|
498
531
|
correcting = { ...correcting, from: options.local.predict(correcting.from, data) };
|
|
499
532
|
}
|
|
500
|
-
|
|
533
|
+
// A silent host gets the backlog from the ping timer, not per input.
|
|
534
|
+
if (!hostSilent())
|
|
535
|
+
sendInputs();
|
|
501
536
|
},
|
|
502
537
|
view() {
|
|
503
538
|
const at = hostNow();
|
package/dist/stream.d.ts
CHANGED
|
@@ -179,7 +179,14 @@ export declare class LeafStream implements AsyncIterable<Uint8Array> {
|
|
|
179
179
|
/** Listen for payloads. Returns a cancel handle. */
|
|
180
180
|
onMessage(listener: (payload: Uint8Array) => void): () => void;
|
|
181
181
|
[Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array>;
|
|
182
|
-
/**
|
|
182
|
+
/**
|
|
183
|
+
* Close the stream and end every consumer.
|
|
184
|
+
*
|
|
185
|
+
* Close is local: the peer's half is its own. Frames the peer still
|
|
186
|
+
* sends on this label reach `node.onEvent` as `stream_data`, exactly as
|
|
187
|
+
* for a stream this page never opened. Before 0.45.1 the node dropped
|
|
188
|
+
* them (`drops.stream_closed`) until the stream was reopened.
|
|
189
|
+
*/
|
|
183
190
|
close(): void;
|
|
184
191
|
/**
|
|
185
192
|
* One callback from the wasm boundary.
|
package/dist/stream.js
CHANGED
|
@@ -176,7 +176,14 @@ export class LeafStream {
|
|
|
176
176
|
this.retiredBy = reason;
|
|
177
177
|
this.close();
|
|
178
178
|
}
|
|
179
|
-
/**
|
|
179
|
+
/**
|
|
180
|
+
* Close the stream and end every consumer.
|
|
181
|
+
*
|
|
182
|
+
* Close is local: the peer's half is its own. Frames the peer still
|
|
183
|
+
* sends on this label reach `node.onEvent` as `stream_data`, exactly as
|
|
184
|
+
* for a stream this page never opened. Before 0.45.1 the node dropped
|
|
185
|
+
* them (`drops.stream_closed`) until the stream was reopened.
|
|
186
|
+
*/
|
|
180
187
|
close() {
|
|
181
188
|
if (this.closed)
|
|
182
189
|
return;
|