@net-mesh/browser 0.42.0 → 0.44.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/CHANGELOG.md +200 -0
- package/README.md +12 -0
- package/dist/index.bundle.js +2 -2
- package/dist/leader/session.d.ts +4 -2
- package/dist/leader/session.js +30 -6
- package/dist/lobby.d.ts +29 -2
- package/dist/lobby.js +80 -10
- package/dist/net_leaf.d.ts +19 -21
- package/dist/net_leaf.js +42 -44
- package/dist/net_leaf_bg.wasm +0 -0
- package/dist/net_leaf_bg.wasm.d.ts +10 -10
- package/dist/netcode/assignment.d.ts +169 -0
- package/dist/netcode/assignment.js +321 -0
- package/dist/netcode/client.d.ts +125 -3
- package/dist/netcode/client.js +291 -27
- package/dist/netcode/codec.d.ts +180 -0
- package/dist/netcode/codec.js +547 -0
- package/dist/netcode/host.d.ts +58 -1
- package/dist/netcode/host.js +254 -9
- package/dist/netcode/index.d.ts +14 -4
- package/dist/netcode/index.js +8 -3
- package/dist/netcode/interpolate.d.ts +24 -1
- package/dist/netcode/interpolate.js +52 -1
- package/dist/netcode/paths.d.ts +115 -0
- package/dist/netcode/paths.js +261 -0
- package/dist/netcode/shards.d.ts +138 -0
- package/dist/netcode/shards.js +270 -0
- package/dist/netcode/wire.d.ts +37 -3
- package/dist/netcode/wire.js +28 -1
- package/dist/node.d.ts +20 -0
- package/dist/node.js +76 -1
- package/dist/store/host.js +10 -4
- package/dist/store/join.js +38 -2
- package/dist/store/owner.d.ts +11 -0
- package/dist/store/owner.js +27 -7
- package/dist/store/types.d.ts +6 -0
- package/dist/stream.d.ts +29 -1
- package/dist/stream.js +66 -4
- package/dist/udp-probe.d.ts +21 -3
- package/dist/udp-probe.js +78 -7
- package/dist/world/link.d.ts +9 -0
- package/dist/world/link.js +4 -3
- package/dist/world/regions.d.ts +9 -2
- package/dist/world/regions.js +34 -4
- package/package.json +3 -2
package/dist/leader/session.d.ts
CHANGED
|
@@ -57,7 +57,10 @@ export interface SessionOptions extends ConnectOptions {
|
|
|
57
57
|
dbName?: string;
|
|
58
58
|
/**
|
|
59
59
|
* Override the Web Lock and `BroadcastChannel` name. Defaults to
|
|
60
|
-
* `net-mesh/<origin>/<identity-fingerprint
|
|
60
|
+
* `net-mesh/<origin>/<identity-fingerprint>`, or — with a custodial
|
|
61
|
+
* `entitySecretHex` — to the identity lock `connect()` takes for that
|
|
62
|
+
* secret, so a `connect()` tab and an `openSession()` tab cannot both run
|
|
63
|
+
* the identity. Setting it opts out of that contention.
|
|
61
64
|
*
|
|
62
65
|
* For tests that need two independent elections inside one origin.
|
|
63
66
|
* A page should not set it: two scopes on one identity is two nodes
|
|
@@ -65,7 +68,6 @@ export interface SessionOptions extends ConnectOptions {
|
|
|
65
68
|
*/
|
|
66
69
|
lockScope?: string;
|
|
67
70
|
}
|
|
68
|
-
/** The origin's Net node, as this tab sees it. */
|
|
69
71
|
export declare class MeshSession {
|
|
70
72
|
private readonly inner;
|
|
71
73
|
/**
|
package/dist/leader/session.js
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
*/
|
|
29
29
|
import { fromWasmError, OrgCancelledError, OrgLeaderLostError, } from '../errors.js';
|
|
30
30
|
import { clientStreamOrgTrampoline, duplexOrgTrampoline, OrgDuplex, OrgHandleRegistry, OrgServe, OrgStream, OrgUpload, streamingOrgTrampoline, toWasmOrgCallOptions, toWasmOrgServeOptions, unaryOrgTrampoline, } from '../org.js';
|
|
31
|
-
import { buildConnectRequest, parseAttemptStatus, parseCounters, parseDescriptors, } from '../node.js';
|
|
31
|
+
import { buildConnectRequest, identityLockName, parseAttemptStatus, parseCounters, parseDescriptors, } from '../node.js';
|
|
32
32
|
import { acceptPeer as driveAccept, answerWaitingOffer, connectPeer as driveConnect, noteOffer, PeerAttempts, } from '../peer-driver.js';
|
|
33
33
|
import { LeafStream } from '../stream.js';
|
|
34
34
|
import { idArg, loadLeafWasm } from '../wasm.js';
|
|
@@ -36,6 +36,13 @@ import { isLifecycleEvent, parseSessionEvent, } from './events.js';
|
|
|
36
36
|
import { asSessionModule } from './wasm.js';
|
|
37
37
|
import { EventHub } from '../events.js';
|
|
38
38
|
/** The origin's Net node, as this tab sees it. */
|
|
39
|
+
/**
|
|
40
|
+
* What a send on a stream ended by a leader change fails with. Worded
|
|
41
|
+
* the way the leaf words a stale handle, because `isStaleStream` (the
|
|
42
|
+
* store's reopen test) matches exactly that: a store over a session
|
|
43
|
+
* reopens on the new leader rather than counting `send-failed` forever.
|
|
44
|
+
*/
|
|
45
|
+
const STALE_AFTER_HANDOFF = 'stale stream handle: the leader changed; reopen the stream';
|
|
39
46
|
export class MeshSession {
|
|
40
47
|
inner;
|
|
41
48
|
/**
|
|
@@ -100,7 +107,7 @@ export class MeshSession {
|
|
|
100
107
|
// The generation that owned the calls is the one they were
|
|
101
108
|
// issued under — typed `LeaderLost`, never resumed.
|
|
102
109
|
this.orgHandles.retireAll(new OrgLeaderLostError(this.streamGeneration));
|
|
103
|
-
this.endStreams();
|
|
110
|
+
this.endStreams(STALE_AFTER_HANDOFF);
|
|
104
111
|
return;
|
|
105
112
|
}
|
|
106
113
|
// And the abrupt case: a generation that moved under us. Read
|
|
@@ -114,7 +121,7 @@ export class MeshSession {
|
|
|
114
121
|
const previous = this.streamGeneration;
|
|
115
122
|
this.streamGeneration = current;
|
|
116
123
|
this.orgHandles.retireAll(new OrgLeaderLostError(previous));
|
|
117
|
-
this.endStreams();
|
|
124
|
+
this.endStreams(STALE_AFTER_HANDOFF);
|
|
118
125
|
});
|
|
119
126
|
}
|
|
120
127
|
/** `'leader'` if this tab runs the node, `'follower'` if another does. */
|
|
@@ -725,11 +732,17 @@ export class MeshSession {
|
|
|
725
732
|
* on close; idempotent, because a page may have closed a stream
|
|
726
733
|
* itself.
|
|
727
734
|
*/
|
|
728
|
-
endStreams() {
|
|
735
|
+
endStreams(staleReason) {
|
|
729
736
|
const open = [...this.streams];
|
|
730
737
|
this.streams.clear();
|
|
731
|
-
for (const stream of open)
|
|
732
|
-
|
|
738
|
+
for (const stream of open) {
|
|
739
|
+
// A leader change retires with the reopenable wording; closing the
|
|
740
|
+
// session is permanent.
|
|
741
|
+
if (staleReason === undefined)
|
|
742
|
+
stream.close();
|
|
743
|
+
else
|
|
744
|
+
stream.retire(staleReason);
|
|
745
|
+
}
|
|
733
746
|
}
|
|
734
747
|
/**
|
|
735
748
|
* Re-type whatever the boundary threw.
|
|
@@ -777,6 +790,17 @@ export async function openSession(options) {
|
|
|
777
790
|
...(options.dbName === undefined ? {} : { dbName: options.dbName }),
|
|
778
791
|
...(options.lockScope === undefined ? {} : { lockScope: options.lockScope }),
|
|
779
792
|
};
|
|
793
|
+
// A custodial identity elects under the same lock name `connect()` takes
|
|
794
|
+
// for it, so mixed connect()/openSession() tabs with one secret cannot
|
|
795
|
+
// both run a node (cubic review of PR #1228). The scope also names the
|
|
796
|
+
// `BroadcastChannel`, and every session tab with that secret derives the
|
|
797
|
+
// same name, so the leader and its followers still meet.
|
|
798
|
+
// `lockIdentity: false` keeps the leaf's own default scope.
|
|
799
|
+
if (request.lockScope === undefined && request.entitySecretHex !== undefined && options.lockIdentity !== false) {
|
|
800
|
+
const shared = await identityLockName(request.entitySecretHex);
|
|
801
|
+
if (shared !== null)
|
|
802
|
+
request.lockScope = shared;
|
|
803
|
+
}
|
|
780
804
|
try {
|
|
781
805
|
return new MeshSession(await module.MeshSession.open(request));
|
|
782
806
|
}
|
package/dist/lobby.d.ts
CHANGED
|
@@ -89,8 +89,33 @@ export declare const MAX_LOBBY_CAPACITY = 256;
|
|
|
89
89
|
/** Characters a code is made of: no 0/O, 1/I/L, so a code survives being read aloud. */
|
|
90
90
|
export declare const LOBBY_CODE_ALPHABET = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
|
|
91
91
|
export declare const LOBBY_CODE_LENGTH = 6;
|
|
92
|
-
/**
|
|
93
|
-
|
|
92
|
+
/**
|
|
93
|
+
* How often a lobby (and a joiner's seek tag) refreshes its announcement.
|
|
94
|
+
* A change of players is announced at once; this is only the lease
|
|
95
|
+
* refresh, well inside the leaf's 300 s announcement TTL.
|
|
96
|
+
*
|
|
97
|
+
* It was 2 s. Every node's re-announcement is flooded through the anchor
|
|
98
|
+
* to every peer, each of which answers every packet with a credit grant,
|
|
99
|
+
* so the load grows with the square of the players: at 64 players on one
|
|
100
|
+
* anchor (sharded-match plan, S0b) a 2 s refresh pinned the host's anchor
|
|
101
|
+
* link at its SCTP advisory (84,667 refused sends), starving every
|
|
102
|
+
* relayed pair and timing out handshakes. At 30 s the same run joined all
|
|
103
|
+
* 64, every pair direct, with no refusals.
|
|
104
|
+
*
|
|
105
|
+
* A node that connects later does not wait for this refresh: the anchor
|
|
106
|
+
* replays the announcements it holds to each session that enrolls, within
|
|
107
|
+
* its game, so an existing lobby is listed at once.
|
|
108
|
+
*
|
|
109
|
+
* A FAILED announcement is not left to this cadence: it is retried after
|
|
110
|
+
* {@link ANNOUNCE_RETRY_MS}, doubling up to {@link ANNOUNCE_RETRY_MAX_MS},
|
|
111
|
+
* until one succeeds. A joiner gives up after 20 s, and a lobby whose
|
|
112
|
+
* first announcement failed must not stay unfindable for 30.
|
|
113
|
+
*/
|
|
114
|
+
export declare const LOBBY_ANNOUNCE_MS = 30000;
|
|
115
|
+
/** The first retry after a failed announcement, ms (lobbies, seek tags, region hosts). */
|
|
116
|
+
export declare const ANNOUNCE_RETRY_MS = 1000;
|
|
117
|
+
/** The longest wait between retries of a failing announcement, ms. */
|
|
118
|
+
export declare const ANNOUNCE_RETRY_MAX_MS = 8000;
|
|
94
119
|
/** A code as typed: case, spaces and dashes forgiven. */
|
|
95
120
|
export declare function normalizeLobbyCode(code: string): string;
|
|
96
121
|
/** What `createLobby` takes: a store's host options, minus the transport, plus the lobby. */
|
|
@@ -173,6 +198,8 @@ export interface JoinLobbyOptions<S extends object, A extends ActionSpec, I exte
|
|
|
173
198
|
* announces goes here. The same option as `createLobby`'s.
|
|
174
199
|
*/
|
|
175
200
|
readonly tags?: readonly string[];
|
|
201
|
+
/** How often the seek tag is refreshed while joined. Default {@link LOBBY_ANNOUNCE_MS}. */
|
|
202
|
+
readonly announceEveryMs?: number;
|
|
176
203
|
}
|
|
177
204
|
/**
|
|
178
205
|
* Join a lobby by code or by listing. Resolves once the host is found
|
package/dist/lobby.js
CHANGED
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
* tags the node should keep announcing as `tags`.
|
|
47
47
|
*/
|
|
48
48
|
import { StoreError } from './store/errors.js';
|
|
49
|
-
import { hostInternals, hostStore, } from './store/host.js';
|
|
49
|
+
import { hostInternals, hostStore, nodeHexOf, } from './store/host.js';
|
|
50
50
|
import { joinStore } from './store/join.js';
|
|
51
51
|
import { hostPlayer } from './store/player.js';
|
|
52
52
|
export class LobbyError extends Error {
|
|
@@ -65,8 +65,33 @@ export const MAX_LOBBY_CAPACITY = 256;
|
|
|
65
65
|
/** Characters a code is made of: no 0/O, 1/I/L, so a code survives being read aloud. */
|
|
66
66
|
export const LOBBY_CODE_ALPHABET = 'ABCDEFGHJKMNPQRSTUVWXYZ23456789';
|
|
67
67
|
export const LOBBY_CODE_LENGTH = 6;
|
|
68
|
-
/**
|
|
69
|
-
|
|
68
|
+
/**
|
|
69
|
+
* How often a lobby (and a joiner's seek tag) refreshes its announcement.
|
|
70
|
+
* A change of players is announced at once; this is only the lease
|
|
71
|
+
* refresh, well inside the leaf's 300 s announcement TTL.
|
|
72
|
+
*
|
|
73
|
+
* It was 2 s. Every node's re-announcement is flooded through the anchor
|
|
74
|
+
* to every peer, each of which answers every packet with a credit grant,
|
|
75
|
+
* so the load grows with the square of the players: at 64 players on one
|
|
76
|
+
* anchor (sharded-match plan, S0b) a 2 s refresh pinned the host's anchor
|
|
77
|
+
* link at its SCTP advisory (84,667 refused sends), starving every
|
|
78
|
+
* relayed pair and timing out handshakes. At 30 s the same run joined all
|
|
79
|
+
* 64, every pair direct, with no refusals.
|
|
80
|
+
*
|
|
81
|
+
* A node that connects later does not wait for this refresh: the anchor
|
|
82
|
+
* replays the announcements it holds to each session that enrolls, within
|
|
83
|
+
* its game, so an existing lobby is listed at once.
|
|
84
|
+
*
|
|
85
|
+
* A FAILED announcement is not left to this cadence: it is retried after
|
|
86
|
+
* {@link ANNOUNCE_RETRY_MS}, doubling up to {@link ANNOUNCE_RETRY_MAX_MS},
|
|
87
|
+
* until one succeeds. A joiner gives up after 20 s, and a lobby whose
|
|
88
|
+
* first announcement failed must not stay unfindable for 30.
|
|
89
|
+
*/
|
|
90
|
+
export const LOBBY_ANNOUNCE_MS = 30_000;
|
|
91
|
+
/** The first retry after a failed announcement, ms (lobbies, seek tags, region hosts). */
|
|
92
|
+
export const ANNOUNCE_RETRY_MS = 1_000;
|
|
93
|
+
/** The longest wait between retries of a failing announcement, ms. */
|
|
94
|
+
export const ANNOUNCE_RETRY_MAX_MS = 8_000;
|
|
70
95
|
/** The frame bound the package's own tests and demo use. */
|
|
71
96
|
const DEFAULT_MAX_EVENT_BYTES = 8104;
|
|
72
97
|
const GAME = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
@@ -215,10 +240,14 @@ function decodeRecord(game, tag) {
|
|
|
215
240
|
return null;
|
|
216
241
|
}
|
|
217
242
|
}
|
|
243
|
+
// Read the id the way every other caller-held id is read (`nodeHexOf`):
|
|
244
|
+
// sixteen hex digits are hex, and anything shorter may be the exact-decimal
|
|
245
|
+
// `peerNode` an event handed the page. Reading every digit run as hex kicked
|
|
246
|
+
// a DIFFERENT id and removed nobody (SDK audit 2026-10-11).
|
|
218
247
|
function hexPeer(peer) {
|
|
219
|
-
const
|
|
220
|
-
if (
|
|
221
|
-
return
|
|
248
|
+
const hex = nodeHexOf(peer);
|
|
249
|
+
if (hex !== null)
|
|
250
|
+
return hex;
|
|
222
251
|
throw new LobbyError('invalid', `not a peer id: ${JSON.stringify(peer)}`);
|
|
223
252
|
}
|
|
224
253
|
/**
|
|
@@ -279,6 +308,10 @@ export async function createLobby(options) {
|
|
|
279
308
|
let closed = false;
|
|
280
309
|
let announcing = null;
|
|
281
310
|
let again = false;
|
|
311
|
+
// A failed announcement is retried on its own short backoff, not at the
|
|
312
|
+
// next lease refresh.
|
|
313
|
+
let retry = null;
|
|
314
|
+
let retryMs = ANNOUNCE_RETRY_MS;
|
|
282
315
|
function currentTags() {
|
|
283
316
|
const list = [...(tags ?? []), lookup];
|
|
284
317
|
if (visibility === 'public') {
|
|
@@ -294,11 +327,25 @@ export async function createLobby(options) {
|
|
|
294
327
|
again = true;
|
|
295
328
|
return;
|
|
296
329
|
}
|
|
330
|
+
if (retry !== null) {
|
|
331
|
+
clearTimeout(retry);
|
|
332
|
+
retry = null;
|
|
333
|
+
}
|
|
297
334
|
announcing = node
|
|
298
335
|
.announce(currentTags())
|
|
336
|
+
.then(() => {
|
|
337
|
+
retryMs = ANNOUNCE_RETRY_MS;
|
|
338
|
+
})
|
|
299
339
|
.catch(() => {
|
|
300
|
-
//
|
|
301
|
-
//
|
|
340
|
+
// Retried shortly; until one lands the lobby is simply not found,
|
|
341
|
+
// which a joiner reports as `not-found`.
|
|
342
|
+
if (closed || retry !== null)
|
|
343
|
+
return;
|
|
344
|
+
retry = setTimeout(() => {
|
|
345
|
+
retry = null;
|
|
346
|
+
announce();
|
|
347
|
+
}, retryMs);
|
|
348
|
+
retryMs = Math.min(retryMs * 2, ANNOUNCE_RETRY_MAX_MS);
|
|
302
349
|
})
|
|
303
350
|
.finally(() => {
|
|
304
351
|
announcing = null;
|
|
@@ -362,6 +409,8 @@ export async function createLobby(options) {
|
|
|
362
409
|
return;
|
|
363
410
|
closed = true;
|
|
364
411
|
clearInterval(timer);
|
|
412
|
+
if (retry !== null)
|
|
413
|
+
clearTimeout(retry);
|
|
365
414
|
stopMembership();
|
|
366
415
|
listeners.clear();
|
|
367
416
|
await me.close();
|
|
@@ -440,15 +489,34 @@ export async function joinLobby(options) {
|
|
|
440
489
|
// them, or one landing after it would put the seek tag back — over a
|
|
441
490
|
// lobby this node created meanwhile.
|
|
442
491
|
const seekingInFlight = new Set();
|
|
492
|
+
// A failed seek announcement is retried on a short backoff: the host
|
|
493
|
+
// cannot let this player in until it holds one, and the reach below
|
|
494
|
+
// gives up at `timeoutMs` — long before the next lease refresh.
|
|
495
|
+
let retry = null;
|
|
496
|
+
let retryMs = ANNOUNCE_RETRY_MS;
|
|
443
497
|
const announce = () => {
|
|
444
498
|
if (stopped !== null)
|
|
445
499
|
return;
|
|
446
|
-
|
|
500
|
+
if (retry !== null) {
|
|
501
|
+
clearTimeout(retry);
|
|
502
|
+
retry = null;
|
|
503
|
+
}
|
|
504
|
+
const sent = node.announce(seeking).then(() => {
|
|
505
|
+
retryMs = ANNOUNCE_RETRY_MS;
|
|
506
|
+
}, () => {
|
|
507
|
+
if (stopped !== null || retry !== null)
|
|
508
|
+
return;
|
|
509
|
+
retry = setTimeout(() => {
|
|
510
|
+
retry = null;
|
|
511
|
+
announce();
|
|
512
|
+
}, retryMs);
|
|
513
|
+
retryMs = Math.min(retryMs * 2, ANNOUNCE_RETRY_MAX_MS);
|
|
514
|
+
});
|
|
447
515
|
seekingInFlight.add(sent);
|
|
448
516
|
void sent.finally(() => seekingInFlight.delete(sent));
|
|
449
517
|
};
|
|
450
518
|
announce();
|
|
451
|
-
const timer = setInterval(announce, LOBBY_ANNOUNCE_MS);
|
|
519
|
+
const timer = setInterval(announce, options.announceEveryMs ?? LOBBY_ANNOUNCE_MS);
|
|
452
520
|
// Withdraws the seek tag, after any seeking announcement still in
|
|
453
521
|
// flight. Settles once the withdrawal has been attempted (a failure is
|
|
454
522
|
// swallowed, as every announcement here is), so a `close()` that awaits
|
|
@@ -459,6 +527,8 @@ export async function joinLobby(options) {
|
|
|
459
527
|
if (stopped !== null)
|
|
460
528
|
return stopped;
|
|
461
529
|
clearInterval(timer);
|
|
530
|
+
if (retry !== null)
|
|
531
|
+
clearTimeout(retry);
|
|
462
532
|
stopped = Promise.all(seekingInFlight).then(() => node.announce(keep)).catch(() => { });
|
|
463
533
|
return stopped;
|
|
464
534
|
};
|
package/dist/net_leaf.d.ts
CHANGED
|
@@ -487,7 +487,7 @@ export class LeafNode {
|
|
|
487
487
|
* The re-attempt owner's ledger, as JSON.
|
|
488
488
|
*
|
|
489
489
|
* `{"armed":<bool>,"online":"<n>","iceFailed":"<n>",
|
|
490
|
-
* "triggers":"<n>","started":"<n>","coalesced":"<n>",
|
|
490
|
+
* "channelClosed":"<n>","triggers":"<n>","started":"<n>","coalesced":"<n>",
|
|
491
491
|
* "notEligible":"<n>","openEpisodes":<n>,"owned":<n>,
|
|
492
492
|
* "last":"<disposition>"|null}`.
|
|
493
493
|
*
|
|
@@ -623,11 +623,10 @@ export class LeafStream {
|
|
|
623
623
|
* **Every registration this stream took is given back**, so
|
|
624
624
|
* repeated open/close leaves [`LeafNode::listener_count`] flat.
|
|
625
625
|
* A callback registered through [`Self::on_message`] lives on
|
|
626
|
-
* the node, not on this object
|
|
627
|
-
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
* alive, for as long as the node lived.
|
|
626
|
+
* the node, not on this object — so a close that removed only
|
|
627
|
+
* the node's stream state left it attached, still invoked and
|
|
628
|
+
* still holding its consumer alive, for as long as the node
|
|
629
|
+
* lived.
|
|
631
630
|
*
|
|
632
631
|
* A refusal here is reported rather than returned: the handle is
|
|
633
632
|
* being discarded either way, and `close` is the one operation
|
|
@@ -675,7 +674,7 @@ export class LeafStream {
|
|
|
675
674
|
* comes from a label or from a publish contract and neither
|
|
676
675
|
* involves the peer, so one label opened to two peers is one id
|
|
677
676
|
* on two sessions — a supported composition. Filtering the
|
|
678
|
-
* node
|
|
677
|
+
* node's events by the id alone made both wrappers
|
|
679
678
|
* accept whichever peer's payload arrived, delivering one
|
|
680
679
|
* peer's bytes into the other peer's inbox; a page that echoes
|
|
681
680
|
* then amplifies it. The incarnation rides the event as
|
|
@@ -689,10 +688,9 @@ export class LeafStream {
|
|
|
689
688
|
* self` — so the advertised echo trapped instead of sending.
|
|
690
689
|
*
|
|
691
690
|
* **Returns the token that cancels the registration**, decimal.
|
|
692
|
-
* The
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
* for every event it produces — which is what repeated
|
|
691
|
+
* The callback is registered on the node, so a registration
|
|
692
|
+
* nothing names is retained for the node's whole life and keeps
|
|
693
|
+
* being invoked for its stream's data — which is what repeated
|
|
696
694
|
* open/close accumulated before the token existed.
|
|
697
695
|
* [`Self::close`] gives back every token this stream took, so
|
|
698
696
|
* an ordinary consumer never has to; [`Self::remove_listener`]
|
|
@@ -1453,16 +1451,16 @@ export interface InitOutput {
|
|
|
1453
1451
|
readonly proxystream_send: (a: number, b: number) => number;
|
|
1454
1452
|
readonly proxystream_stream_id_hex: (a: number, b: number) => void;
|
|
1455
1453
|
readonly start: () => void;
|
|
1456
|
-
readonly
|
|
1457
|
-
readonly
|
|
1458
|
-
readonly
|
|
1459
|
-
readonly
|
|
1460
|
-
readonly
|
|
1461
|
-
readonly
|
|
1462
|
-
readonly
|
|
1463
|
-
readonly
|
|
1464
|
-
readonly
|
|
1465
|
-
readonly
|
|
1454
|
+
readonly __wasm_bindgen_func_elem_6529: (a: number, b: number, c: number, d: number) => void;
|
|
1455
|
+
readonly __wasm_bindgen_func_elem_6531: (a: number, b: number, c: number, d: number) => void;
|
|
1456
|
+
readonly __wasm_bindgen_func_elem_2373: (a: number, b: number, c: number) => number;
|
|
1457
|
+
readonly __wasm_bindgen_func_elem_2374: (a: number, b: number, c: number) => void;
|
|
1458
|
+
readonly __wasm_bindgen_func_elem_2374_112: (a: number, b: number, c: number) => void;
|
|
1459
|
+
readonly __wasm_bindgen_func_elem_2374_113: (a: number, b: number, c: number) => void;
|
|
1460
|
+
readonly __wasm_bindgen_func_elem_2374_114: (a: number, b: number, c: number) => void;
|
|
1461
|
+
readonly __wasm_bindgen_func_elem_2374_115: (a: number, b: number, c: number) => void;
|
|
1462
|
+
readonly __wasm_bindgen_func_elem_2374_116: (a: number, b: number, c: number) => void;
|
|
1463
|
+
readonly __wasm_bindgen_func_elem_2374_117: (a: number, b: number, c: number) => void;
|
|
1466
1464
|
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
1467
1465
|
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
1468
1466
|
readonly __wbindgen_export3: (a: number) => void;
|
package/dist/net_leaf.js
CHANGED
|
@@ -848,7 +848,7 @@ export class LeafNode {
|
|
|
848
848
|
* The re-attempt owner's ledger, as JSON.
|
|
849
849
|
*
|
|
850
850
|
* `{"armed":<bool>,"online":"<n>","iceFailed":"<n>",
|
|
851
|
-
* "triggers":"<n>","started":"<n>","coalesced":"<n>",
|
|
851
|
+
* "channelClosed":"<n>","triggers":"<n>","started":"<n>","coalesced":"<n>",
|
|
852
852
|
* "notEligible":"<n>","openEpisodes":<n>,"owned":<n>,
|
|
853
853
|
* "last":"<disposition>"|null}`.
|
|
854
854
|
*
|
|
@@ -1150,11 +1150,10 @@ export class LeafStream {
|
|
|
1150
1150
|
* **Every registration this stream took is given back**, so
|
|
1151
1151
|
* repeated open/close leaves [`LeafNode::listener_count`] flat.
|
|
1152
1152
|
* A callback registered through [`Self::on_message`] lives on
|
|
1153
|
-
* the node, not on this object
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1157
|
-
* alive, for as long as the node lived.
|
|
1153
|
+
* the node, not on this object — so a close that removed only
|
|
1154
|
+
* the node's stream state left it attached, still invoked and
|
|
1155
|
+
* still holding its consumer alive, for as long as the node
|
|
1156
|
+
* lived.
|
|
1158
1157
|
*
|
|
1159
1158
|
* A refusal here is reported rather than returned: the handle is
|
|
1160
1159
|
* being discarded either way, and `close` is the one operation
|
|
@@ -1224,7 +1223,7 @@ export class LeafStream {
|
|
|
1224
1223
|
* comes from a label or from a publish contract and neither
|
|
1225
1224
|
* involves the peer, so one label opened to two peers is one id
|
|
1226
1225
|
* on two sessions — a supported composition. Filtering the
|
|
1227
|
-
* node
|
|
1226
|
+
* node's events by the id alone made both wrappers
|
|
1228
1227
|
* accept whichever peer's payload arrived, delivering one
|
|
1229
1228
|
* peer's bytes into the other peer's inbox; a page that echoes
|
|
1230
1229
|
* then amplifies it. The incarnation rides the event as
|
|
@@ -1238,10 +1237,9 @@ export class LeafStream {
|
|
|
1238
1237
|
* self` — so the advertised echo trapped instead of sending.
|
|
1239
1238
|
*
|
|
1240
1239
|
* **Returns the token that cancels the registration**, decimal.
|
|
1241
|
-
* The
|
|
1242
|
-
*
|
|
1243
|
-
*
|
|
1244
|
-
* for every event it produces — which is what repeated
|
|
1240
|
+
* The callback is registered on the node, so a registration
|
|
1241
|
+
* nothing names is retained for the node's whole life and keeps
|
|
1242
|
+
* being invoked for its stream's data — which is what repeated
|
|
1245
1243
|
* open/close accumulated before the token existed.
|
|
1246
1244
|
* [`Self::close`] gives back every token this stream took, so
|
|
1247
1245
|
* an ordinary consumer never has to; [`Self::remove_listener`]
|
|
@@ -2722,7 +2720,7 @@ function __wbg_get_imports() {
|
|
|
2722
2720
|
const ret = getObject(arg0).error;
|
|
2723
2721
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
2724
2722
|
}, arguments); },
|
|
2725
|
-
|
|
2723
|
+
__wbg_error_def25afd803510fb: function(arg0, arg1) {
|
|
2726
2724
|
console.error(getStringFromWasm0(arg0, arg1));
|
|
2727
2725
|
},
|
|
2728
2726
|
__wbg_fetch_4178962c570137ca: function(arg0, arg1, arg2) {
|
|
@@ -2914,7 +2912,7 @@ function __wbg_get_imports() {
|
|
|
2914
2912
|
const a = state0.a;
|
|
2915
2913
|
state0.a = 0;
|
|
2916
2914
|
try {
|
|
2917
|
-
return
|
|
2915
|
+
return __wasm_bindgen_func_elem_6531(a, state0.b, arg0, arg1);
|
|
2918
2916
|
} finally {
|
|
2919
2917
|
state0.a = a;
|
|
2920
2918
|
}
|
|
@@ -2956,7 +2954,7 @@ function __wbg_get_imports() {
|
|
|
2956
2954
|
const a = state0.a;
|
|
2957
2955
|
state0.a = 0;
|
|
2958
2956
|
try {
|
|
2959
|
-
return
|
|
2957
|
+
return __wasm_bindgen_func_elem_6531(a, state0.b, arg0, arg1);
|
|
2960
2958
|
} finally {
|
|
2961
2959
|
state0.a = a;
|
|
2962
2960
|
}
|
|
@@ -3266,47 +3264,47 @@ function __wbg_get_imports() {
|
|
|
3266
3264
|
},
|
|
3267
3265
|
__wbindgen_generic_0000000000000001: function(arg0, arg1) {
|
|
3268
3266
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 34, ret: Externref, inner_ret: Some(Externref) }, mutable: true }) -> Externref`.
|
|
3269
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3267
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2373);
|
|
3270
3268
|
return addHeapObject(ret);
|
|
3271
3269
|
},
|
|
3272
3270
|
__wbindgen_generic_0000000000000002: function(arg0, arg1) {
|
|
3273
3271
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3274
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3272
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2374);
|
|
3275
3273
|
return addHeapObject(ret);
|
|
3276
3274
|
},
|
|
3277
3275
|
__wbindgen_generic_0000000000000003: function(arg0, arg1) {
|
|
3278
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx:
|
|
3279
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3276
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 866, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
3277
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_6529);
|
|
3280
3278
|
return addHeapObject(ret);
|
|
3281
3279
|
},
|
|
3282
3280
|
__wbindgen_generic_0000000000000004: function(arg0, arg1) {
|
|
3283
3281
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("CloseEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3284
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3282
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2374_112);
|
|
3285
3283
|
return addHeapObject(ret);
|
|
3286
3284
|
},
|
|
3287
3285
|
__wbindgen_generic_0000000000000005: function(arg0, arg1) {
|
|
3288
3286
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3289
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3287
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2374_113);
|
|
3290
3288
|
return addHeapObject(ret);
|
|
3291
3289
|
},
|
|
3292
3290
|
__wbindgen_generic_0000000000000006: function(arg0, arg1) {
|
|
3293
3291
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("MessageEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3294
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3292
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2374_114);
|
|
3295
3293
|
return addHeapObject(ret);
|
|
3296
3294
|
},
|
|
3297
3295
|
__wbindgen_generic_0000000000000007: function(arg0, arg1) {
|
|
3298
3296
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCDataChannelEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3299
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3297
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2374_115);
|
|
3300
3298
|
return addHeapObject(ret);
|
|
3301
3299
|
},
|
|
3302
3300
|
__wbindgen_generic_0000000000000008: function(arg0, arg1) {
|
|
3303
3301
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCPeerConnectionIceErrorEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3304
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3302
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2374_116);
|
|
3305
3303
|
return addHeapObject(ret);
|
|
3306
3304
|
},
|
|
3307
3305
|
__wbindgen_generic_0000000000000009: function(arg0, arg1) {
|
|
3308
3306
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCPeerConnectionIceEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3309
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3307
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2374_117);
|
|
3310
3308
|
return addHeapObject(ret);
|
|
3311
3309
|
},
|
|
3312
3310
|
__wbindgen_generic_000000000000000a: function(arg0) {
|
|
@@ -3333,47 +3331,47 @@ function __wbg_get_imports() {
|
|
|
3333
3331
|
};
|
|
3334
3332
|
}
|
|
3335
3333
|
|
|
3336
|
-
function
|
|
3337
|
-
wasm.
|
|
3334
|
+
function __wasm_bindgen_func_elem_2374(arg0, arg1, arg2) {
|
|
3335
|
+
wasm.__wasm_bindgen_func_elem_2374(arg0, arg1, addHeapObject(arg2));
|
|
3338
3336
|
}
|
|
3339
3337
|
|
|
3340
|
-
function
|
|
3341
|
-
wasm.
|
|
3338
|
+
function __wasm_bindgen_func_elem_2374_112(arg0, arg1, arg2) {
|
|
3339
|
+
wasm.__wasm_bindgen_func_elem_2374_112(arg0, arg1, addHeapObject(arg2));
|
|
3342
3340
|
}
|
|
3343
3341
|
|
|
3344
|
-
function
|
|
3345
|
-
wasm.
|
|
3342
|
+
function __wasm_bindgen_func_elem_2374_113(arg0, arg1, arg2) {
|
|
3343
|
+
wasm.__wasm_bindgen_func_elem_2374_113(arg0, arg1, addHeapObject(arg2));
|
|
3346
3344
|
}
|
|
3347
3345
|
|
|
3348
|
-
function
|
|
3349
|
-
wasm.
|
|
3346
|
+
function __wasm_bindgen_func_elem_2374_114(arg0, arg1, arg2) {
|
|
3347
|
+
wasm.__wasm_bindgen_func_elem_2374_114(arg0, arg1, addHeapObject(arg2));
|
|
3350
3348
|
}
|
|
3351
3349
|
|
|
3352
|
-
function
|
|
3353
|
-
wasm.
|
|
3350
|
+
function __wasm_bindgen_func_elem_2374_115(arg0, arg1, arg2) {
|
|
3351
|
+
wasm.__wasm_bindgen_func_elem_2374_115(arg0, arg1, addHeapObject(arg2));
|
|
3354
3352
|
}
|
|
3355
3353
|
|
|
3356
|
-
function
|
|
3357
|
-
wasm.
|
|
3354
|
+
function __wasm_bindgen_func_elem_2374_116(arg0, arg1, arg2) {
|
|
3355
|
+
wasm.__wasm_bindgen_func_elem_2374_116(arg0, arg1, addHeapObject(arg2));
|
|
3358
3356
|
}
|
|
3359
3357
|
|
|
3360
|
-
function
|
|
3361
|
-
wasm.
|
|
3358
|
+
function __wasm_bindgen_func_elem_2374_117(arg0, arg1, arg2) {
|
|
3359
|
+
wasm.__wasm_bindgen_func_elem_2374_117(arg0, arg1, addHeapObject(arg2));
|
|
3362
3360
|
}
|
|
3363
3361
|
|
|
3364
|
-
function
|
|
3365
|
-
const ret = wasm.
|
|
3362
|
+
function __wasm_bindgen_func_elem_2373(arg0, arg1, arg2) {
|
|
3363
|
+
const ret = wasm.__wasm_bindgen_func_elem_2373(arg0, arg1, addHeapObject(arg2));
|
|
3366
3364
|
return takeObject(ret);
|
|
3367
3365
|
}
|
|
3368
3366
|
|
|
3369
|
-
function
|
|
3370
|
-
wasm.
|
|
3367
|
+
function __wasm_bindgen_func_elem_6531(arg0, arg1, arg2, arg3) {
|
|
3368
|
+
wasm.__wasm_bindgen_func_elem_6531(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
|
|
3371
3369
|
}
|
|
3372
3370
|
|
|
3373
|
-
function
|
|
3371
|
+
function __wasm_bindgen_func_elem_6529(arg0, arg1, arg2) {
|
|
3374
3372
|
try {
|
|
3375
3373
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
3376
|
-
wasm.
|
|
3374
|
+
wasm.__wasm_bindgen_func_elem_6529(retptr, arg0, arg1, addHeapObject(arg2));
|
|
3377
3375
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
3378
3376
|
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
3379
3377
|
if (r1) {
|
package/dist/net_leaf_bg.wasm
CHANGED
|
Binary file
|
|
@@ -119,16 +119,16 @@ export const proxystream_peer_node_hex: (a: number, b: number) => void;
|
|
|
119
119
|
export const proxystream_send: (a: number, b: number) => number;
|
|
120
120
|
export const proxystream_stream_id_hex: (a: number, b: number) => void;
|
|
121
121
|
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
|
|
122
|
+
export const __wasm_bindgen_func_elem_6529: (a: number, b: number, c: number, d: number) => void;
|
|
123
|
+
export const __wasm_bindgen_func_elem_6531: (a: number, b: number, c: number, d: number) => void;
|
|
124
|
+
export const __wasm_bindgen_func_elem_2373: (a: number, b: number, c: number) => number;
|
|
125
|
+
export const __wasm_bindgen_func_elem_2374: (a: number, b: number, c: number) => void;
|
|
126
|
+
export const __wasm_bindgen_func_elem_2374_112: (a: number, b: number, c: number) => void;
|
|
127
|
+
export const __wasm_bindgen_func_elem_2374_113: (a: number, b: number, c: number) => void;
|
|
128
|
+
export const __wasm_bindgen_func_elem_2374_114: (a: number, b: number, c: number) => void;
|
|
129
|
+
export const __wasm_bindgen_func_elem_2374_115: (a: number, b: number, c: number) => void;
|
|
130
|
+
export const __wasm_bindgen_func_elem_2374_116: (a: number, b: number, c: number) => void;
|
|
131
|
+
export const __wasm_bindgen_func_elem_2374_117: (a: number, b: number, c: number) => void;
|
|
132
132
|
export const __wbindgen_export: (a: number, b: number) => number;
|
|
133
133
|
export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
134
134
|
export const __wbindgen_export3: (a: number) => void;
|