@irtio/runtime 3.1.1 → 4.0.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/{chunk-XPRLQCNF.js → chunk-G2XKCXRO.js} +1 -1
- package/dist/{chunk-2L3RGWXM.js → chunk-S4D472RL.js} +56 -16
- package/dist/{contract-BoCNAPZT.d.ts → contract-CpBkqkn7.d.ts} +13 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{room-CGbiPxi3.d.ts → room-B9h9dc4e.d.ts} +9 -1
- package/dist/test/index.d.ts +16 -3
- package/dist/test/index.js +21 -2
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/index.js +2 -2
- package/package.json +4 -4
|
@@ -578,12 +578,12 @@ import {
|
|
|
578
578
|
SERVER_OWNER as SERVER_OWNER2,
|
|
579
579
|
decodeFields,
|
|
580
580
|
encodeFields,
|
|
581
|
-
validateValue
|
|
581
|
+
validateValue as validateValue2
|
|
582
582
|
} from "@irtio/schema";
|
|
583
583
|
import { DenyError } from "@irtio/server";
|
|
584
584
|
|
|
585
585
|
// src/core/ownership.ts
|
|
586
|
-
import { SERVER_OWNER, defaultRecord } from "@irtio/schema";
|
|
586
|
+
import { SERVER_OWNER, cloneValue, defaultRecord, validateValue } from "@irtio/schema";
|
|
587
587
|
var HOLD_ACTIONS = /* @__PURE__ */ new Set([
|
|
588
588
|
"release",
|
|
589
589
|
"nearest",
|
|
@@ -735,7 +735,7 @@ function nearestConnected(core, collection, id) {
|
|
|
735
735
|
}
|
|
736
736
|
return best;
|
|
737
737
|
}
|
|
738
|
-
function addPerPlayerRecords(core, clientId) {
|
|
738
|
+
function addPerPlayerRecords(core, clientId, seeds) {
|
|
739
739
|
for (const c of core.ext.collections) {
|
|
740
740
|
if (c.kind !== "entity" || !c.perPlayer) continue;
|
|
741
741
|
const coll = plainEntity(core.plain, c.name);
|
|
@@ -746,7 +746,23 @@ function addPerPlayerRecords(core, clientId) {
|
|
|
746
746
|
continue;
|
|
747
747
|
}
|
|
748
748
|
try {
|
|
749
|
-
|
|
749
|
+
const record = defaultRecord(c);
|
|
750
|
+
const seed = seeds?.get(c.name);
|
|
751
|
+
if (seed && c.persist) {
|
|
752
|
+
for (const field of c.persist) {
|
|
753
|
+
const value = seed[field];
|
|
754
|
+
if (value === void 0) continue;
|
|
755
|
+
const desc = c.fields[c.fieldIndex.get(field) ?? -1];
|
|
756
|
+
if (!desc) continue;
|
|
757
|
+
const err = validateValue(desc.type, value, `${c.name}.${field}`);
|
|
758
|
+
if (err) {
|
|
759
|
+
core.log("warn", `persisted ${c.name}.${field} for ${clientId} dropped: ${err}`);
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
record[field] = cloneValue(value);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
trackedEntity(core, c.name).add(clientId, record, { owner: clientId });
|
|
750
766
|
} catch (err) {
|
|
751
767
|
core.log("error", `perPlayer add on ${c.name} failed for ${clientId}:`, err);
|
|
752
768
|
}
|
|
@@ -942,7 +958,7 @@ function handleCall(core, clientId, payload) {
|
|
|
942
958
|
return true;
|
|
943
959
|
}
|
|
944
960
|
for (const f of desc.params) {
|
|
945
|
-
const problem =
|
|
961
|
+
const problem = validateValue2(f.type, params[f.name], f.name);
|
|
946
962
|
if (problem) {
|
|
947
963
|
traceEarly?.(errorText("E_RPC_BAD_PARAMS", problem));
|
|
948
964
|
sendReply(core, clientId, call.reqId, null, errorText("E_RPC_BAD_PARAMS", problem));
|
|
@@ -1353,7 +1369,7 @@ function rejectAllHostCalls(core, reason) {
|
|
|
1353
1369
|
// src/core/writes.ts
|
|
1354
1370
|
import {
|
|
1355
1371
|
SERVER_OWNER as SERVER_OWNER3,
|
|
1356
|
-
cloneValue,
|
|
1372
|
+
cloneValue as cloneValue2,
|
|
1357
1373
|
decodeDelta,
|
|
1358
1374
|
defaultValue,
|
|
1359
1375
|
encodeDelta as encodeDelta2,
|
|
@@ -1407,7 +1423,7 @@ function applyMaskedPatch(fields, target, patch, mask) {
|
|
|
1407
1423
|
continue;
|
|
1408
1424
|
}
|
|
1409
1425
|
}
|
|
1410
|
-
target[f.name] =
|
|
1426
|
+
target[f.name] = cloneValue2(value);
|
|
1411
1427
|
}
|
|
1412
1428
|
}
|
|
1413
1429
|
function assignChanged(desc, target, key, prev, next) {
|
|
@@ -1532,17 +1548,17 @@ function applyOp(core, clientId, c, op) {
|
|
|
1532
1548
|
const fields = fieldList(c);
|
|
1533
1549
|
const growth = updateGrowth(c, leafPaths(fields, op.mask));
|
|
1534
1550
|
if (growth > 0 && !admitGrowth(core, clientId, growth)) return;
|
|
1535
|
-
const prev =
|
|
1536
|
-
const next =
|
|
1551
|
+
const prev = cloneValue2(current);
|
|
1552
|
+
const next = cloneValue2(current);
|
|
1537
1553
|
applyMaskedPatch(fields, next, op.patch, op.mask);
|
|
1538
|
-
const requested =
|
|
1554
|
+
const requested = cloneValue2(next);
|
|
1539
1555
|
if (c.physics || c.serverFields) {
|
|
1540
1556
|
const refused2 = [];
|
|
1541
1557
|
for (const leaf of leafPaths(fields, op.mask)) {
|
|
1542
1558
|
const field = leaf.names[0];
|
|
1543
1559
|
const why = ownerMayNotWrite(c, field);
|
|
1544
1560
|
if (why === void 0) continue;
|
|
1545
|
-
next[field] =
|
|
1561
|
+
next[field] = cloneValue2(prev[field]);
|
|
1546
1562
|
refused2.push(why);
|
|
1547
1563
|
}
|
|
1548
1564
|
if (refused2.length > 0) {
|
|
@@ -1580,7 +1596,7 @@ function applyOp(core, clientId, c, op) {
|
|
|
1580
1596
|
map = /* @__PURE__ */ new Map();
|
|
1581
1597
|
entry.accepted.set(key, map);
|
|
1582
1598
|
}
|
|
1583
|
-
for (const leaf of written) map.set(leafKey(leaf),
|
|
1599
|
+
for (const leaf of written) map.set(leafKey(leaf), cloneValue2(valueAt(result, leaf.names)));
|
|
1584
1600
|
}
|
|
1585
1601
|
const corrected = written.filter(
|
|
1586
1602
|
(leaf) => !deepEqual(valueAt(result, leaf.names), valueAt(requested, leaf.names))
|
|
@@ -3774,7 +3790,7 @@ import {
|
|
|
3774
3790
|
withBuiltins as withBuiltins2
|
|
3775
3791
|
} from "@irtio/protocol";
|
|
3776
3792
|
import {
|
|
3777
|
-
cloneValue as
|
|
3793
|
+
cloneValue as cloneValue3,
|
|
3778
3794
|
createDirtySet as createDirtySet3,
|
|
3779
3795
|
createState,
|
|
3780
3796
|
decodeSnapshot as decodeSnapshot3,
|
|
@@ -6141,7 +6157,7 @@ function ownJoinCapture(plain, name, added, clientId) {
|
|
|
6141
6157
|
for (const id of added) {
|
|
6142
6158
|
const owner = coll.ownerOf(id);
|
|
6143
6159
|
if (name === PRESENCE_COLLECTION ? id !== clientId : owner !== clientId) continue;
|
|
6144
|
-
(mine ??= /* @__PURE__ */ new Map()).set(id, { value:
|
|
6160
|
+
(mine ??= /* @__PURE__ */ new Map()).set(id, { value: cloneValue3(coll.get(id)), owner });
|
|
6145
6161
|
}
|
|
6146
6162
|
return mine;
|
|
6147
6163
|
}
|
|
@@ -6905,7 +6921,7 @@ var RoomCore = class _RoomCore {
|
|
|
6905
6921
|
this.clients.set(clientId, entry);
|
|
6906
6922
|
this.invalidateClients();
|
|
6907
6923
|
reclaimHolds(this.internals, clientId, entry.playerId);
|
|
6908
|
-
addPerPlayerRecords(this.internals, clientId);
|
|
6924
|
+
addPerPlayerRecords(this.internals, clientId, options.persisted);
|
|
6909
6925
|
const onJoin = this.definition.config.onJoin;
|
|
6910
6926
|
if (onJoin) {
|
|
6911
6927
|
const ctx = this.ctxFor(clientId, reconnecting);
|
|
@@ -6928,7 +6944,7 @@ var RoomCore = class _RoomCore {
|
|
|
6928
6944
|
const captured = mine ?? /* @__PURE__ */ new Map();
|
|
6929
6945
|
for (const id of cd.added) {
|
|
6930
6946
|
if (!visible.has(id) || captured.has(id)) continue;
|
|
6931
|
-
captured.set(id, { value:
|
|
6947
|
+
captured.set(id, { value: cloneValue3(coll.get(id)), owner: coll.ownerOf(id) });
|
|
6932
6948
|
}
|
|
6933
6949
|
if (captured.size > 0) pending.set(name2, captured);
|
|
6934
6950
|
} else if (mine) pending.set(name2, mine);
|
|
@@ -6969,6 +6985,30 @@ var RoomCore = class _RoomCore {
|
|
|
6969
6985
|
this.invalidateClients();
|
|
6970
6986
|
this.eventFlush();
|
|
6971
6987
|
}
|
|
6988
|
+
// ---- M8 proposal 13: identity-keyed player persistence ----
|
|
6989
|
+
/**
|
|
6990
|
+
* The current values of every `persist` field this client's `perPlayer` records hold, or
|
|
6991
|
+
* `undefined` when the schema declares none and when the client has no records.
|
|
6992
|
+
*
|
|
6993
|
+
* Read by the relay host just before `leave`, which is the last moment the records exist: the
|
|
6994
|
+
* declared leave rules remove a `perPlayer` record.
|
|
6995
|
+
*/
|
|
6996
|
+
persistedFieldsOf(clientId) {
|
|
6997
|
+
let out;
|
|
6998
|
+
for (const c of this.ext.collections) {
|
|
6999
|
+
if (c.kind !== "entity" || !c.perPlayer || !c.persist || c.persist.length === 0) continue;
|
|
7000
|
+
const record = plainEntity(this.plain, c.name).get(clientId);
|
|
7001
|
+
if (!record) continue;
|
|
7002
|
+
const picked = {};
|
|
7003
|
+
for (const field of c.persist) {
|
|
7004
|
+
const value = record[field];
|
|
7005
|
+
if (value !== void 0) picked[field] = cloneValue3(value);
|
|
7006
|
+
}
|
|
7007
|
+
if (Object.keys(picked).length > 0) (out ??= /* @__PURE__ */ new Map()).set(c.name, picked);
|
|
7008
|
+
}
|
|
7009
|
+
return out;
|
|
7010
|
+
}
|
|
7011
|
+
// ---- end M8 proposal 13 ----
|
|
6972
7012
|
markDisconnected(clientId) {
|
|
6973
7013
|
const entry = this.clients.get(clientId);
|
|
6974
7014
|
if (!entry) {
|
|
@@ -552,6 +552,12 @@ interface JoinOptions {
|
|
|
552
552
|
* therefore the only thing `room.ban` can key a cooldown on honestly.
|
|
553
553
|
*/
|
|
554
554
|
readonly subject?: string;
|
|
555
|
+
/**
|
|
556
|
+
* Seed values for this client's fresh `perPlayer` records, from the relay host's persistence
|
|
557
|
+
* blob: collection name → partial field values. Applied only where a new record is created; a
|
|
558
|
+
* reclaimed or reconnected record keeps what it has.
|
|
559
|
+
*/
|
|
560
|
+
readonly persisted?: ReadonlyMap<string, Readonly<Record<string, unknown>>>;
|
|
555
561
|
}
|
|
556
562
|
interface JoinResult {
|
|
557
563
|
readonly tick: number;
|
|
@@ -657,6 +663,13 @@ interface RoomCoreApi<S extends AnySchema = AnySchema> {
|
|
|
657
663
|
leave(clientId: string, reason: LeaveReason): void;
|
|
658
664
|
/** Grace window opened by the host: presence `connected = false`; frames are no longer sent. */
|
|
659
665
|
markDisconnected(clientId: string): void;
|
|
666
|
+
/**
|
|
667
|
+
* M8 proposal 13: the current values of every `persist` field this client's `perPlayer` records
|
|
668
|
+
* hold, or `undefined` when the schema declares none and when the client has no records.
|
|
669
|
+
*
|
|
670
|
+
* Read by the relay host just before `leave`, to write the player's persistence blob.
|
|
671
|
+
*/
|
|
672
|
+
persistedFieldsOf(clientId: string): ReadonlyMap<string, Record<string, unknown>> | undefined;
|
|
660
673
|
/** One inbound protocol frame (`WRITE` | `CALL` | `REPLY` | `MSG`). Anything else → host.kick(E_BAD_FRAME). */
|
|
661
674
|
receive(clientId: string, frame: Uint8Array): void;
|
|
662
675
|
/** Full state + tick + rng for hibernation. Runs `onSleep`. Clears timers. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as AdmissionError, D as DEFAULT_RECORDS_PER_COLLECTION, a as DEFAULT_TIMELINE_MAX_RECORDS, b as DEFAULT_TIMELINE_MAX_TICKS, E as EVENT_RING_SIZE, H as HOST_CALL_TIMEOUT_MS, c as HostCall, d as HostCallResult, J as JoinOptions, e as JoinResult, L as LogLevel, P as PHYSICS_STEP_EMA_ALPHA, R as RELAY_RECORDS_PER_COLLECTION, f as RELAY_STATE_BYTES, g as RELAY_WRITES_PER_SECOND, h as RELAY_WRITE_CAPS, i as RPC_TRACE_SIZE, j as RPC_TRACE_SUMMARY_MAX, k as RoomCoreApi, l as RoomCoreOptions, m as RoomEvent, n as RoomEventKind, o as RoomFullError, p as RoomHost, q as RoomInspection, r as RoomStats, s as RpcOutcome, t as RpcTraceDump, u as RpcTraceEntry, v as RpcTraceRing, S as StampLag, T as TimelineDump, w as TimelineFrame, x as TimelineRecorder, y as TimelineRecorderOptions, W as WriteCaps, z as inspectState, B as summarizeRpcResult } from './contract-
|
|
2
|
-
export { C as CRASH_AFTER_THROWS, M as MAX_CATCHUP, a as MatterBodyRecord, b as MatterSection, c as Mulberry32, P as PhysicsEngineTag, d as PhysicsSection, R as RoomCore, e as decodeMatterBodies, f as decodeMatterSectionEnvelope, g as decodePhysicsSection, h as decodeRapier2dSectionEnvelope, i as encodeMatterBodies, j as encodeMatterSectionEnvelope, k as encodePhysicsSection, l as encodeRapier2dSectionEnvelope, m as initMatter, n as initPhysics, o as initRapier2d, p as loadedMatter, q as loadedPhysics, r as loadedRapier2d, s as physicsSectionEngine, t as resetMatterForTests, u as resetPhysicsForTests, v as resetRapier2dForTests } from './room-
|
|
1
|
+
export { A as AdmissionError, D as DEFAULT_RECORDS_PER_COLLECTION, a as DEFAULT_TIMELINE_MAX_RECORDS, b as DEFAULT_TIMELINE_MAX_TICKS, E as EVENT_RING_SIZE, H as HOST_CALL_TIMEOUT_MS, c as HostCall, d as HostCallResult, J as JoinOptions, e as JoinResult, L as LogLevel, P as PHYSICS_STEP_EMA_ALPHA, R as RELAY_RECORDS_PER_COLLECTION, f as RELAY_STATE_BYTES, g as RELAY_WRITES_PER_SECOND, h as RELAY_WRITE_CAPS, i as RPC_TRACE_SIZE, j as RPC_TRACE_SUMMARY_MAX, k as RoomCoreApi, l as RoomCoreOptions, m as RoomEvent, n as RoomEventKind, o as RoomFullError, p as RoomHost, q as RoomInspection, r as RoomStats, s as RpcOutcome, t as RpcTraceDump, u as RpcTraceEntry, v as RpcTraceRing, S as StampLag, T as TimelineDump, w as TimelineFrame, x as TimelineRecorder, y as TimelineRecorderOptions, W as WriteCaps, z as inspectState, B as summarizeRpcResult } from './contract-CpBkqkn7.js';
|
|
2
|
+
export { C as CRASH_AFTER_THROWS, M as MAX_CATCHUP, a as MatterBodyRecord, b as MatterSection, c as Mulberry32, P as PhysicsEngineTag, d as PhysicsSection, R as RoomCore, e as decodeMatterBodies, f as decodeMatterSectionEnvelope, g as decodePhysicsSection, h as decodeRapier2dSectionEnvelope, i as encodeMatterBodies, j as encodeMatterSectionEnvelope, k as encodePhysicsSection, l as encodeRapier2dSectionEnvelope, m as initMatter, n as initPhysics, o as initRapier2d, p as loadedMatter, q as loadedPhysics, r as loadedRapier2d, s as physicsSectionEngine, t as resetMatterForTests, u as resetPhysicsForTests, v as resetRapier2dForTests } from './room-B9h9dc4e.js';
|
|
3
3
|
import { CollectionDesc, AnySchema, PlainState, DirtySet } from '@irtio/schema';
|
|
4
4
|
import '@irtio/protocol';
|
|
5
5
|
import '@irtio/server';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
fromMigrationState,
|
|
3
3
|
migrateSnapshot,
|
|
4
4
|
toMigrationState
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-G2XKCXRO.js";
|
|
6
6
|
import {
|
|
7
7
|
AdmissionError,
|
|
8
8
|
CRASH_AFTER_THROWS,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
visibleNames,
|
|
59
59
|
visibleTo,
|
|
60
60
|
writeHibernationBlob
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-S4D472RL.js";
|
|
62
62
|
export {
|
|
63
63
|
AdmissionError,
|
|
64
64
|
CRASH_AFTER_THROWS,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PlatformNotice, AttributeOptions, ProfileSnapshot } from '@irtio/protocol';
|
|
2
2
|
import { DirtySet, AnySchema, PlainState, Tracked, State } from '@irtio/schema';
|
|
3
3
|
import { RoomDefinition, RoomMode, Room, RewindView, Ctx, MatterModule, MatterEngine, MatterBody, RapierModule, RapierWorld, RapierRigidBody, Rapier2dModule, Rapier2dWorld, Rapier2dRigidBody, ResolvedRoomConfig, LeaveReason } from '@irtio/server';
|
|
4
|
-
import { p as RoomHost, r as RoomStats, u as RpcTraceEntry, L as LogLevel, k as RoomCoreApi, l as RoomCoreOptions, n as RoomEventKind, y as TimelineRecorderOptions, T as TimelineDump, t as RpcTraceDump, q as RoomInspection, J as JoinOptions, e as JoinResult, d as HostCallResult } from './contract-
|
|
4
|
+
import { p as RoomHost, r as RoomStats, u as RpcTraceEntry, L as LogLevel, k as RoomCoreApi, l as RoomCoreOptions, n as RoomEventKind, y as TimelineRecorderOptions, T as TimelineDump, t as RpcTraceDump, q as RoomInspection, J as JoinOptions, e as JoinResult, d as HostCallResult } from './contract-CpBkqkn7.js';
|
|
5
5
|
|
|
6
6
|
declare class Mulberry32 {
|
|
7
7
|
/** Current internal state (u32). Survives hibernation. */
|
|
@@ -1152,6 +1152,14 @@ declare class RoomCore<S extends AnySchema = AnySchema> implements RoomCoreApi<S
|
|
|
1152
1152
|
/** Event mode only: presence/lifecycle changes are their own event. No-op in tick mode. */
|
|
1153
1153
|
private eventFlush;
|
|
1154
1154
|
leave(clientId: string, reason: LeaveReason): void;
|
|
1155
|
+
/**
|
|
1156
|
+
* The current values of every `persist` field this client's `perPlayer` records hold, or
|
|
1157
|
+
* `undefined` when the schema declares none and when the client has no records.
|
|
1158
|
+
*
|
|
1159
|
+
* Read by the relay host just before `leave`, which is the last moment the records exist: the
|
|
1160
|
+
* declared leave rules remove a `perPlayer` record.
|
|
1161
|
+
*/
|
|
1162
|
+
persistedFieldsOf(clientId: string): ReadonlyMap<string, Record<string, unknown>> | undefined;
|
|
1155
1163
|
markDisconnected(clientId: string): void;
|
|
1156
1164
|
ctxFor(clientId: string, reconnecting?: boolean): Ctx;
|
|
1157
1165
|
/**
|
package/dist/test/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { R as RoomCore } from '../room-
|
|
2
|
-
export { m as initMatter, n as initPhysics, o as initRapier2d } from '../room-
|
|
1
|
+
import { R as RoomCore } from '../room-B9h9dc4e.js';
|
|
2
|
+
export { m as initMatter, n as initPhysics, o as initRapier2d } from '../room-B9h9dc4e.js';
|
|
3
3
|
import { ErrorCodeName, FrameType } from '@irtio/protocol';
|
|
4
4
|
import { NpcConfig, LeaveReason, Room, RoomDefinition } from '@irtio/server';
|
|
5
|
-
import { p as RoomHost, L as LogLevel, k as RoomCoreApi, c as HostCall, d as HostCallResult, W as WriteCaps, r as RoomStats } from '../contract-
|
|
5
|
+
import { p as RoomHost, L as LogLevel, k as RoomCoreApi, c as HostCall, d as HostCallResult, W as WriteCaps, r as RoomStats } from '../contract-CpBkqkn7.js';
|
|
6
6
|
import { AnySchema, PlainState, EntityCollection, State } from '@irtio/schema';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -20,6 +20,14 @@ declare class FakeClock {
|
|
|
20
20
|
clearTimeout(handle: unknown): void;
|
|
21
21
|
/** Number of timers still armed (a room that is ticking always has at least one). */
|
|
22
22
|
get pending(): number;
|
|
23
|
+
/**
|
|
24
|
+
* The `at` of the earliest armed timer, or `undefined` when nothing is armed. Read-only: it
|
|
25
|
+
* changes nothing. It exists for callers that need to advance to the next timer rather than
|
|
26
|
+
* over it — `testRoom`'s `t.run(ms)` uses it to hop timer by timer, so a script parked on an
|
|
27
|
+
* `await` (whose continuation only runs once `advance` has returned and microtasks drain) can
|
|
28
|
+
* arm its next timer and keep going inside a single long run.
|
|
29
|
+
*/
|
|
30
|
+
nextDueAt(): number | undefined;
|
|
23
31
|
/**
|
|
24
32
|
* Advances to `time + ms`, firing every timer that comes due in order (earliest `at` first,
|
|
25
33
|
* ties broken by creation order). A timer that arms another timer inside the window fires too.
|
|
@@ -361,6 +369,11 @@ interface JoinSpec {
|
|
|
361
369
|
* `onAdmit` that requires identity needs to be tested against.
|
|
362
370
|
*/
|
|
363
371
|
readonly subject?: string;
|
|
372
|
+
/**
|
|
373
|
+
* The persistence blob this join arrives with: collection name → persisted field values. What
|
|
374
|
+
* the relay host reads from the store for an identified player, without a store or a socket.
|
|
375
|
+
*/
|
|
376
|
+
readonly persisted?: ReadonlyMap<string, Readonly<Record<string, unknown>>>;
|
|
364
377
|
}
|
|
365
378
|
interface UntilOptions {
|
|
366
379
|
/** Default 1000. */
|
package/dist/test/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
initPhysics,
|
|
6
6
|
initRapier2d,
|
|
7
7
|
visibleNames
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-S4D472RL.js";
|
|
9
9
|
|
|
10
10
|
// src/test/clock.ts
|
|
11
11
|
var FakeClock = class {
|
|
@@ -28,6 +28,22 @@ var FakeClock = class {
|
|
|
28
28
|
get pending() {
|
|
29
29
|
return this.timers.size;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* The `at` of the earliest armed timer, or `undefined` when nothing is armed. Read-only: it
|
|
33
|
+
* changes nothing. It exists for callers that need to advance to the next timer rather than
|
|
34
|
+
* over it — `testRoom`'s `t.run(ms)` uses it to hop timer by timer, so a script parked on an
|
|
35
|
+
* `await` (whose continuation only runs once `advance` has returned and microtasks drain) can
|
|
36
|
+
* arm its next timer and keep going inside a single long run.
|
|
37
|
+
*/
|
|
38
|
+
nextDueAt() {
|
|
39
|
+
let earliest;
|
|
40
|
+
for (const t of this.timers.values()) {
|
|
41
|
+
if (!earliest || t.at < earliest.at || t.at === earliest.at && t.id < earliest.id) {
|
|
42
|
+
earliest = t;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return earliest?.at;
|
|
46
|
+
}
|
|
31
47
|
/**
|
|
32
48
|
* Advances to `time + ms`, firing every timer that comes due in order (earliest `at` first,
|
|
33
49
|
* ties broken by creation order). A timer that arms another timer inside the window fires too.
|
|
@@ -966,8 +982,11 @@ var Harness = class {
|
|
|
966
982
|
...spec.playerId !== void 0 ? { playerId: spec.playerId } : {},
|
|
967
983
|
// ---- end M6 lane K ----
|
|
968
984
|
// ---- M8 lane 5: moderation ----
|
|
969
|
-
...spec.subject !== void 0 ? { subject: spec.subject } : {}
|
|
985
|
+
...spec.subject !== void 0 ? { subject: spec.subject } : {},
|
|
970
986
|
// ---- end M8 lane 5 ----
|
|
987
|
+
// ---- M8 proposal 13 ----
|
|
988
|
+
...spec.persisted !== void 0 ? { persisted: spec.persisted } : {}
|
|
989
|
+
// ---- end M8 proposal 13 ----
|
|
971
990
|
};
|
|
972
991
|
const client = new FakeClientImpl(this.bridge, id, options);
|
|
973
992
|
this.byId.set(id, client);
|
package/dist/worker/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LogLevel, t as RpcTraceDump, T as TimelineDump, r as RoomStats, c as HostCall, d as HostCallResult, k as RoomCoreApi, p as RoomHost } from '../contract-
|
|
1
|
+
import { L as LogLevel, t as RpcTraceDump, T as TimelineDump, r as RoomStats, c as HostCall, d as HostCallResult, k as RoomCoreApi, p as RoomHost } from '../contract-CpBkqkn7.js';
|
|
2
2
|
import { ErrorCodeName, ProfileSnapshot, PlatformNotice } from '@irtio/protocol';
|
|
3
3
|
import { NpcConfig, LeaveReason } from '@irtio/server';
|
|
4
4
|
import '@irtio/schema';
|
package/dist/worker/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
migrateSnapshot
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-G2XKCXRO.js";
|
|
4
4
|
import {
|
|
5
5
|
AdmissionError,
|
|
6
6
|
RoomCore,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
initRapier2d,
|
|
11
11
|
onFirstRapierStep,
|
|
12
12
|
rapierHasStepped
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-S4D472RL.js";
|
|
14
14
|
|
|
15
15
|
// src/worker/index.ts
|
|
16
16
|
import { getHeapStatistics } from "v8";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@irtio/runtime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "irtio room runtime: RoomCore, worker_threads host, in-process test harness",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"@dimforge/rapier2d-compat": "0.20.0",
|
|
37
37
|
"@dimforge/rapier3d-compat": "0.20.0",
|
|
38
38
|
"matter-js": "0.20.0",
|
|
39
|
-
"@irtio/protocol": "
|
|
40
|
-
"@irtio/schema": "
|
|
41
|
-
"@irtio/server": "
|
|
39
|
+
"@irtio/protocol": "^4.0.0",
|
|
40
|
+
"@irtio/schema": "^4.0.0",
|
|
41
|
+
"@irtio/server": "^4.0.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/matter-js": "0.20.2"
|