@irtio/runtime 0.11.0 → 1.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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  parseHibernationBlob,
3
3
  writeHibernationBlob
4
- } from "./chunk-GYPUNTQN.js";
4
+ } from "./chunk-LT46QFLW.js";
5
5
 
6
6
  // src/migrate.ts
7
7
  import { PRESENCE_COLLECTION, withBuiltins } from "@irtio/protocol";
@@ -1,6 +1,6 @@
1
1
  import { AnySchema, PlainState, State, Tracked } from '@irtio/schema';
2
2
  import * as _irtio_protocol from '@irtio/protocol';
3
- import { ErrorCodeName } from '@irtio/protocol';
3
+ import { PlatformNotice, ErrorCodeName } from '@irtio/protocol';
4
4
  import { RoomDefinition, Room, LeaveReason, NpcConfig } from '@irtio/server';
5
5
 
6
6
  /**
@@ -84,7 +84,9 @@ declare class TimelineRecorder {
84
84
 
85
85
  type RoomEventKind = 'join' | 'leave' | 'write' | 'write-rejected' | 'correct' | 'call' | 'reply' | 'msg' | 'alarm'
86
86
  /** D59: a bus event (a published message) or a directed bus send being delivered. */
87
- | 'bus' | 'error';
87
+ | 'bus'
88
+ /** M7 D-P2: a platform notice reaching `onPlatformNotice`; the detail is the phase. */
89
+ | 'notice' | 'error';
88
90
  interface RoomEvent {
89
91
  readonly tick: number;
90
92
  readonly kind: RoomEventKind;
@@ -267,10 +269,42 @@ type HostCall = {
267
269
  * number, but that bound lives on the side of the seam the tenant's own code owns.
268
270
  *
269
271
  * The result's `value` is the minted clip id.
272
+ *
273
+ * M6 clip-TTL packet: `expiresAtEpochS` is the unix second this clip should die, computed here
274
+ * because this is where `replay.ttl` is declared and read. The supervisor clamps it into
275
+ * `[now + 1m, now + 3650d]` before minting an id from it, so choosing it inside the tenant's
276
+ * own worker buys a hostile room nothing an honest one cannot declare.
270
277
  */
271
278
  | {
272
279
  readonly kind: 'clip';
273
280
  readonly bytes: Uint8Array;
281
+ readonly expiresAtEpochS: number;
282
+ }
283
+ /**
284
+ * D81's `record: true`: one numbered chunk of a continuous recording, on its way to storage.
285
+ *
286
+ * The chunk is the ring's own evictions, kept — so this call carries bulk bytes for the same
287
+ * reason `clip` does, is walled on the far side for the same reason, and is the only other host
288
+ * call that does either.
289
+ *
290
+ * `recId` is `undefined` on the first chunk of a recording and the supervisor's reply carries
291
+ * the id it minted; every chunk after it names that id. The mint is on the supervisor's side
292
+ * because that is where the entropy and the key algebra live (the `clip` precedent), and the
293
+ * runtime never invents one — which is also what keeps two rooms recording in one project from
294
+ * ever sharing a prefix.
295
+ *
296
+ * M6 clip-TTL packet: `expiresAtEpochS` is the expiry computed when the recording STARTED, and
297
+ * every chunk carries that same number for the life of the recording. It only decides anything
298
+ * on the first chunk — the mint — because every chunk after it is addressed by the `recId` the
299
+ * mint produced, which is what makes a 40-minute match expire atomically instead of losing its
300
+ * opening while its ending is still being watched.
301
+ */
302
+ | {
303
+ readonly kind: 'record-chunk';
304
+ readonly recId: string | undefined;
305
+ readonly seq: number;
306
+ readonly bytes: Uint8Array;
307
+ readonly expiresAtEpochS: number;
274
308
  };
275
309
  /**
276
310
  * What a `HostCall` produced. `value` carries the save id for `save` and the stored string for
@@ -533,6 +567,12 @@ interface RoomCoreApi<S extends AnySchema = AnySchema> {
533
567
  fireAlarm(name: string): void;
534
568
  /** D59: deliver one published message on a channel this room is subscribed to. */
535
569
  deliverBusEvent(channel: string, from: string, payload: string): void;
570
+ /**
571
+ * M7 D-P2: deliver a platform notice to `onPlatformNotice` and answer whether the supervisor
572
+ * should still broadcast it. `false` means the room vetoed; a throw, a missing handler and a
573
+ * stopped room all answer `true`.
574
+ */
575
+ deliverPlatformNotice(notice: PlatformNotice): boolean;
536
576
  /** D59: deliver one directed `room.bus.send`. At-least-once, so this may repeat a message. */
537
577
  deliverBusMessage(from: string, payload: string): void;
538
578
  /**
@@ -543,6 +583,8 @@ interface RoomCoreApi<S extends AnySchema = AnySchema> {
543
583
  stateBytes(): number | undefined;
544
584
  /** D77: how many records this room is holding for players who have left. */
545
585
  holdCount(): number;
586
+ /** How many `transfer: 'ask'` requests are waiting on an owner's answer. Never survives sleep. */
587
+ askCount(): number;
546
588
  }
547
589
 
548
590
  export { DEFAULT_RECORDS_PER_COLLECTION as D, EVENT_RING_SIZE as E, HOST_CALL_TIMEOUT_MS as H, type JoinOptions as J, type LogLevel as L, RELAY_RECORDS_PER_COLLECTION as R, type TimelineDump as T, type WriteCaps as W, DEFAULT_TIMELINE_MAX_RECORDS as a, DEFAULT_TIMELINE_MAX_TICKS as b, type HostCall as c, type HostCallResult as d, type JoinResult as e, RELAY_STATE_BYTES as f, RELAY_WRITES_PER_SECOND as g, RELAY_WRITE_CAPS as h, type RoomCoreApi as i, type RoomCoreOptions as j, type RoomEvent as k, type RoomEventKind as l, RoomFullError as m, type RoomHost as n, type RoomInspection as o, type RoomStats as p, type TimelineFrame as q, TimelineRecorder as r, type TimelineRecorderOptions as s, inspectState as t };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { 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, R as RELAY_RECORDS_PER_COLLECTION, f as RELAY_STATE_BYTES, g as RELAY_WRITES_PER_SECOND, h as RELAY_WRITE_CAPS, i as RoomCoreApi, j as RoomCoreOptions, k as RoomEvent, l as RoomEventKind, m as RoomFullError, n as RoomHost, o as RoomInspection, p as RoomStats, T as TimelineDump, q as TimelineFrame, r as TimelineRecorder, s as TimelineRecorderOptions, W as WriteCaps, t as inspectState } from './contract-Hk4SkDtW.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-0FZBGyke.js';
1
+ export { 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, R as RELAY_RECORDS_PER_COLLECTION, f as RELAY_STATE_BYTES, g as RELAY_WRITES_PER_SECOND, h as RELAY_WRITE_CAPS, i as RoomCoreApi, j as RoomCoreOptions, k as RoomEvent, l as RoomEventKind, m as RoomFullError, n as RoomHost, o as RoomInspection, p as RoomStats, T as TimelineDump, q as TimelineFrame, r as TimelineRecorder, s as TimelineRecorderOptions, W as WriteCaps, t as inspectState } from './contract-UEKTud1Z.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-uhj3b-8E.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-ACC3SDIO.js";
5
+ } from "./chunk-YWDRE77H.js";
6
6
  import {
7
7
  CRASH_AFTER_THROWS,
8
8
  DEFAULT_RECORDS_PER_COLLECTION,
@@ -52,7 +52,7 @@ import {
52
52
  visibleNames,
53
53
  visibleTo,
54
54
  writeHibernationBlob
55
- } from "./chunk-GYPUNTQN.js";
55
+ } from "./chunk-LT46QFLW.js";
56
56
  export {
57
57
  CRASH_AFTER_THROWS,
58
58
  DEFAULT_RECORDS_PER_COLLECTION,
@@ -1,7 +1,7 @@
1
- import { AttributeOptions, ProfileSnapshot } from '@irtio/protocol';
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 { n as RoomHost, p as RoomStats, L as LogLevel, i as RoomCoreApi, j as RoomCoreOptions, l as RoomEventKind, s as TimelineRecorderOptions, T as TimelineDump, o as RoomInspection, J as JoinOptions, e as JoinResult, d as HostCallResult } from './contract-Hk4SkDtW.js';
4
+ import { n as RoomHost, p as RoomStats, L as LogLevel, i as RoomCoreApi, j as RoomCoreOptions, l as RoomEventKind, s as TimelineRecorderOptions, T as TimelineDump, o as RoomInspection, J as JoinOptions, e as JoinResult, d as HostCallResult } from './contract-UEKTud1Z.js';
5
5
 
6
6
  declare class Mulberry32 {
7
7
  /** Current internal state (u32). Survives hibernation. */
@@ -734,6 +734,26 @@ declare class RoomCore<S extends AnySchema = AnySchema> implements RoomCoreApi<S
734
734
  constructor(definition: RoomDefinition<S>, host: RoomHost, options: RoomCoreOptions);
735
735
  private subscribeDeclaredChannels;
736
736
  private get busConfig();
737
+ /**
738
+ * M7 D-P2: the platform notice, and the room's veto.
739
+ *
740
+ * Answers whether the supervisor should broadcast. `false` — the veto — comes back for exactly
741
+ * one input: a handler that ran and returned `false`. Every other path answers `true`, and each
742
+ * one is a different way of the room having said nothing:
743
+ *
744
+ * - **No handler.** A room that never wrote this hook. The design's whole point is that its
745
+ * players still hear the warning; a code-less room does not even reach this file.
746
+ * - **A handler that threw.** `tryRun` and not `guard`, so the throw counts toward the crash
747
+ * threshold like any other, and it still does not become a veto. This is the one place the
748
+ * convention differs from `onChat`, where a throw refuses, and the reason is the asymmetry of
749
+ * the two losses: a chat line nobody sees is small; a save-loss warning nobody sees is the
750
+ * feature not existing.
751
+ * - **A stopped room.** Nobody to ask, and for `closing` nobody left to veto for.
752
+ *
753
+ * The handler may also have written state, posted chat or started an end sequence. All of that
754
+ * is ordinary handler work and is flushed here the way an alarm's is.
755
+ */
756
+ deliverPlatformNotice(notice: PlatformNotice): boolean;
737
757
  /**
738
758
  * D59: one published message arriving on a channel this room is subscribed to.
739
759
  *
@@ -881,6 +901,8 @@ declare class RoomCore<S extends AnySchema = AnySchema> implements RoomCoreApi<S
881
901
  stateBytes(): number | undefined;
882
902
  /** D77: how many records are held for players who have left. */
883
903
  holdCount(): number;
904
+ /** How many `transfer: 'ask'` requests are waiting on an owner's answer right now. */
905
+ askCount(): number;
884
906
  profile(): ProfileSnapshot | undefined;
885
907
  private badFrame;
886
908
  receive(clientId: string, frame: Uint8Array): void;
@@ -1,8 +1,8 @@
1
- import { R as RoomCore } from '../room-0FZBGyke.js';
2
- export { m as initMatter, n as initPhysics, o as initRapier2d } from '../room-0FZBGyke.js';
1
+ import { R as RoomCore } from '../room-uhj3b-8E.js';
2
+ export { m as initMatter, n as initPhysics, o as initRapier2d } from '../room-uhj3b-8E.js';
3
3
  import { ErrorCodeName, FrameType } from '@irtio/protocol';
4
4
  import { NpcConfig, LeaveReason, Room, RoomDefinition } from '@irtio/server';
5
- import { n as RoomHost, L as LogLevel, i as RoomCoreApi, c as HostCall, d as HostCallResult, W as WriteCaps, p as RoomStats } from '../contract-Hk4SkDtW.js';
5
+ import { n as RoomHost, L as LogLevel, i as RoomCoreApi, c as HostCall, d as HostCallResult, W as WriteCaps, p as RoomStats } from '../contract-UEKTud1Z.js';
6
6
  import { AnySchema, PlainState, EntityCollection, State } from '@irtio/schema';
7
7
 
8
8
  /**
@@ -141,6 +141,12 @@ declare class HarnessHost implements RoomHost {
141
141
  /** D81: every clip the room wrote, in order: `clipId` -> the blob it was handed. */
142
142
  readonly clips: Map<string, Uint8Array<ArrayBufferLike>>;
143
143
  private nextClipId;
144
+ /** D81: every recording this room wrote: `recId` -> its chunks in the order they were sent. */
145
+ readonly recordings: Map<string, {
146
+ seq: number;
147
+ bytes: Uint8Array;
148
+ }[]>;
149
+ private nextRecordingId;
144
150
  /**
145
151
  * D44: the in-process harness has no supervisor, no sockets and therefore no loopback session
146
152
  * to open. Recording the request rather than faking a session is the honest option: a test that
@@ -5,7 +5,7 @@ import {
5
5
  initPhysics,
6
6
  initRapier2d,
7
7
  visibleNames
8
- } from "../chunk-GYPUNTQN.js";
8
+ } from "../chunk-LT46QFLW.js";
9
9
 
10
10
  // src/test/clock.ts
11
11
  var FakeClock = class {
@@ -209,6 +209,18 @@ var HarnessHost = class {
209
209
  this.clips.set(clipId, call.bytes);
210
210
  return { ok: true, value: clipId };
211
211
  }
212
+ // ---- end M6 lane N ----
213
+ // ---- M6 record packet ----
214
+ case "record-chunk": {
215
+ const recId = call.recId ?? `rec${String(this.nextRecordingId++).padStart(4, "0")}`;
216
+ let chunks = this.recordings.get(recId);
217
+ if (!chunks) {
218
+ chunks = [];
219
+ this.recordings.set(recId, chunks);
220
+ }
221
+ chunks.push({ seq: call.seq, bytes: call.bytes });
222
+ return { ok: true, value: recId };
223
+ }
212
224
  }
213
225
  }
214
226
  // ---- M6 lane N: replays ----
@@ -216,6 +228,11 @@ var HarnessHost = class {
216
228
  clips = /* @__PURE__ */ new Map();
217
229
  nextClipId = 1;
218
230
  // ---- end M6 lane N ----
231
+ // ---- M6 record packet ----
232
+ /** D81: every recording this room wrote: `recId` -> its chunks in the order they were sent. */
233
+ recordings = /* @__PURE__ */ new Map();
234
+ nextRecordingId = 1;
235
+ // ---- end M6 record packet ----
219
236
  // -------------------------------------------------------------------------
220
237
  // Week 12: durable alarms (D26)
221
238
  // -------------------------------------------------------------------------
@@ -1,5 +1,5 @@
1
- import { L as LogLevel, T as TimelineDump, p as RoomStats, c as HostCall, d as HostCallResult, i as RoomCoreApi, n as RoomHost } from '../contract-Hk4SkDtW.js';
2
- import { ErrorCodeName, ProfileSnapshot } from '@irtio/protocol';
1
+ import { L as LogLevel, T as TimelineDump, p as RoomStats, c as HostCall, d as HostCallResult, i as RoomCoreApi, n as RoomHost } from '../contract-UEKTud1Z.js';
2
+ import { ErrorCodeName, ProfileSnapshot, PlatformNotice } from '@irtio/protocol';
3
3
  import { NpcConfig, LeaveReason } from '@irtio/server';
4
4
  import '@irtio/schema';
5
5
 
@@ -132,6 +132,17 @@ type ToWorker = {
132
132
  name: string;
133
133
  from: string;
134
134
  payload: string;
135
+ }
136
+ /**
137
+ * M7 D-P2: the platform has something to tell this room's players, and the room gets the first
138
+ * look. Carries a `reqId` because the answer decides whether the supervisor broadcasts, so this
139
+ * is a request and not a notification — a rare thing on this side of the wire, and the reason is
140
+ * that a veto only means anything before the frame goes out.
141
+ */
142
+ | {
143
+ t: 'platformNotice';
144
+ reqId: number;
145
+ notice: PlatformNotice;
135
146
  } | {
136
147
  t: 'stop';
137
148
  };
@@ -224,6 +235,17 @@ type FromWorker = {
224
235
  reqId: number;
225
236
  ok: boolean;
226
237
  }
238
+ /**
239
+ * M7 D-P2: the room's answer to a `platformNotice`. `broadcast: false` only when the handler
240
+ * returned exactly `false`. A handler that threw, a room with no handler, and a room whose core
241
+ * is not up all answer `true`, because the veto is a room saying "I will tell them myself" and
242
+ * none of those three said anything.
243
+ */
244
+ | {
245
+ t: 'platformNoticeResult';
246
+ reqId: number;
247
+ broadcast: boolean;
248
+ }
227
249
  /** D41: the recorded timeline. `dump` absent when nobody armed the recorder. */
228
250
  | {
229
251
  t: 'timeline';
@@ -368,5 +390,17 @@ interface WorkerState {
368
390
  * killing the worker.
369
391
  */
370
392
  declare function handleMessage(state: WorkerState, host: RoomHost, post: (msg: FromWorker, transfer?: ArrayBuffer[]) => void, msg: ToWorker): Promise<void>;
393
+ /**
394
+ * Replaces `Math.random` with sfc32 seeded from 16 host-supplied bytes.
395
+ *
396
+ * Box day 2 (2026-09-08) measured why this exists: two VMs restored from one golden snapshot
397
+ * handed their room workers **bit-for-bit identical `Math.random` streams** — V8 seeds a new
398
+ * isolate's PRNG from process state that a memory snapshot clones, and the kernel's VMGenID
399
+ * reseed does not reach it. `Math.random` is the only random primitive room code has (the
400
+ * sandbox refuses `node:crypto`), so an unseeded clone gives two different projects the same
401
+ * dice. The seed comes from the supervisor's clone-safe entropy mixer via `workerData`, so
402
+ * every worker — cold boot or restore, same VM or sibling clones — rolls its own.
403
+ */
404
+ declare function seedMathRandom(seedHex: string): void;
371
405
 
372
- export { type FromWorker, type MigrationChainStep, type ToWorker, type WorkerState, createWorkerHost, handleMessage, transferList };
406
+ export { type FromWorker, type MigrationChainStep, type ToWorker, type WorkerState, createWorkerHost, handleMessage, seedMathRandom, transferList };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  migrateSnapshot
3
- } from "../chunk-ACC3SDIO.js";
3
+ } from "../chunk-YWDRE77H.js";
4
4
  import {
5
5
  RoomCore,
6
6
  RoomFullError,
@@ -9,11 +9,11 @@ import {
9
9
  initRapier2d,
10
10
  onFirstRapierStep,
11
11
  rapierHasStepped
12
- } from "../chunk-GYPUNTQN.js";
12
+ } from "../chunk-LT46QFLW.js";
13
13
 
14
14
  // src/worker/index.ts
15
15
  import { getHeapStatistics } from "v8";
16
- import { isMainThread, parentPort } from "worker_threads";
16
+ import { isMainThread, parentPort, workerData } from "worker_threads";
17
17
  import { isRoomDefinition } from "@irtio/server";
18
18
 
19
19
  // src/worker/protocol.ts
@@ -352,6 +352,11 @@ async function handleMessage(state, host, post, msg) {
352
352
  state.core?.fireAlarm(msg.name);
353
353
  return;
354
354
  }
355
+ case "platformNotice": {
356
+ const broadcast = state.core?.deliverPlatformNotice(msg.notice) ?? true;
357
+ post({ t: "platformNoticeResult", reqId: msg.reqId, broadcast });
358
+ return;
359
+ }
355
360
  case "busEvent": {
356
361
  state.core?.deliverBusEvent(msg.channel, msg.from, msg.payload);
357
362
  return;
@@ -390,7 +395,32 @@ async function handleMessage(state, host, post, msg) {
390
395
  });
391
396
  }
392
397
  }
398
+ function seedMathRandom(seedHex) {
399
+ if (!/^[0-9a-f]{32}$/.test(seedHex)) return;
400
+ const u32 = (i) => Number.parseInt(seedHex.slice(i * 8, i * 8 + 8), 16) >>> 0;
401
+ let a = u32(0);
402
+ let b = u32(1);
403
+ let c = u32(2);
404
+ let d = u32(3);
405
+ const sfc32 = () => {
406
+ a >>>= 0;
407
+ b >>>= 0;
408
+ c >>>= 0;
409
+ d >>>= 0;
410
+ const t = a + b + d >>> 0;
411
+ d = d + 1 >>> 0;
412
+ a = b ^ b >>> 9;
413
+ b = c + (c << 3) >>> 0;
414
+ c = (c << 21 | c >>> 11) >>> 0;
415
+ c = c + t >>> 0;
416
+ return t / 4294967296;
417
+ };
418
+ for (let i = 0; i < 12; i++) sfc32();
419
+ Math.random = sfc32;
420
+ }
393
421
  if (!isMainThread && parentPort) {
422
+ const seed = workerData?.mathRandomSeed;
423
+ if (typeof seed === "string") seedMathRandom(seed);
394
424
  const port = parentPort;
395
425
  const post = (msg, transfer) => {
396
426
  port.postMessage(msg, transfer ?? transferList(msg));
@@ -404,5 +434,6 @@ if (!isMainThread && parentPort) {
404
434
  export {
405
435
  createWorkerHost,
406
436
  handleMessage,
437
+ seedMathRandom,
407
438
  transferList
408
439
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@irtio/runtime",
3
- "version": "0.11.0",
3
+ "version": "1.0.0",
4
4
  "description": "irtio room runtime: RoomCore, worker_threads host, in-process test harness",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -31,9 +31,9 @@
31
31
  "@dimforge/rapier2d-compat": "0.20.0",
32
32
  "@dimforge/rapier3d-compat": "0.20.0",
33
33
  "matter-js": "0.20.0",
34
- "@irtio/protocol": "0.11.0",
35
- "@irtio/schema": "0.11.0",
36
- "@irtio/server": "0.11.0"
34
+ "@irtio/protocol": "1.0.0",
35
+ "@irtio/schema": "1.0.0",
36
+ "@irtio/server": "1.0.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/matter-js": "0.20.2"