@rpgjs/server 5.0.0-alpha.26 → 5.0.0-alpha.27

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/index.js CHANGED
@@ -5608,13 +5608,13 @@ function fromIterable(iterable) {
5608
5608
  }
5609
5609
  function fromAsyncIterable(asyncIterable) {
5610
5610
  return new Observable(function (subscriber) {
5611
- process$1(asyncIterable, subscriber).catch(function (err) { return subscriber.error(err); });
5611
+ process$2(asyncIterable, subscriber).catch(function (err) { return subscriber.error(err); });
5612
5612
  });
5613
5613
  }
5614
5614
  function fromReadableStreamLike(readableStream) {
5615
5615
  return fromAsyncIterable(readableStreamLikeToAsyncGenerator(readableStream));
5616
5616
  }
5617
- function process$1(asyncIterable, subscriber) {
5617
+ function process$2(asyncIterable, subscriber) {
5618
5618
  var asyncIterable_1, asyncIterable_1_1;
5619
5619
  var e_2, _a;
5620
5620
  return __awaiter(this, void 0, void 0, function () {
@@ -6065,7 +6065,7 @@ function toArray() {
6065
6065
  });
6066
6066
  }
6067
6067
 
6068
- function finalize(callback) {
6068
+ function finalize$1(callback) {
6069
6069
  return operate(function (source, subscriber) {
6070
6070
  try {
6071
6071
  source.subscribe(subscriber);
@@ -6517,7 +6517,7 @@ function computed(computeFunction, disposableFn) {
6517
6517
  }
6518
6518
  return dep.observable;
6519
6519
  });
6520
- const computedObservable = combineLatest(observables).pipe(filter(() => !init), map(() => computeFunction()), finalize(() => disposableFn?.()));
6520
+ const computedObservable = combineLatest(observables).pipe(filter(() => !init), map(() => computeFunction()), finalize$1(() => disposableFn?.()));
6521
6521
  const fn = /* @__PURE__ */ __name$2(function() {
6522
6522
  trackDependency(fn);
6523
6523
  return lastComputedValue;
@@ -7745,6 +7745,7 @@ var Server = class {
7745
7745
  instance.$memoryAll = {};
7746
7746
  instance.$autoSync = instance["autoSync"] !== false;
7747
7747
  instance.$pendingSync = /* @__PURE__ */ new Map();
7748
+ instance.$pendingInitialSync = /* @__PURE__ */ new Map();
7748
7749
  instance.$send = (conn, obj) => {
7749
7750
  return this.send(conn, obj, instance);
7750
7751
  };
@@ -7762,10 +7763,25 @@ var Server = class {
7762
7763
  } else {
7763
7764
  packet = instance.$memoryAll;
7764
7765
  }
7765
- this.broadcast({
7766
- type: "sync",
7767
- value: packet
7768
- }, instance);
7766
+ const pendingConnections = new Set(instance.$pendingInitialSync.keys());
7767
+ for (const [conn, publicId] of instance.$pendingInitialSync) {
7768
+ this.send(conn, {
7769
+ type: "sync",
7770
+ value: {
7771
+ pId: publicId,
7772
+ ...packet
7773
+ }
7774
+ }, instance);
7775
+ }
7776
+ instance.$pendingInitialSync.clear();
7777
+ for (const conn of this.room.getConnections()) {
7778
+ if (!pendingConnections.has(conn)) {
7779
+ this.send(conn, {
7780
+ type: "sync",
7781
+ value: packet
7782
+ }, instance);
7783
+ }
7784
+ }
7769
7785
  };
7770
7786
  instance.$sessionTransfer = async (conn, targetRoomId) => {
7771
7787
  let user;
@@ -8083,6 +8099,8 @@ var Server = class {
8083
8099
  ...subRoom.$memoryAll
8084
8100
  }
8085
8101
  }, subRoom);
8102
+ } else {
8103
+ subRoom.$pendingInitialSync.set(conn, publicId);
8086
8104
  }
8087
8105
  }
8088
8106
  /**
@@ -8368,6 +8386,9 @@ var Server = class {
8368
8386
  if (!subRoom) {
8369
8387
  return;
8370
8388
  }
8389
+ if (subRoom.$pendingInitialSync) {
8390
+ subRoom.$pendingInitialSync.delete(conn);
8391
+ }
8371
8392
  const signal2 = this.getUsersProperty(subRoom);
8372
8393
  if (!conn.state) {
8373
8394
  return;
@@ -9962,6 +9983,9 @@ __decorateClass$3([
9962
9983
  __decorateClass$3([
9963
9984
  sync()
9964
9985
  ], RpgCommonPlayer.prototype, "_gold");
9986
+ __decorateClass$3([
9987
+ sync()
9988
+ ], RpgCommonPlayer.prototype, "animationName");
9965
9989
  __decorateClass$3([
9966
9990
  sync()
9967
9991
  ], RpgCommonPlayer.prototype, "hpSignal");
@@ -15264,29 +15288,6 @@ class Knockback {
15264
15288
  }
15265
15289
  }
15266
15290
 
15267
- class LinearMove {
15268
- /**
15269
- * Creates a linear movement strategy.
15270
- *
15271
- * @param velocity - Velocity to apply (units per second)
15272
- * @param duration - Optional duration in seconds (undefined for infinite)
15273
- */
15274
- constructor(velocity, duration) {
15275
- this.velocity = velocity;
15276
- this.duration = duration;
15277
- this.elapsed = 0;
15278
- }
15279
- update(body, dt) {
15280
- if (this.duration !== void 0) {
15281
- this.elapsed += dt;
15282
- }
15283
- body.setVelocity(this.velocity);
15284
- }
15285
- isFinished() {
15286
- return this.duration !== void 0 && this.elapsed >= this.duration;
15287
- }
15288
- }
15289
-
15290
15291
  class LinearRepulsion {
15291
15292
  /**
15292
15293
  * @param engine - Physics engine used for spatial queries
@@ -15811,6 +15812,11 @@ class RpgCommonMap {
15811
15812
  this.tileHeight = 32;
15812
15813
  this.physicsAccumulatorMs = 0;
15813
15814
  this.physicsSyncDepth = 0;
15815
+ /**
15816
+ * Whether to automatically subscribe to tick$ for physics updates
15817
+ * Set to false in test environments for manual control with nextTick()
15818
+ */
15819
+ this.autoTickEnabled = true;
15814
15820
  /**
15815
15821
  * Observable representing the game loop tick
15816
15822
  *
@@ -16044,9 +16050,11 @@ class RpgCommonMap {
16044
16050
  this.updateCharacterHitbox(event);
16045
16051
  }
16046
16052
  });
16047
- this.tickSubscription = this.tick$.subscribe(({ delta }) => {
16048
- this.runFixedTicks(delta);
16049
- });
16053
+ if (this.autoTickEnabled) {
16054
+ this.tickSubscription = this.tick$.subscribe(({ delta }) => {
16055
+ this.runFixedTicks(delta);
16056
+ });
16057
+ }
16050
16058
  }
16051
16059
  async movePlayer(player, direction) {
16052
16060
  const currentX = player.x();
@@ -16068,12 +16076,8 @@ class RpgCommonMap {
16068
16076
  nextY = currentY + speed;
16069
16077
  break;
16070
16078
  }
16071
- if (typeof player.setIntendedDirection === "function") {
16072
- player.setIntendedDirection(direction);
16073
- } else if (typeof player.changeDirection === "function") {
16074
- player.changeDirection(direction);
16075
- }
16076
- if (typeof player.autoChangeMap === "function") {
16079
+ player.changeDirection(direction);
16080
+ if (typeof player.autoChangeMap === "function" && !player.isEvent()) {
16077
16081
  const mapChanged = await player.autoChangeMap({ x: nextX, y: nextY }, direction);
16078
16082
  if (mapChanged) {
16079
16083
  this.stopMovement(player);
@@ -16157,6 +16161,46 @@ class RpgCommonMap {
16157
16161
  }
16158
16162
  return executed;
16159
16163
  }
16164
+ /**
16165
+ * Manually trigger a single game tick
16166
+ *
16167
+ * This method allows you to manually advance the game by one tick (16ms at 60fps).
16168
+ * It's primarily useful for testing where you need precise control over when
16169
+ * physics updates occur, rather than relying on the automatic tick$ subscription.
16170
+ *
16171
+ * ## Use Cases
16172
+ *
16173
+ * - **Testing**: Control exactly when physics steps occur in unit tests
16174
+ * - **Manual control**: Step through game state manually for debugging
16175
+ * - **Deterministic testing**: Ensure consistent timing in test scenarios
16176
+ *
16177
+ * ## Important
16178
+ *
16179
+ * This method should NOT be used in production code alongside the automatic `tick$`
16180
+ * subscription, as it will cause double-stepping. Use either:
16181
+ * - Automatic ticks (via `loadPhysic()` which subscribes to `tick$`)
16182
+ * - Manual ticks (via `nextTick()` without `loadPhysic()` subscription)
16183
+ *
16184
+ * @param deltaMs - Optional delta time in milliseconds (default: 16ms for 60fps)
16185
+ * @returns Number of physics ticks executed
16186
+ *
16187
+ * @example
16188
+ * ```ts
16189
+ * // In tests: manually advance game by one tick
16190
+ * map.nextTick(); // Advances by 16ms (one frame at 60fps)
16191
+ *
16192
+ * // With custom delta
16193
+ * map.nextTick(32); // Advances by 32ms (two frames at 60fps)
16194
+ *
16195
+ * // In a test loop
16196
+ * for (let i = 0; i < 60; i++) {
16197
+ * map.nextTick(); // Simulate 1 second of game time
16198
+ * }
16199
+ * ```
16200
+ */
16201
+ nextTick(deltaMs = 16) {
16202
+ return this.runFixedTicks(deltaMs);
16203
+ }
16160
16204
  /**
16161
16205
  * Force a single physics tick outside of the normal game loop
16162
16206
  *
@@ -16206,19 +16250,12 @@ class RpgCommonMap {
16206
16250
  const hitbox = typeof owner.hitbox === "function" ? owner.hitbox() : owner.hitbox;
16207
16251
  const width = hitbox?.w ?? 32;
16208
16252
  const height = hitbox?.h ?? 32;
16209
- const topLeftX = this.resolveNumeric(owner.x);
16210
- const topLeftY = this.resolveNumeric(owner.y);
16211
- const centerX = topLeftX + width / 2;
16212
- const centerY = topLeftY + height / 2;
16213
16253
  const radius = Math.max(width, height) / 2;
16214
- const speedValue = typeof owner.speed === "function" ? owner.speed() : typeof owner.speed === "number" ? owner.speed : void 0;
16215
16254
  this.addCharacter({
16216
16255
  owner,
16217
- x: centerX,
16218
- y: centerY,
16219
16256
  radius,
16220
16257
  kind,
16221
- maxSpeed: speedValue,
16258
+ maxSpeed: owner.speed(),
16222
16259
  collidesWithCharacters: !this.shouldDisableCharacterCollisions(owner),
16223
16260
  isStatic: options?.isStatic,
16224
16261
  mass: options?.mass
@@ -16590,11 +16627,24 @@ class RpgCommonMap {
16590
16627
  owner2.changeDirection(cardinalDirection);
16591
16628
  });
16592
16629
  entity.onMovementChange(({ isMoving, intensity }) => {
16630
+ const owner2 = entity.owner;
16631
+ if (!owner2) return;
16593
16632
  const LOW_INTENSITY_THRESHOLD = 10;
16633
+ const hasSetAnimation = typeof owner2.setAnimation === "function";
16634
+ const animationNameSignal = owner2.animationName;
16635
+ const ownerHasAnimationName = animationNameSignal && typeof animationNameSignal === "object" && typeof animationNameSignal.set === "function";
16594
16636
  if (isMoving && intensity > LOW_INTENSITY_THRESHOLD) {
16595
- owner.animationName.set("walk");
16637
+ if (hasSetAnimation) {
16638
+ owner2.setAnimation("walk");
16639
+ } else if (ownerHasAnimationName) {
16640
+ animationNameSignal.set("walk");
16641
+ }
16596
16642
  } else if (!isMoving) {
16597
- owner.animationName.set("stand");
16643
+ if (hasSetAnimation) {
16644
+ owner2.setAnimation("stand");
16645
+ } else if (ownerHasAnimationName) {
16646
+ animationNameSignal.set("stand");
16647
+ }
16598
16648
  }
16599
16649
  });
16600
16650
  const entityWidth = width;
@@ -16669,10 +16719,7 @@ class RpgCommonMap {
16669
16719
  moveBody(player, direction) {
16670
16720
  const entity = this.physic.getEntityByUUID(player.id);
16671
16721
  if (!entity) return false;
16672
- const speedValue = typeof player.speed === "function" ? Number(player.speed()) : 0;
16673
- if (typeof player.setIntendedDirection === "function") {
16674
- player.setIntendedDirection(direction);
16675
- }
16722
+ const speedValue = player.speed();
16676
16723
  let vx = 0, vy = 0;
16677
16724
  switch (direction) {
16678
16725
  case Direction.Left:
@@ -16724,9 +16771,6 @@ class RpgCommonMap {
16724
16771
  const entity = this.physic.getEntityByUUID(player.id);
16725
16772
  if (!entity) return false;
16726
16773
  this.moveManager.stopMovement(player.id);
16727
- if (typeof player.setIntendedDirection === "function") {
16728
- player.setIntendedDirection(null);
16729
- }
16730
16774
  player.pendingInputs = [];
16731
16775
  return true;
16732
16776
  }
@@ -17309,6 +17353,204 @@ var PrebuiltGui = /* @__PURE__ */ ((PrebuiltGui2) => {
17309
17353
  return PrebuiltGui2;
17310
17354
  })(PrebuiltGui || {});
17311
17355
 
17356
+ class PerlinNoise2D {
17357
+ /**
17358
+ * Creates a new Perlin noise generator
17359
+ *
17360
+ * @param seed - Optional seed for deterministic noise generation. If not provided, uses a default seed.
17361
+ *
17362
+ * @example
17363
+ * ```ts
17364
+ * const noise = new PerlinNoise2D(12345);
17365
+ * const value = noise.get(10, 20);
17366
+ * ```
17367
+ */
17368
+ constructor(seed = 0) {
17369
+ this.permutation = this.generatePermutation(seed);
17370
+ this.p = [...this.permutation, ...this.permutation];
17371
+ }
17372
+ /**
17373
+ * Generates a permutation table based on seed
17374
+ *
17375
+ * @param seed - Seed value for permutation generation
17376
+ * @returns Array of 256 shuffled values
17377
+ */
17378
+ generatePermutation(seed) {
17379
+ const p = [];
17380
+ for (let i = 0; i < 256; i++) {
17381
+ p[i] = i;
17382
+ }
17383
+ let state = seed;
17384
+ const lcg = () => {
17385
+ state = state * 1103515245 + 12345 & 2147483647;
17386
+ return state;
17387
+ };
17388
+ for (let i = 255; i > 0; i--) {
17389
+ const j = lcg() % (i + 1);
17390
+ [p[i], p[j]] = [p[j], p[i]];
17391
+ }
17392
+ return p;
17393
+ }
17394
+ /**
17395
+ * Fade function for smooth interpolation (ease curve)
17396
+ *
17397
+ * @param t - Value between 0 and 1
17398
+ * @returns Smoothed value between 0 and 1
17399
+ */
17400
+ fade(t) {
17401
+ return t * t * t * (t * (t * 6 - 15) + 10);
17402
+ }
17403
+ /**
17404
+ * Linear interpolation
17405
+ *
17406
+ * @param a - Start value
17407
+ * @param b - End value
17408
+ * @param t - Interpolation factor (0 to 1)
17409
+ * @returns Interpolated value
17410
+ */
17411
+ lerp(a, b, t) {
17412
+ return a + t * (b - a);
17413
+ }
17414
+ /**
17415
+ * Gradient function - generates a pseudo-random gradient vector
17416
+ *
17417
+ * @param hash - Hash value from permutation table
17418
+ * @param x - X component
17419
+ * @param y - Y component
17420
+ * @returns Dot product of gradient and position
17421
+ */
17422
+ grad(hash, x, y) {
17423
+ const h = hash & 3;
17424
+ switch (h) {
17425
+ case 0:
17426
+ return x + y;
17427
+ // (1, 1)
17428
+ case 1:
17429
+ return -x + y;
17430
+ // (-1, 1)
17431
+ case 2:
17432
+ return x - y;
17433
+ // (1, -1)
17434
+ case 3:
17435
+ return -x - y;
17436
+ // (-1, -1)
17437
+ default:
17438
+ return 0;
17439
+ }
17440
+ }
17441
+ /**
17442
+ * Gets the noise value at the specified 2D coordinates
17443
+ *
17444
+ * Returns a value between approximately -1 and 1, though values near the edges
17445
+ * are less common. For practical use, you may want to clamp or normalize the result.
17446
+ *
17447
+ * @param x - X coordinate
17448
+ * @param y - Y coordinate
17449
+ * @param scale - Optional scale factor (default: 0.1). Lower values create smoother, larger patterns.
17450
+ * @returns Noise value between approximately -1 and 1
17451
+ *
17452
+ * @example
17453
+ * ```ts
17454
+ * const noise = new PerlinNoise2D();
17455
+ * const value = noise.get(10, 20); // Basic usage
17456
+ * const scaled = noise.get(10, 20, 0.05); // Smoother pattern
17457
+ * ```
17458
+ */
17459
+ get(x, y, scale = 0.1) {
17460
+ x *= scale;
17461
+ y *= scale;
17462
+ const X = Math.floor(x) & 255;
17463
+ const Y = Math.floor(y) & 255;
17464
+ x -= Math.floor(x);
17465
+ y -= Math.floor(y);
17466
+ const u = this.fade(x);
17467
+ const v = this.fade(y);
17468
+ const A = this.p[X] + Y;
17469
+ const AA = this.p[A];
17470
+ const AB = this.p[A + 1];
17471
+ const B = this.p[X + 1] + Y;
17472
+ const BA = this.p[B];
17473
+ const BB = this.p[B + 1];
17474
+ return this.lerp(
17475
+ this.lerp(
17476
+ this.grad(this.p[AA], x, y),
17477
+ this.grad(this.p[BA], x - 1, y),
17478
+ u
17479
+ ),
17480
+ this.lerp(
17481
+ this.grad(this.p[AB], x, y - 1),
17482
+ this.grad(this.p[BB], x - 1, y - 1),
17483
+ u
17484
+ ),
17485
+ v
17486
+ );
17487
+ }
17488
+ /**
17489
+ * Gets a normalized noise value between 0 and 1
17490
+ *
17491
+ * Convenience method that normalizes the noise output to a 0-1 range.
17492
+ *
17493
+ * @param x - X coordinate
17494
+ * @param y - Y coordinate
17495
+ * @param scale - Optional scale factor (default: 0.1)
17496
+ * @returns Noise value between 0 and 1
17497
+ *
17498
+ * @example
17499
+ * ```ts
17500
+ * const noise = new PerlinNoise2D();
17501
+ * const normalized = noise.getNormalized(10, 20);
17502
+ * // Returns value between 0 and 1
17503
+ * ```
17504
+ */
17505
+ getNormalized(x, y, scale = 0.1) {
17506
+ return (this.get(x, y, scale) + 1) * 0.5;
17507
+ }
17508
+ /**
17509
+ * Gets a noise value mapped to a specific range
17510
+ *
17511
+ * Maps the noise output to a custom min-max range.
17512
+ *
17513
+ * @param x - X coordinate
17514
+ * @param y - Y coordinate
17515
+ * @param min - Minimum output value
17516
+ * @param max - Maximum output value
17517
+ * @param scale - Optional scale factor (default: 0.1)
17518
+ * @returns Noise value between min and max
17519
+ *
17520
+ * @example
17521
+ * ```ts
17522
+ * const noise = new PerlinNoise2D();
17523
+ * const direction = noise.getRange(10, 20, 0, 3); // Returns 0, 1, 2, or 3
17524
+ * ```
17525
+ */
17526
+ getRange(x, y, min, max, scale = 0.1) {
17527
+ const normalized = this.getNormalized(x, y, scale);
17528
+ return min + normalized * (max - min);
17529
+ }
17530
+ /**
17531
+ * Gets an integer noise value in a specific range (inclusive)
17532
+ *
17533
+ * Useful for selecting discrete values like array indices or enum values.
17534
+ *
17535
+ * @param x - X coordinate
17536
+ * @param y - Y coordinate
17537
+ * @param min - Minimum integer value (inclusive)
17538
+ * @param max - Maximum integer value (inclusive)
17539
+ * @param scale - Optional scale factor (default: 0.1)
17540
+ * @returns Integer noise value between min and max (inclusive)
17541
+ *
17542
+ * @example
17543
+ * ```ts
17544
+ * const noise = new PerlinNoise2D();
17545
+ * const directionIndex = noise.getInt(10, 20, 0, 3); // Returns 0, 1, 2, or 3
17546
+ * ```
17547
+ */
17548
+ getInt(x, y, min, max, scale = 0.1) {
17549
+ const value = this.getRange(x, y, min, max + 1, scale);
17550
+ return Math.floor(value);
17551
+ }
17552
+ }
17553
+
17312
17554
  function WithComponentManager(Base) {
17313
17555
  return class extends Base {
17314
17556
  setGraphic(graphic) {
@@ -18016,6 +18258,63 @@ var Speed = /* @__PURE__ */ ((Speed2) => {
18016
18258
  return Speed2;
18017
18259
  })(Speed || {});
18018
18260
  class MoveList {
18261
+ static {
18262
+ // Shared Perlin noise instance for smooth random movement
18263
+ this.perlinNoise = new PerlinNoise2D();
18264
+ }
18265
+ static {
18266
+ this.randomCounter = 0;
18267
+ }
18268
+ static {
18269
+ // Instance counter for each call to ensure variation
18270
+ this.callCounter = 0;
18271
+ }
18272
+ /**
18273
+ * Gets a random direction index (0-3) using a hybrid approach for balanced randomness
18274
+ *
18275
+ * Uses a combination of hash-based pseudo-randomness and Perlin noise to ensure
18276
+ * fair distribution of directions while maintaining smooth, natural-looking movement patterns.
18277
+ * The hash function guarantees uniform distribution, while Perlin noise adds spatial/temporal coherence.
18278
+ *
18279
+ * @param player - Optional player instance for coordinate-based noise
18280
+ * @param index - Optional index for array-based calls to ensure variation
18281
+ * @returns Direction index (0-3) corresponding to Right, Left, Up, Down
18282
+ */
18283
+ getRandomDirectionIndex(player, index) {
18284
+ MoveList.callCounter++;
18285
+ let seed;
18286
+ const time = Date.now() * 1e-3;
18287
+ if (player) {
18288
+ const playerX = typeof player.x === "function" ? player.x() : player.x;
18289
+ const playerY = typeof player.y === "function" ? player.y() : player.y;
18290
+ seed = Math.floor(
18291
+ playerX * 0.1 + playerY * 0.1 + time * 1e3 + MoveList.callCounter * 17 + (index ?? 0) * 31
18292
+ );
18293
+ } else {
18294
+ MoveList.randomCounter++;
18295
+ seed = Math.floor(
18296
+ MoveList.randomCounter * 17 + time * 1e3 + MoveList.callCounter * 31 + (index ?? 0) * 47
18297
+ );
18298
+ }
18299
+ let hash1 = (seed * 1103515245 + 12345 & 2147483647) >>> 0;
18300
+ let hash2 = seed * 2654435761 >>> 0;
18301
+ let hash3 = seed ^ seed >>> 16;
18302
+ hash3 = hash3 * 2246822507 >>> 0;
18303
+ let combinedHash = (hash1 ^ hash2 ^ hash3) >>> 0;
18304
+ const hashValue = combinedHash % 1e6 / 1e6;
18305
+ const perlinX = seed * 1e-3;
18306
+ const perlinY = seed * 1.618 * 1e-3;
18307
+ const perlinValue = MoveList.perlinNoise.getNormalized(perlinX, perlinY, 0.3);
18308
+ const finalValue = hashValue * 0.9 + perlinValue * 0.1;
18309
+ const clampedValue = Math.max(0, Math.min(0.999999, finalValue));
18310
+ let directionIndex = Math.floor(clampedValue * 4);
18311
+ directionIndex = Math.max(0, Math.min(3, directionIndex));
18312
+ if (!Number.isFinite(directionIndex) || directionIndex < 0 || directionIndex > 3) {
18313
+ const fallbackIndex = Math.floor(hashValue * 4) % 4;
18314
+ return Math.max(0, Math.min(3, fallbackIndex));
18315
+ }
18316
+ return directionIndex;
18317
+ }
18019
18318
  repeatMove(direction, repeat) {
18020
18319
  if (!Number.isFinite(repeat) || repeat < 0 || repeat > 1e4) {
18021
18320
  console.warn("Invalid repeat value:", repeat, "using default value 1");
@@ -18083,12 +18382,16 @@ class MoveList {
18083
18382
  repeat = 1;
18084
18383
  }
18085
18384
  try {
18086
- return new Array(repeat).fill(null).map(() => [
18087
- Direction.Right,
18088
- Direction.Left,
18089
- Direction.Up,
18090
- Direction.Down
18091
- ][random(0, 3)]);
18385
+ MoveList.randomCounter += repeat;
18386
+ return new Array(repeat).fill(null).map((_, index) => {
18387
+ const directionIndex = this.getRandomDirectionIndex(void 0, index);
18388
+ return [
18389
+ Direction.Right,
18390
+ Direction.Left,
18391
+ Direction.Up,
18392
+ Direction.Down
18393
+ ][directionIndex];
18394
+ });
18092
18395
  } catch (error) {
18093
18396
  console.error("Error creating random array with repeat:", repeat, error);
18094
18397
  return [Direction.Down];
@@ -18114,13 +18417,23 @@ class MoveList {
18114
18417
  }
18115
18418
  repeat = Math.floor(repeat);
18116
18419
  let directions = [];
18420
+ const directionFunctions = [
18421
+ this.tileRight(),
18422
+ this.tileLeft(),
18423
+ this.tileUp(),
18424
+ this.tileDown()
18425
+ ];
18117
18426
  for (let i = 0; i < repeat; i++) {
18118
- const randFn = [
18119
- this.tileRight(),
18120
- this.tileLeft(),
18121
- this.tileUp(),
18122
- this.tileDown()
18123
- ][random(0, 3)];
18427
+ let directionIndex = this.getRandomDirectionIndex(player, i);
18428
+ if (!Number.isInteger(directionIndex) || directionIndex < 0 || directionIndex > 3) {
18429
+ console.warn("Invalid directionIndex in tileRandom:", directionIndex, "using fallback");
18430
+ directionIndex = Math.floor(Math.random() * 4) % 4;
18431
+ }
18432
+ const randFn = directionFunctions[directionIndex];
18433
+ if (typeof randFn !== "function") {
18434
+ console.warn("randFn is not a function in tileRandom, skipping iteration");
18435
+ continue;
18436
+ }
18124
18437
  try {
18125
18438
  const newDirections = randFn(player, map);
18126
18439
  if (Array.isArray(newDirections)) {
@@ -18230,12 +18543,13 @@ class MoveList {
18230
18543
  return "turn-" + Direction.Down;
18231
18544
  }
18232
18545
  turnRandom() {
18546
+ const directionIndex = this.getRandomDirectionIndex();
18233
18547
  return [
18234
18548
  this.turnRight(),
18235
18549
  this.turnLeft(),
18236
18550
  this.turnUp(),
18237
18551
  this.turnDown()
18238
- ][random(0, 3)];
18552
+ ][directionIndex];
18239
18553
  }
18240
18554
  turnAwayFromPlayer(otherPlayer) {
18241
18555
  return (player) => {
@@ -18379,115 +18693,369 @@ function WithMoveManager(Base) {
18379
18693
  };
18380
18694
  this.addMovement(new ProjectileMovement(type, config));
18381
18695
  }
18382
- moveRoutes(routes) {
18383
- let count = 0;
18384
- let frequence = 0;
18696
+ moveRoutes(routes, options) {
18385
18697
  const player = this;
18386
18698
  this.clearMovements();
18387
18699
  return new Promise(async (resolve) => {
18388
18700
  this._finishRoute = resolve;
18389
- const processedRoutes = routes.map((route) => {
18390
- if (typeof route === "function") {
18391
- const map = player.getCurrentMap();
18392
- if (!map) {
18393
- return void 0;
18701
+ const processedRoutes = await Promise.all(
18702
+ routes.map(async (route) => {
18703
+ if (typeof route === "function") {
18704
+ const map = player.getCurrentMap();
18705
+ if (!map) {
18706
+ return void 0;
18707
+ }
18708
+ return route.apply(route, [player, map]);
18394
18709
  }
18395
- return route.apply(route, [player, map]);
18396
- }
18397
- return route;
18398
- });
18399
- const flatRoutes = this.flattenRoutes(processedRoutes);
18400
- let routeIndex = 0;
18401
- const executeNextRoute = async () => {
18402
- if (!player || !player.getCurrentMap()) {
18403
- this._finishRoute = null;
18404
- resolve(false);
18405
- return;
18710
+ return route;
18711
+ })
18712
+ );
18713
+ const finalRoutes = this.flattenRoutes(processedRoutes);
18714
+ class RouteMovementStrategy {
18715
+ constructor(routes2, player2, onComplete, options2) {
18716
+ this.routeIndex = 0;
18717
+ this.currentTarget = null;
18718
+ // Center position for physics
18719
+ this.currentTargetTopLeft = null;
18720
+ // Top-left position for player.x() comparison
18721
+ this.currentDirection = { x: 0, y: 0 };
18722
+ this.finished = false;
18723
+ this.waitingForPromise = false;
18724
+ this.promiseStartTime = 0;
18725
+ this.promiseDuration = 0;
18726
+ // Frequency wait state
18727
+ this.waitingForFrequency = false;
18728
+ this.frequencyWaitStartTime = 0;
18729
+ this.ratioFrequency = 15;
18730
+ // Stuck detection state
18731
+ this.lastPosition = null;
18732
+ this.lastPositionTime = 0;
18733
+ this.stuckCheckStartTime = 0;
18734
+ this.lastDistanceToTarget = null;
18735
+ this.isCurrentlyStuck = false;
18736
+ this.stuckCheckInitialized = false;
18737
+ this.routes = routes2;
18738
+ this.player = player2;
18739
+ this.onComplete = onComplete;
18740
+ this.tileSize = player2.nbPixelInTile || 32;
18741
+ this.tolerance = 0.5;
18742
+ this.onStuck = options2?.onStuck;
18743
+ this.stuckTimeout = options2?.stuckTimeout ?? 500;
18744
+ this.stuckThreshold = options2?.stuckThreshold ?? 1;
18745
+ this.processNextRoute();
18406
18746
  }
18407
- if (count >= (player.nbPixelInTile || 32)) {
18408
- if (frequence < (player.frequency || 0)) {
18409
- frequence++;
18410
- setTimeout(executeNextRoute, 16);
18747
+ processNextRoute() {
18748
+ this.waitingForFrequency = false;
18749
+ this.frequencyWaitStartTime = 0;
18750
+ if (this.routeIndex >= this.routes.length) {
18751
+ this.finished = true;
18752
+ this.onComplete(true);
18411
18753
  return;
18412
18754
  }
18413
- }
18414
- frequence = 0;
18415
- count++;
18416
- if (routeIndex >= flatRoutes.length) {
18417
- this._finishRoute = null;
18418
- resolve(true);
18419
- return;
18420
- }
18421
- const currentRoute = flatRoutes[routeIndex];
18422
- routeIndex++;
18423
- if (currentRoute === void 0) {
18424
- executeNextRoute();
18425
- return;
18426
- }
18427
- try {
18428
- if (typeof currentRoute === "object" && "then" in currentRoute) {
18429
- await currentRoute;
18430
- executeNextRoute();
18431
- } else if (typeof currentRoute === "string" && currentRoute.startsWith("turn-")) {
18432
- const directionStr = currentRoute.replace("turn-", "");
18433
- let direction = Direction.Down;
18434
- switch (directionStr) {
18435
- case "up":
18436
- case Direction.Up:
18437
- direction = Direction.Up;
18438
- break;
18439
- case "down":
18440
- case Direction.Down:
18441
- direction = Direction.Down;
18442
- break;
18443
- case "left":
18444
- case Direction.Left:
18445
- direction = Direction.Left;
18446
- break;
18447
- case "right":
18448
- case Direction.Right:
18449
- direction = Direction.Right;
18450
- break;
18451
- }
18452
- if (player.changeDirection) {
18453
- player.changeDirection(direction);
18454
- }
18455
- executeNextRoute();
18456
- } else if (typeof currentRoute === "number") {
18457
- if (player.moveByDirection) {
18458
- await player.moveByDirection(currentRoute, 1);
18459
- } else {
18460
- let vx = 0, vy = 0;
18461
- const direction = currentRoute;
18462
- switch (direction) {
18755
+ const currentRoute = this.routes[this.routeIndex];
18756
+ this.routeIndex++;
18757
+ if (currentRoute === void 0) {
18758
+ this.processNextRoute();
18759
+ return;
18760
+ }
18761
+ try {
18762
+ if (typeof currentRoute === "object" && "then" in currentRoute) {
18763
+ this.waitingForPromise = true;
18764
+ this.promiseStartTime = Date.now();
18765
+ this.promiseDuration = 1e3;
18766
+ currentRoute.then(() => {
18767
+ this.waitingForPromise = false;
18768
+ this.processNextRoute();
18769
+ }).catch(() => {
18770
+ this.waitingForPromise = false;
18771
+ this.processNextRoute();
18772
+ });
18773
+ } else if (typeof currentRoute === "string" && currentRoute.startsWith("turn-")) {
18774
+ const directionStr = currentRoute.replace("turn-", "");
18775
+ let direction = Direction.Down;
18776
+ switch (directionStr) {
18777
+ case "up":
18778
+ case Direction.Up:
18779
+ direction = Direction.Up;
18780
+ break;
18781
+ case "down":
18782
+ case Direction.Down:
18783
+ direction = Direction.Down;
18784
+ break;
18785
+ case "left":
18786
+ case Direction.Left:
18787
+ direction = Direction.Left;
18788
+ break;
18789
+ case "right":
18463
18790
  case Direction.Right:
18464
- vx = 1;
18791
+ direction = Direction.Right;
18792
+ break;
18793
+ }
18794
+ if (this.player.changeDirection) {
18795
+ this.player.changeDirection(direction);
18796
+ }
18797
+ this.processNextRoute();
18798
+ } else if (typeof currentRoute === "number" || typeof currentRoute === "string") {
18799
+ const moveDirection = currentRoute;
18800
+ const map = this.player.getCurrentMap();
18801
+ if (!map) {
18802
+ this.finished = true;
18803
+ this.onComplete(false);
18804
+ return;
18805
+ }
18806
+ const currentTopLeftX = typeof this.player.x === "function" ? this.player.x() : this.player.x;
18807
+ const currentTopLeftY = typeof this.player.y === "function" ? this.player.y() : this.player.y;
18808
+ let playerSpeed = this.player.speed();
18809
+ let distance = playerSpeed;
18810
+ const initialDistance = distance;
18811
+ const initialRouteIndex = this.routeIndex;
18812
+ while (this.routeIndex < this.routes.length) {
18813
+ const nextRoute = this.routes[this.routeIndex];
18814
+ if (nextRoute === currentRoute) {
18815
+ distance += playerSpeed;
18816
+ this.routeIndex++;
18817
+ } else {
18818
+ break;
18819
+ }
18820
+ }
18821
+ let targetTopLeftX = currentTopLeftX;
18822
+ let targetTopLeftY = currentTopLeftY;
18823
+ switch (moveDirection) {
18824
+ case Direction.Right:
18825
+ case "right":
18826
+ targetTopLeftX = currentTopLeftX + distance;
18465
18827
  break;
18466
18828
  case Direction.Left:
18467
- vx = -1;
18829
+ case "left":
18830
+ targetTopLeftX = currentTopLeftX - distance;
18468
18831
  break;
18469
18832
  case Direction.Down:
18470
- vy = 1;
18833
+ case "down":
18834
+ targetTopLeftY = currentTopLeftY + distance;
18471
18835
  break;
18472
18836
  case Direction.Up:
18473
- vy = -1;
18837
+ case "up":
18838
+ targetTopLeftY = currentTopLeftY - distance;
18474
18839
  break;
18475
18840
  }
18476
- const speed = player.speed?.() ?? 3;
18477
- this.addMovement(new LinearMove({ x: vx * speed, y: vy * speed }, 0.1));
18478
- setTimeout(executeNextRoute, 100);
18841
+ const entity = map.physic.getEntityByUUID(this.player.id);
18842
+ if (!entity) {
18843
+ this.finished = true;
18844
+ this.onComplete(false);
18845
+ return;
18846
+ }
18847
+ const hitbox = this.player.hitbox();
18848
+ const hitboxWidth = hitbox?.w ?? 32;
18849
+ const hitboxHeight = hitbox?.h ?? 32;
18850
+ const targetX = targetTopLeftX + hitboxWidth / 2;
18851
+ const targetY = targetTopLeftY + hitboxHeight / 2;
18852
+ this.currentTarget = { x: targetX, y: targetY };
18853
+ this.currentTargetTopLeft = { x: targetTopLeftX, y: targetTopLeftY };
18854
+ this.currentDirection = { x: 0, y: 0 };
18855
+ this.lastPosition = null;
18856
+ this.isCurrentlyStuck = false;
18857
+ this.stuckCheckStartTime = 0;
18858
+ this.lastDistanceToTarget = null;
18859
+ this.stuckCheckInitialized = false;
18860
+ this.waitingForFrequency = false;
18861
+ this.frequencyWaitStartTime = 0;
18862
+ } else if (Array.isArray(currentRoute)) {
18863
+ for (let i = currentRoute.length - 1; i >= 0; i--) {
18864
+ this.routes.splice(this.routeIndex, 0, currentRoute[i]);
18865
+ }
18866
+ this.processNextRoute();
18867
+ } else {
18868
+ this.processNextRoute();
18869
+ }
18870
+ } catch (error) {
18871
+ console.warn("Error processing route:", error);
18872
+ this.processNextRoute();
18873
+ }
18874
+ }
18875
+ update(body, dt) {
18876
+ if (this.waitingForPromise) {
18877
+ body.setVelocity({ x: 0, y: 0 });
18878
+ if (Date.now() - this.promiseStartTime > this.promiseDuration) {
18879
+ this.waitingForPromise = false;
18880
+ this.processNextRoute();
18881
+ }
18882
+ return;
18883
+ }
18884
+ if (this.waitingForFrequency) {
18885
+ body.setVelocity({ x: 0, y: 0 });
18886
+ const playerFrequency = this.player.frequency;
18887
+ const frequencyMs = playerFrequency || 0;
18888
+ if (frequencyMs > 0 && Date.now() - this.frequencyWaitStartTime >= frequencyMs * this.ratioFrequency) {
18889
+ this.waitingForFrequency = false;
18890
+ this.processNextRoute();
18891
+ }
18892
+ return;
18893
+ }
18894
+ if (!this.currentTarget) {
18895
+ if (!this.finished) {
18896
+ this.processNextRoute();
18897
+ }
18898
+ if (!this.currentTarget) {
18899
+ body.setVelocity({ x: 0, y: 0 });
18900
+ this.lastPosition = null;
18901
+ this.isCurrentlyStuck = false;
18902
+ this.lastDistanceToTarget = null;
18903
+ this.stuckCheckInitialized = false;
18904
+ this.currentTargetTopLeft = null;
18905
+ return;
18906
+ }
18907
+ }
18908
+ const entity = body.getEntity?.();
18909
+ if (!entity) {
18910
+ this.finished = true;
18911
+ this.onComplete(false);
18912
+ return;
18913
+ }
18914
+ const currentPosition = { x: entity.position.x, y: entity.position.y };
18915
+ const currentTime = Date.now();
18916
+ const currentTopLeftX = this.player.x();
18917
+ const currentTopLeftY = this.player.y();
18918
+ let dx, dy, distance;
18919
+ if (this.currentTargetTopLeft) {
18920
+ dx = this.currentTargetTopLeft.x - currentTopLeftX;
18921
+ dy = this.currentTargetTopLeft.y - currentTopLeftY;
18922
+ distance = Math.hypot(dx, dy);
18923
+ if (distance <= this.tolerance) {
18924
+ this.currentTarget = null;
18925
+ this.currentTargetTopLeft = null;
18926
+ this.currentDirection = { x: 0, y: 0 };
18927
+ body.setVelocity({ x: 0, y: 0 });
18928
+ this.lastPosition = null;
18929
+ this.isCurrentlyStuck = false;
18930
+ this.lastDistanceToTarget = null;
18931
+ this.stuckCheckInitialized = false;
18932
+ if (!this.finished) {
18933
+ const playerFrequency = this.player.frequency;
18934
+ if (playerFrequency && playerFrequency > 0) {
18935
+ this.waitingForFrequency = true;
18936
+ this.frequencyWaitStartTime = Date.now();
18937
+ } else {
18938
+ this.processNextRoute();
18939
+ }
18940
+ }
18479
18941
  return;
18480
18942
  }
18481
- executeNextRoute();
18482
18943
  } else {
18483
- executeNextRoute();
18944
+ dx = this.currentTarget.x - currentPosition.x;
18945
+ dy = this.currentTarget.y - currentPosition.y;
18946
+ distance = Math.hypot(dx, dy);
18947
+ if (distance <= this.tolerance) {
18948
+ this.currentTarget = null;
18949
+ this.currentTargetTopLeft = null;
18950
+ this.currentDirection = { x: 0, y: 0 };
18951
+ body.setVelocity({ x: 0, y: 0 });
18952
+ this.lastPosition = null;
18953
+ this.isCurrentlyStuck = false;
18954
+ this.lastDistanceToTarget = null;
18955
+ this.stuckCheckInitialized = false;
18956
+ if (!this.finished) {
18957
+ const playerFrequency = player.frequency;
18958
+ if (playerFrequency && playerFrequency > 0) {
18959
+ this.waitingForFrequency = true;
18960
+ this.frequencyWaitStartTime = Date.now();
18961
+ } else {
18962
+ this.processNextRoute();
18963
+ }
18964
+ }
18965
+ return;
18966
+ }
18484
18967
  }
18485
- } catch (error) {
18486
- console.warn("Error executing route:", error);
18487
- executeNextRoute();
18968
+ if (this.onStuck && this.currentTarget) {
18969
+ if (!this.stuckCheckInitialized) {
18970
+ this.lastPosition = { ...currentPosition };
18971
+ this.lastDistanceToTarget = distance;
18972
+ this.stuckCheckInitialized = true;
18973
+ this.lastPositionTime = currentTime;
18974
+ } else if (this.lastPosition && this.lastDistanceToTarget !== null) {
18975
+ const positionChanged = Math.hypot(
18976
+ currentPosition.x - this.lastPosition.x,
18977
+ currentPosition.y - this.lastPosition.y
18978
+ ) > this.stuckThreshold;
18979
+ const distanceImproved = distance < this.lastDistanceToTarget - this.stuckThreshold;
18980
+ if (!positionChanged && !distanceImproved) {
18981
+ if (!this.isCurrentlyStuck) {
18982
+ this.stuckCheckStartTime = currentTime;
18983
+ this.isCurrentlyStuck = true;
18984
+ } else {
18985
+ if (currentTime - this.stuckCheckStartTime >= this.stuckTimeout) {
18986
+ const shouldContinue = this.onStuck(
18987
+ this.player,
18988
+ this.currentTarget,
18989
+ currentPosition
18990
+ );
18991
+ if (shouldContinue === false) {
18992
+ this.finished = true;
18993
+ this.onComplete(false);
18994
+ body.setVelocity({ x: 0, y: 0 });
18995
+ return;
18996
+ }
18997
+ this.isCurrentlyStuck = false;
18998
+ this.stuckCheckStartTime = 0;
18999
+ this.lastPosition = { ...currentPosition };
19000
+ this.lastDistanceToTarget = distance;
19001
+ }
19002
+ }
19003
+ } else {
19004
+ this.isCurrentlyStuck = false;
19005
+ this.stuckCheckStartTime = 0;
19006
+ }
19007
+ this.lastPosition = { ...currentPosition };
19008
+ this.lastPositionTime = currentTime;
19009
+ this.lastDistanceToTarget = distance;
19010
+ }
19011
+ }
19012
+ const map = this.player.getCurrentMap();
19013
+ map?.speedScalar ?? 50;
19014
+ if (distance > 0) {
19015
+ this.currentDirection = { x: dx / distance, y: dy / distance };
19016
+ } else {
19017
+ this.currentTarget = null;
19018
+ this.currentTargetTopLeft = null;
19019
+ this.currentDirection = { x: 0, y: 0 };
19020
+ body.setVelocity({ x: 0, y: 0 });
19021
+ if (!this.finished) {
19022
+ const playerFrequency = typeof this.player.frequency === "function" ? this.player.frequency() : this.player.frequency;
19023
+ if (playerFrequency && playerFrequency > 0) {
19024
+ this.waitingForFrequency = true;
19025
+ this.frequencyWaitStartTime = Date.now();
19026
+ } else {
19027
+ this.processNextRoute();
19028
+ }
19029
+ }
19030
+ return;
19031
+ }
19032
+ const absX = Math.abs(this.currentDirection.x);
19033
+ const absY = Math.abs(this.currentDirection.y);
19034
+ let cardinalDirection;
19035
+ if (absX >= absY) {
19036
+ cardinalDirection = this.currentDirection.x >= 0 ? Direction.Right : Direction.Left;
19037
+ } else {
19038
+ cardinalDirection = this.currentDirection.y >= 0 ? Direction.Down : Direction.Up;
19039
+ }
19040
+ map.movePlayer(this.player, cardinalDirection);
18488
19041
  }
18489
- };
18490
- executeNextRoute();
19042
+ isFinished() {
19043
+ return this.finished;
19044
+ }
19045
+ onFinished() {
19046
+ this.onComplete(true);
19047
+ }
19048
+ }
19049
+ const routeStrategy = new RouteMovementStrategy(
19050
+ finalRoutes,
19051
+ player,
19052
+ (success) => {
19053
+ this._finishRoute = null;
19054
+ resolve(success);
19055
+ },
19056
+ options
19057
+ );
19058
+ this.addMovement(routeStrategy);
18491
19059
  });
18492
19060
  }
18493
19061
  flattenRoutes(routes) {
@@ -20329,7 +20897,12 @@ const _RpgPlayer = class _RpgPlayer extends BasicPlayerMixins(RpgCommonPlayer) {
20329
20897
  if (this.map && this.map.physic) {
20330
20898
  const entity = this.map.physic.getEntityByUUID(this.id);
20331
20899
  if (entity) {
20332
- this.map.physic.teleport(entity, { x: positions.x, y: positions.y });
20900
+ const hitbox = typeof this.hitbox === "function" ? this.hitbox() : this.hitbox;
20901
+ const width = hitbox?.w ?? 32;
20902
+ const height = hitbox?.h ?? 32;
20903
+ const centerX = positions.x + width / 2;
20904
+ const centerY = positions.y + height / 2;
20905
+ this.map.physic.teleport(entity, { x: centerX, y: centerY });
20333
20906
  }
20334
20907
  }
20335
20908
  this.x.set(positions.x);
@@ -20969,6 +21542,9 @@ const _RpgPlayer = class _RpgPlayer extends BasicPlayerMixins(RpgCommonPlayer) {
20969
21542
  }, this);
20970
21543
  }
20971
21544
  }
21545
+ isEvent() {
21546
+ return false;
21547
+ }
20972
21548
  };
20973
21549
  __decorateClass$2([
20974
21550
  sync(_RpgPlayer)
@@ -20988,6 +21564,9 @@ class RpgEvent extends RpgPlayer {
20988
21564
  if (!map2) return;
20989
21565
  map2.removeEvent(this.id);
20990
21566
  }
21567
+ isEvent() {
21568
+ return true;
21569
+ }
20991
21570
  }
20992
21571
 
20993
21572
  const context$1 = new Context();
@@ -22140,8 +22719,8 @@ class Doc {
22140
22719
 
22141
22720
  const version = {
22142
22721
  major: 4,
22143
- minor: 1,
22144
- patch: 13,
22722
+ minor: 2,
22723
+ patch: 0,
22145
22724
  };
22146
22725
 
22147
22726
  const $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
@@ -22211,16 +22790,6 @@ const $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
22211
22790
  }
22212
22791
  return payload;
22213
22792
  };
22214
- // const handleChecksResult = (
22215
- // checkResult: ParsePayload,
22216
- // originalResult: ParsePayload,
22217
- // ctx: ParseContextInternal
22218
- // ): util.MaybeAsync<ParsePayload> => {
22219
- // // if the checks mutated the value && there are no issues, re-parse the result
22220
- // if (checkResult.value !== originalResult.value && !checkResult.issues.length)
22221
- // return inst._zod.parse(checkResult, ctx);
22222
- // return originalResult;
22223
- // };
22224
22793
  const handleCanaryResult = (canary, payload, ctx) => {
22225
22794
  // abort if the canary is aborted
22226
22795
  if (aborted(canary)) {
@@ -23831,6 +24400,656 @@ function _check(fn, params) {
23831
24400
  return ch;
23832
24401
  }
23833
24402
 
24403
+ // function initializeContext<T extends schemas.$ZodType>(inputs: JSONSchemaGeneratorParams<T>): ToJSONSchemaContext<T> {
24404
+ // return {
24405
+ // processor: inputs.processor,
24406
+ // metadataRegistry: inputs.metadata ?? globalRegistry,
24407
+ // target: inputs.target ?? "draft-2020-12",
24408
+ // unrepresentable: inputs.unrepresentable ?? "throw",
24409
+ // };
24410
+ // }
24411
+ function initializeContext(params) {
24412
+ // Normalize target: convert old non-hyphenated versions to hyphenated versions
24413
+ let target = params?.target ?? "draft-2020-12";
24414
+ if (target === "draft-4")
24415
+ target = "draft-04";
24416
+ if (target === "draft-7")
24417
+ target = "draft-07";
24418
+ return {
24419
+ processors: params.processors ?? {},
24420
+ metadataRegistry: params?.metadata ?? globalRegistry,
24421
+ target,
24422
+ unrepresentable: params?.unrepresentable ?? "throw",
24423
+ override: params?.override ?? (() => { }),
24424
+ io: params?.io ?? "output",
24425
+ counter: 0,
24426
+ seen: new Map(),
24427
+ cycles: params?.cycles ?? "ref",
24428
+ reused: params?.reused ?? "inline",
24429
+ external: params?.external ?? undefined,
24430
+ };
24431
+ }
24432
+ function process$1(schema, ctx, _params = { path: [], schemaPath: [] }) {
24433
+ var _a;
24434
+ const def = schema._zod.def;
24435
+ // check for schema in seens
24436
+ const seen = ctx.seen.get(schema);
24437
+ if (seen) {
24438
+ seen.count++;
24439
+ // check if cycle
24440
+ const isCycle = _params.schemaPath.includes(schema);
24441
+ if (isCycle) {
24442
+ seen.cycle = _params.path;
24443
+ }
24444
+ return seen.schema;
24445
+ }
24446
+ // initialize
24447
+ const result = { schema: {}, count: 1, cycle: undefined, path: _params.path };
24448
+ ctx.seen.set(schema, result);
24449
+ // custom method overrides default behavior
24450
+ const overrideSchema = schema._zod.toJSONSchema?.();
24451
+ if (overrideSchema) {
24452
+ result.schema = overrideSchema;
24453
+ }
24454
+ else {
24455
+ const params = {
24456
+ ..._params,
24457
+ schemaPath: [..._params.schemaPath, schema],
24458
+ path: _params.path,
24459
+ };
24460
+ const parent = schema._zod.parent;
24461
+ if (parent) {
24462
+ // schema was cloned from another schema
24463
+ result.ref = parent;
24464
+ process$1(parent, ctx, params);
24465
+ ctx.seen.get(parent).isParent = true;
24466
+ }
24467
+ else if (schema._zod.processJSONSchema) {
24468
+ schema._zod.processJSONSchema(ctx, result.schema, params);
24469
+ }
24470
+ else {
24471
+ const _json = result.schema;
24472
+ const processor = ctx.processors[def.type];
24473
+ if (!processor) {
24474
+ throw new Error(`[toJSONSchema]: Non-representable type encountered: ${def.type}`);
24475
+ }
24476
+ processor(schema, ctx, _json, params);
24477
+ }
24478
+ }
24479
+ // metadata
24480
+ const meta = ctx.metadataRegistry.get(schema);
24481
+ if (meta)
24482
+ Object.assign(result.schema, meta);
24483
+ if (ctx.io === "input" && isTransforming(schema)) {
24484
+ // examples/defaults only apply to output type of pipe
24485
+ delete result.schema.examples;
24486
+ delete result.schema.default;
24487
+ }
24488
+ // set prefault as default
24489
+ if (ctx.io === "input" && result.schema._prefault)
24490
+ (_a = result.schema).default ?? (_a.default = result.schema._prefault);
24491
+ delete result.schema._prefault;
24492
+ // pulling fresh from ctx.seen in case it was overwritten
24493
+ const _result = ctx.seen.get(schema);
24494
+ return _result.schema;
24495
+ }
24496
+ function extractDefs(ctx, schema
24497
+ // params: EmitParams
24498
+ ) {
24499
+ // iterate over seen map;
24500
+ const root = ctx.seen.get(schema);
24501
+ if (!root)
24502
+ throw new Error("Unprocessed schema. This is a bug in Zod.");
24503
+ // returns a ref to the schema
24504
+ // defId will be empty if the ref points to an external schema (or #)
24505
+ const makeURI = (entry) => {
24506
+ // comparing the seen objects because sometimes
24507
+ // multiple schemas map to the same seen object.
24508
+ // e.g. lazy
24509
+ // external is configured
24510
+ const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
24511
+ if (ctx.external) {
24512
+ const externalId = ctx.external.registry.get(entry[0])?.id; // ?? "__shared";// `__schema${ctx.counter++}`;
24513
+ // check if schema is in the external registry
24514
+ const uriGenerator = ctx.external.uri ?? ((id) => id);
24515
+ if (externalId) {
24516
+ return { ref: uriGenerator(externalId) };
24517
+ }
24518
+ // otherwise, add to __shared
24519
+ const id = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
24520
+ entry[1].defId = id; // set defId so it will be reused if needed
24521
+ return { defId: id, ref: `${uriGenerator("__shared")}#/${defsSegment}/${id}` };
24522
+ }
24523
+ if (entry[1] === root) {
24524
+ return { ref: "#" };
24525
+ }
24526
+ // self-contained schema
24527
+ const uriPrefix = `#`;
24528
+ const defUriPrefix = `${uriPrefix}/${defsSegment}/`;
24529
+ const defId = entry[1].schema.id ?? `__schema${ctx.counter++}`;
24530
+ return { defId, ref: defUriPrefix + defId };
24531
+ };
24532
+ // stored cached version in `def` property
24533
+ // remove all properties, set $ref
24534
+ const extractToDef = (entry) => {
24535
+ // if the schema is already a reference, do not extract it
24536
+ if (entry[1].schema.$ref) {
24537
+ return;
24538
+ }
24539
+ const seen = entry[1];
24540
+ const { ref, defId } = makeURI(entry);
24541
+ seen.def = { ...seen.schema };
24542
+ // defId won't be set if the schema is a reference to an external schema
24543
+ // or if the schema is the root schema
24544
+ if (defId)
24545
+ seen.defId = defId;
24546
+ // wipe away all properties except $ref
24547
+ const schema = seen.schema;
24548
+ for (const key in schema) {
24549
+ delete schema[key];
24550
+ }
24551
+ schema.$ref = ref;
24552
+ };
24553
+ // throw on cycles
24554
+ // break cycles
24555
+ if (ctx.cycles === "throw") {
24556
+ for (const entry of ctx.seen.entries()) {
24557
+ const seen = entry[1];
24558
+ if (seen.cycle) {
24559
+ throw new Error("Cycle detected: " +
24560
+ `#/${seen.cycle?.join("/")}/<root>` +
24561
+ '\n\nSet the `cycles` parameter to `"ref"` to resolve cyclical schemas with defs.');
24562
+ }
24563
+ }
24564
+ }
24565
+ // extract schemas into $defs
24566
+ for (const entry of ctx.seen.entries()) {
24567
+ const seen = entry[1];
24568
+ // convert root schema to # $ref
24569
+ if (schema === entry[0]) {
24570
+ extractToDef(entry); // this has special handling for the root schema
24571
+ continue;
24572
+ }
24573
+ // extract schemas that are in the external registry
24574
+ if (ctx.external) {
24575
+ const ext = ctx.external.registry.get(entry[0])?.id;
24576
+ if (schema !== entry[0] && ext) {
24577
+ extractToDef(entry);
24578
+ continue;
24579
+ }
24580
+ }
24581
+ // extract schemas with `id` meta
24582
+ const id = ctx.metadataRegistry.get(entry[0])?.id;
24583
+ if (id) {
24584
+ extractToDef(entry);
24585
+ continue;
24586
+ }
24587
+ // break cycles
24588
+ if (seen.cycle) {
24589
+ // any
24590
+ extractToDef(entry);
24591
+ continue;
24592
+ }
24593
+ // extract reused schemas
24594
+ if (seen.count > 1) {
24595
+ if (ctx.reused === "ref") {
24596
+ extractToDef(entry);
24597
+ // biome-ignore lint:
24598
+ continue;
24599
+ }
24600
+ }
24601
+ }
24602
+ }
24603
+ function finalize(ctx, schema) {
24604
+ //
24605
+ // iterate over seen map;
24606
+ const root = ctx.seen.get(schema);
24607
+ if (!root)
24608
+ throw new Error("Unprocessed schema. This is a bug in Zod.");
24609
+ // flatten _refs
24610
+ const flattenRef = (zodSchema) => {
24611
+ const seen = ctx.seen.get(zodSchema);
24612
+ const schema = seen.def ?? seen.schema;
24613
+ const _cached = { ...schema };
24614
+ // already seen
24615
+ if (seen.ref === null) {
24616
+ return;
24617
+ }
24618
+ // flatten ref if defined
24619
+ const ref = seen.ref;
24620
+ seen.ref = null; // prevent recursion
24621
+ if (ref) {
24622
+ flattenRef(ref);
24623
+ // merge referenced schema into current
24624
+ const refSchema = ctx.seen.get(ref).schema;
24625
+ if (refSchema.$ref && (ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0")) {
24626
+ schema.allOf = schema.allOf ?? [];
24627
+ schema.allOf.push(refSchema);
24628
+ }
24629
+ else {
24630
+ Object.assign(schema, refSchema);
24631
+ Object.assign(schema, _cached); // prevent overwriting any fields in the original schema
24632
+ }
24633
+ }
24634
+ // execute overrides
24635
+ if (!seen.isParent)
24636
+ ctx.override({
24637
+ zodSchema: zodSchema,
24638
+ jsonSchema: schema,
24639
+ path: seen.path ?? [],
24640
+ });
24641
+ };
24642
+ for (const entry of [...ctx.seen.entries()].reverse()) {
24643
+ flattenRef(entry[0]);
24644
+ }
24645
+ const result = {};
24646
+ if (ctx.target === "draft-2020-12") {
24647
+ result.$schema = "https://json-schema.org/draft/2020-12/schema";
24648
+ }
24649
+ else if (ctx.target === "draft-07") {
24650
+ result.$schema = "http://json-schema.org/draft-07/schema#";
24651
+ }
24652
+ else if (ctx.target === "draft-04") {
24653
+ result.$schema = "http://json-schema.org/draft-04/schema#";
24654
+ }
24655
+ else if (ctx.target === "openapi-3.0") ;
24656
+ else ;
24657
+ if (ctx.external?.uri) {
24658
+ const id = ctx.external.registry.get(schema)?.id;
24659
+ if (!id)
24660
+ throw new Error("Schema is missing an `id` property");
24661
+ result.$id = ctx.external.uri(id);
24662
+ }
24663
+ Object.assign(result, root.def ?? root.schema);
24664
+ // build defs object
24665
+ const defs = ctx.external?.defs ?? {};
24666
+ for (const entry of ctx.seen.entries()) {
24667
+ const seen = entry[1];
24668
+ if (seen.def && seen.defId) {
24669
+ defs[seen.defId] = seen.def;
24670
+ }
24671
+ }
24672
+ // set definitions in result
24673
+ if (ctx.external) ;
24674
+ else {
24675
+ if (Object.keys(defs).length > 0) {
24676
+ if (ctx.target === "draft-2020-12") {
24677
+ result.$defs = defs;
24678
+ }
24679
+ else {
24680
+ result.definitions = defs;
24681
+ }
24682
+ }
24683
+ }
24684
+ try {
24685
+ // this "finalizes" this schema and ensures all cycles are removed
24686
+ // each call to finalize() is functionally independent
24687
+ // though the seen map is shared
24688
+ const finalized = JSON.parse(JSON.stringify(result));
24689
+ Object.defineProperty(finalized, "~standard", {
24690
+ value: {
24691
+ ...schema["~standard"],
24692
+ jsonSchema: {
24693
+ input: createStandardJSONSchemaMethod(schema, "input"),
24694
+ output: createStandardJSONSchemaMethod(schema, "output"),
24695
+ },
24696
+ },
24697
+ enumerable: false,
24698
+ writable: false,
24699
+ });
24700
+ return finalized;
24701
+ }
24702
+ catch (_err) {
24703
+ throw new Error("Error converting schema to JSON.");
24704
+ }
24705
+ }
24706
+ function isTransforming(_schema, _ctx) {
24707
+ const ctx = _ctx ?? { seen: new Set() };
24708
+ if (ctx.seen.has(_schema))
24709
+ return false;
24710
+ ctx.seen.add(_schema);
24711
+ const def = _schema._zod.def;
24712
+ if (def.type === "transform")
24713
+ return true;
24714
+ if (def.type === "array")
24715
+ return isTransforming(def.element, ctx);
24716
+ if (def.type === "set")
24717
+ return isTransforming(def.valueType, ctx);
24718
+ if (def.type === "lazy")
24719
+ return isTransforming(def.getter(), ctx);
24720
+ if (def.type === "promise" ||
24721
+ def.type === "optional" ||
24722
+ def.type === "nonoptional" ||
24723
+ def.type === "nullable" ||
24724
+ def.type === "readonly" ||
24725
+ def.type === "default" ||
24726
+ def.type === "prefault") {
24727
+ return isTransforming(def.innerType, ctx);
24728
+ }
24729
+ if (def.type === "intersection") {
24730
+ return isTransforming(def.left, ctx) || isTransforming(def.right, ctx);
24731
+ }
24732
+ if (def.type === "record" || def.type === "map") {
24733
+ return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
24734
+ }
24735
+ if (def.type === "pipe") {
24736
+ return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);
24737
+ }
24738
+ if (def.type === "object") {
24739
+ for (const key in def.shape) {
24740
+ if (isTransforming(def.shape[key], ctx))
24741
+ return true;
24742
+ }
24743
+ return false;
24744
+ }
24745
+ if (def.type === "union") {
24746
+ for (const option of def.options) {
24747
+ if (isTransforming(option, ctx))
24748
+ return true;
24749
+ }
24750
+ return false;
24751
+ }
24752
+ if (def.type === "tuple") {
24753
+ for (const item of def.items) {
24754
+ if (isTransforming(item, ctx))
24755
+ return true;
24756
+ }
24757
+ if (def.rest && isTransforming(def.rest, ctx))
24758
+ return true;
24759
+ return false;
24760
+ }
24761
+ return false;
24762
+ }
24763
+ /**
24764
+ * Creates a toJSONSchema method for a schema instance.
24765
+ * This encapsulates the logic of initializing context, processing, extracting defs, and finalizing.
24766
+ */
24767
+ const createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
24768
+ const ctx = initializeContext({ ...params, processors });
24769
+ process$1(schema, ctx);
24770
+ extractDefs(ctx, schema);
24771
+ return finalize(ctx, schema);
24772
+ };
24773
+ const createStandardJSONSchemaMethod = (schema, io) => (params) => {
24774
+ const { libraryOptions, target } = params ?? {};
24775
+ const ctx = initializeContext({ ...(libraryOptions ?? {}), target, io, processors: {} });
24776
+ process$1(schema, ctx);
24777
+ extractDefs(ctx, schema);
24778
+ return finalize(ctx, schema);
24779
+ };
24780
+
24781
+ const formatMap = {
24782
+ guid: "uuid",
24783
+ url: "uri",
24784
+ datetime: "date-time",
24785
+ json_string: "json-string",
24786
+ regex: "", // do not set
24787
+ };
24788
+ // ==================== SIMPLE TYPE PROCESSORS ====================
24789
+ const stringProcessor = (schema, ctx, _json, _params) => {
24790
+ const json = _json;
24791
+ json.type = "string";
24792
+ const { minimum, maximum, format, patterns, contentEncoding } = schema._zod
24793
+ .bag;
24794
+ if (typeof minimum === "number")
24795
+ json.minLength = minimum;
24796
+ if (typeof maximum === "number")
24797
+ json.maxLength = maximum;
24798
+ // custom pattern overrides format
24799
+ if (format) {
24800
+ json.format = formatMap[format] ?? format;
24801
+ if (json.format === "")
24802
+ delete json.format; // empty format is not valid
24803
+ }
24804
+ if (contentEncoding)
24805
+ json.contentEncoding = contentEncoding;
24806
+ if (patterns && patterns.size > 0) {
24807
+ const regexes = [...patterns];
24808
+ if (regexes.length === 1)
24809
+ json.pattern = regexes[0].source;
24810
+ else if (regexes.length > 1) {
24811
+ json.allOf = [
24812
+ ...regexes.map((regex) => ({
24813
+ ...(ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0"
24814
+ ? { type: "string" }
24815
+ : {}),
24816
+ pattern: regex.source,
24817
+ })),
24818
+ ];
24819
+ }
24820
+ }
24821
+ };
24822
+ const numberProcessor = (schema, ctx, _json, _params) => {
24823
+ const json = _json;
24824
+ const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
24825
+ if (typeof format === "string" && format.includes("int"))
24826
+ json.type = "integer";
24827
+ else
24828
+ json.type = "number";
24829
+ if (typeof exclusiveMinimum === "number") {
24830
+ if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") {
24831
+ json.minimum = exclusiveMinimum;
24832
+ json.exclusiveMinimum = true;
24833
+ }
24834
+ else {
24835
+ json.exclusiveMinimum = exclusiveMinimum;
24836
+ }
24837
+ }
24838
+ if (typeof minimum === "number") {
24839
+ json.minimum = minimum;
24840
+ if (typeof exclusiveMinimum === "number" && ctx.target !== "draft-04") {
24841
+ if (exclusiveMinimum >= minimum)
24842
+ delete json.minimum;
24843
+ else
24844
+ delete json.exclusiveMinimum;
24845
+ }
24846
+ }
24847
+ if (typeof exclusiveMaximum === "number") {
24848
+ if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") {
24849
+ json.maximum = exclusiveMaximum;
24850
+ json.exclusiveMaximum = true;
24851
+ }
24852
+ else {
24853
+ json.exclusiveMaximum = exclusiveMaximum;
24854
+ }
24855
+ }
24856
+ if (typeof maximum === "number") {
24857
+ json.maximum = maximum;
24858
+ if (typeof exclusiveMaximum === "number" && ctx.target !== "draft-04") {
24859
+ if (exclusiveMaximum <= maximum)
24860
+ delete json.maximum;
24861
+ else
24862
+ delete json.exclusiveMaximum;
24863
+ }
24864
+ }
24865
+ if (typeof multipleOf === "number")
24866
+ json.multipleOf = multipleOf;
24867
+ };
24868
+ const neverProcessor = (_schema, _ctx, json, _params) => {
24869
+ json.not = {};
24870
+ };
24871
+ const anyProcessor = (_schema, _ctx, _json, _params) => {
24872
+ // empty schema accepts anything
24873
+ };
24874
+ const unknownProcessor = (_schema, _ctx, _json, _params) => {
24875
+ // empty schema accepts anything
24876
+ };
24877
+ const enumProcessor = (schema, _ctx, json, _params) => {
24878
+ const def = schema._zod.def;
24879
+ const values = getEnumValues(def.entries);
24880
+ // Number enums can have both string and number values
24881
+ if (values.every((v) => typeof v === "number"))
24882
+ json.type = "number";
24883
+ if (values.every((v) => typeof v === "string"))
24884
+ json.type = "string";
24885
+ json.enum = values;
24886
+ };
24887
+ const customProcessor = (_schema, ctx, _json, _params) => {
24888
+ if (ctx.unrepresentable === "throw") {
24889
+ throw new Error("Custom types cannot be represented in JSON Schema");
24890
+ }
24891
+ };
24892
+ const transformProcessor = (_schema, ctx, _json, _params) => {
24893
+ if (ctx.unrepresentable === "throw") {
24894
+ throw new Error("Transforms cannot be represented in JSON Schema");
24895
+ }
24896
+ };
24897
+ // ==================== COMPOSITE TYPE PROCESSORS ====================
24898
+ const arrayProcessor = (schema, ctx, _json, params) => {
24899
+ const json = _json;
24900
+ const def = schema._zod.def;
24901
+ const { minimum, maximum } = schema._zod.bag;
24902
+ if (typeof minimum === "number")
24903
+ json.minItems = minimum;
24904
+ if (typeof maximum === "number")
24905
+ json.maxItems = maximum;
24906
+ json.type = "array";
24907
+ json.items = process$1(def.element, ctx, { ...params, path: [...params.path, "items"] });
24908
+ };
24909
+ const objectProcessor = (schema, ctx, _json, params) => {
24910
+ const json = _json;
24911
+ const def = schema._zod.def;
24912
+ json.type = "object";
24913
+ json.properties = {};
24914
+ const shape = def.shape;
24915
+ for (const key in shape) {
24916
+ json.properties[key] = process$1(shape[key], ctx, {
24917
+ ...params,
24918
+ path: [...params.path, "properties", key],
24919
+ });
24920
+ }
24921
+ // required keys
24922
+ const allKeys = new Set(Object.keys(shape));
24923
+ const requiredKeys = new Set([...allKeys].filter((key) => {
24924
+ const v = def.shape[key]._zod;
24925
+ if (ctx.io === "input") {
24926
+ return v.optin === undefined;
24927
+ }
24928
+ else {
24929
+ return v.optout === undefined;
24930
+ }
24931
+ }));
24932
+ if (requiredKeys.size > 0) {
24933
+ json.required = Array.from(requiredKeys);
24934
+ }
24935
+ // catchall
24936
+ if (def.catchall?._zod.def.type === "never") {
24937
+ // strict
24938
+ json.additionalProperties = false;
24939
+ }
24940
+ else if (!def.catchall) {
24941
+ // regular
24942
+ if (ctx.io === "output")
24943
+ json.additionalProperties = false;
24944
+ }
24945
+ else if (def.catchall) {
24946
+ json.additionalProperties = process$1(def.catchall, ctx, {
24947
+ ...params,
24948
+ path: [...params.path, "additionalProperties"],
24949
+ });
24950
+ }
24951
+ };
24952
+ const unionProcessor = (schema, ctx, json, params) => {
24953
+ const def = schema._zod.def;
24954
+ // Exclusive unions (inclusive === false) use oneOf (exactly one match) instead of anyOf (one or more matches)
24955
+ // This includes both z.xor() and discriminated unions
24956
+ const isExclusive = def.inclusive === false;
24957
+ const options = def.options.map((x, i) => process$1(x, ctx, {
24958
+ ...params,
24959
+ path: [...params.path, isExclusive ? "oneOf" : "anyOf", i],
24960
+ }));
24961
+ if (isExclusive) {
24962
+ json.oneOf = options;
24963
+ }
24964
+ else {
24965
+ json.anyOf = options;
24966
+ }
24967
+ };
24968
+ const intersectionProcessor = (schema, ctx, json, params) => {
24969
+ const def = schema._zod.def;
24970
+ const a = process$1(def.left, ctx, {
24971
+ ...params,
24972
+ path: [...params.path, "allOf", 0],
24973
+ });
24974
+ const b = process$1(def.right, ctx, {
24975
+ ...params,
24976
+ path: [...params.path, "allOf", 1],
24977
+ });
24978
+ const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
24979
+ const allOf = [
24980
+ ...(isSimpleIntersection(a) ? a.allOf : [a]),
24981
+ ...(isSimpleIntersection(b) ? b.allOf : [b]),
24982
+ ];
24983
+ json.allOf = allOf;
24984
+ };
24985
+ const nullableProcessor = (schema, ctx, json, params) => {
24986
+ const def = schema._zod.def;
24987
+ const inner = process$1(def.innerType, ctx, params);
24988
+ const seen = ctx.seen.get(schema);
24989
+ if (ctx.target === "openapi-3.0") {
24990
+ seen.ref = def.innerType;
24991
+ json.nullable = true;
24992
+ }
24993
+ else {
24994
+ json.anyOf = [inner, { type: "null" }];
24995
+ }
24996
+ };
24997
+ const nonoptionalProcessor = (schema, ctx, _json, params) => {
24998
+ const def = schema._zod.def;
24999
+ process$1(def.innerType, ctx, params);
25000
+ const seen = ctx.seen.get(schema);
25001
+ seen.ref = def.innerType;
25002
+ };
25003
+ const defaultProcessor = (schema, ctx, json, params) => {
25004
+ const def = schema._zod.def;
25005
+ process$1(def.innerType, ctx, params);
25006
+ const seen = ctx.seen.get(schema);
25007
+ seen.ref = def.innerType;
25008
+ json.default = JSON.parse(JSON.stringify(def.defaultValue));
25009
+ };
25010
+ const prefaultProcessor = (schema, ctx, json, params) => {
25011
+ const def = schema._zod.def;
25012
+ process$1(def.innerType, ctx, params);
25013
+ const seen = ctx.seen.get(schema);
25014
+ seen.ref = def.innerType;
25015
+ if (ctx.io === "input")
25016
+ json._prefault = JSON.parse(JSON.stringify(def.defaultValue));
25017
+ };
25018
+ const catchProcessor = (schema, ctx, json, params) => {
25019
+ const def = schema._zod.def;
25020
+ process$1(def.innerType, ctx, params);
25021
+ const seen = ctx.seen.get(schema);
25022
+ seen.ref = def.innerType;
25023
+ let catchValue;
25024
+ try {
25025
+ catchValue = def.catchValue(undefined);
25026
+ }
25027
+ catch {
25028
+ throw new Error("Dynamic catch values are not supported in JSON Schema");
25029
+ }
25030
+ json.default = catchValue;
25031
+ };
25032
+ const pipeProcessor = (schema, ctx, _json, params) => {
25033
+ const def = schema._zod.def;
25034
+ const innerType = ctx.io === "input" ? (def.in._zod.def.type === "transform" ? def.out : def.in) : def.out;
25035
+ process$1(innerType, ctx, params);
25036
+ const seen = ctx.seen.get(schema);
25037
+ seen.ref = innerType;
25038
+ };
25039
+ const readonlyProcessor = (schema, ctx, json, params) => {
25040
+ const def = schema._zod.def;
25041
+ process$1(def.innerType, ctx, params);
25042
+ const seen = ctx.seen.get(schema);
25043
+ seen.ref = def.innerType;
25044
+ json.readOnly = true;
25045
+ };
25046
+ const optionalProcessor = (schema, ctx, _json, params) => {
25047
+ const def = schema._zod.def;
25048
+ process$1(def.innerType, ctx, params);
25049
+ const seen = ctx.seen.get(schema);
25050
+ seen.ref = def.innerType;
25051
+ };
25052
+
23834
25053
  const ZodISODateTime = /*@__PURE__*/ $constructor("ZodISODateTime", (inst, def) => {
23835
25054
  $ZodISODateTime.init(inst, def);
23836
25055
  ZodStringFormat.init(inst, def);
@@ -23921,6 +25140,13 @@ const safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
23921
25140
 
23922
25141
  const ZodType = /*@__PURE__*/ $constructor("ZodType", (inst, def) => {
23923
25142
  $ZodType.init(inst, def);
25143
+ Object.assign(inst["~standard"], {
25144
+ jsonSchema: {
25145
+ input: createStandardJSONSchemaMethod(inst, "input"),
25146
+ output: createStandardJSONSchemaMethod(inst, "output"),
25147
+ },
25148
+ });
25149
+ inst.toJSONSchema = createToJSONSchemaMethod(inst, {});
23924
25150
  inst.def = def;
23925
25151
  inst.type = def.type;
23926
25152
  Object.defineProperty(inst, "_def", { value: def });
@@ -24002,6 +25228,7 @@ const ZodType = /*@__PURE__*/ $constructor("ZodType", (inst, def) => {
24002
25228
  const _ZodString = /*@__PURE__*/ $constructor("_ZodString", (inst, def) => {
24003
25229
  $ZodString.init(inst, def);
24004
25230
  ZodType.init(inst, def);
25231
+ inst._zod.processJSONSchema = (ctx, json, params) => stringProcessor(inst, ctx, json);
24005
25232
  const bag = inst._zod.bag;
24006
25233
  inst.format = bag.format ?? null;
24007
25234
  inst.minLength = bag.minimum ?? null;
@@ -24159,6 +25386,7 @@ const ZodJWT = /*@__PURE__*/ $constructor("ZodJWT", (inst, def) => {
24159
25386
  const ZodNumber = /*@__PURE__*/ $constructor("ZodNumber", (inst, def) => {
24160
25387
  $ZodNumber.init(inst, def);
24161
25388
  ZodType.init(inst, def);
25389
+ inst._zod.processJSONSchema = (ctx, json, params) => numberProcessor(inst, ctx, json);
24162
25390
  inst.gt = (value, params) => inst.check(_gt(value, params));
24163
25391
  inst.gte = (value, params) => inst.check(_gte(value, params));
24164
25392
  inst.min = (value, params) => inst.check(_gte(value, params));
@@ -24197,6 +25425,7 @@ function int(params) {
24197
25425
  const ZodAny = /*@__PURE__*/ $constructor("ZodAny", (inst, def) => {
24198
25426
  $ZodAny.init(inst, def);
24199
25427
  ZodType.init(inst, def);
25428
+ inst._zod.processJSONSchema = (ctx, json, params) => anyProcessor();
24200
25429
  });
24201
25430
  function any() {
24202
25431
  return _any(ZodAny);
@@ -24204,6 +25433,7 @@ function any() {
24204
25433
  const ZodUnknown = /*@__PURE__*/ $constructor("ZodUnknown", (inst, def) => {
24205
25434
  $ZodUnknown.init(inst, def);
24206
25435
  ZodType.init(inst, def);
25436
+ inst._zod.processJSONSchema = (ctx, json, params) => unknownProcessor();
24207
25437
  });
24208
25438
  function unknown() {
24209
25439
  return _unknown(ZodUnknown);
@@ -24211,6 +25441,7 @@ function unknown() {
24211
25441
  const ZodNever = /*@__PURE__*/ $constructor("ZodNever", (inst, def) => {
24212
25442
  $ZodNever.init(inst, def);
24213
25443
  ZodType.init(inst, def);
25444
+ inst._zod.processJSONSchema = (ctx, json, params) => neverProcessor(inst, ctx, json);
24214
25445
  });
24215
25446
  function never(params) {
24216
25447
  return _never(ZodNever, params);
@@ -24218,6 +25449,7 @@ function never(params) {
24218
25449
  const ZodArray = /*@__PURE__*/ $constructor("ZodArray", (inst, def) => {
24219
25450
  $ZodArray.init(inst, def);
24220
25451
  ZodType.init(inst, def);
25452
+ inst._zod.processJSONSchema = (ctx, json, params) => arrayProcessor(inst, ctx, json, params);
24221
25453
  inst.element = def.element;
24222
25454
  inst.min = (minLength, params) => inst.check(_minLength(minLength, params));
24223
25455
  inst.nonempty = (params) => inst.check(_minLength(1, params));
@@ -24231,6 +25463,7 @@ function array(element, params) {
24231
25463
  const ZodObject = /*@__PURE__*/ $constructor("ZodObject", (inst, def) => {
24232
25464
  $ZodObjectJIT.init(inst, def);
24233
25465
  ZodType.init(inst, def);
25466
+ inst._zod.processJSONSchema = (ctx, json, params) => objectProcessor(inst, ctx, json, params);
24234
25467
  defineLazy(inst, "shape", () => {
24235
25468
  return def.shape;
24236
25469
  });
@@ -24263,6 +25496,7 @@ function object(shape, params) {
24263
25496
  const ZodUnion = /*@__PURE__*/ $constructor("ZodUnion", (inst, def) => {
24264
25497
  $ZodUnion.init(inst, def);
24265
25498
  ZodType.init(inst, def);
25499
+ inst._zod.processJSONSchema = (ctx, json, params) => unionProcessor(inst, ctx, json, params);
24266
25500
  inst.options = def.options;
24267
25501
  });
24268
25502
  function union(options, params) {
@@ -24275,6 +25509,7 @@ function union(options, params) {
24275
25509
  const ZodIntersection = /*@__PURE__*/ $constructor("ZodIntersection", (inst, def) => {
24276
25510
  $ZodIntersection.init(inst, def);
24277
25511
  ZodType.init(inst, def);
25512
+ inst._zod.processJSONSchema = (ctx, json, params) => intersectionProcessor(inst, ctx, json, params);
24278
25513
  });
24279
25514
  function intersection(left, right) {
24280
25515
  return new ZodIntersection({
@@ -24286,6 +25521,7 @@ function intersection(left, right) {
24286
25521
  const ZodEnum = /*@__PURE__*/ $constructor("ZodEnum", (inst, def) => {
24287
25522
  $ZodEnum.init(inst, def);
24288
25523
  ZodType.init(inst, def);
25524
+ inst._zod.processJSONSchema = (ctx, json, params) => enumProcessor(inst, ctx, json);
24289
25525
  inst.enum = def.entries;
24290
25526
  inst.options = Object.values(def.entries);
24291
25527
  const keys = new Set(Object.keys(def.entries));
@@ -24333,6 +25569,7 @@ function _enum(values, params) {
24333
25569
  const ZodTransform = /*@__PURE__*/ $constructor("ZodTransform", (inst, def) => {
24334
25570
  $ZodTransform.init(inst, def);
24335
25571
  ZodType.init(inst, def);
25572
+ inst._zod.processJSONSchema = (ctx, json, params) => transformProcessor(inst, ctx);
24336
25573
  inst._zod.parse = (payload, _ctx) => {
24337
25574
  if (_ctx.direction === "backward") {
24338
25575
  throw new $ZodEncodeError(inst.constructor.name);
@@ -24373,6 +25610,7 @@ function transform(fn) {
24373
25610
  const ZodOptional = /*@__PURE__*/ $constructor("ZodOptional", (inst, def) => {
24374
25611
  $ZodOptional.init(inst, def);
24375
25612
  ZodType.init(inst, def);
25613
+ inst._zod.processJSONSchema = (ctx, json, params) => optionalProcessor(inst, ctx, json, params);
24376
25614
  inst.unwrap = () => inst._zod.def.innerType;
24377
25615
  });
24378
25616
  function optional(innerType) {
@@ -24384,6 +25622,7 @@ function optional(innerType) {
24384
25622
  const ZodNullable = /*@__PURE__*/ $constructor("ZodNullable", (inst, def) => {
24385
25623
  $ZodNullable.init(inst, def);
24386
25624
  ZodType.init(inst, def);
25625
+ inst._zod.processJSONSchema = (ctx, json, params) => nullableProcessor(inst, ctx, json, params);
24387
25626
  inst.unwrap = () => inst._zod.def.innerType;
24388
25627
  });
24389
25628
  function nullable(innerType) {
@@ -24395,6 +25634,7 @@ function nullable(innerType) {
24395
25634
  const ZodDefault = /*@__PURE__*/ $constructor("ZodDefault", (inst, def) => {
24396
25635
  $ZodDefault.init(inst, def);
24397
25636
  ZodType.init(inst, def);
25637
+ inst._zod.processJSONSchema = (ctx, json, params) => defaultProcessor(inst, ctx, json, params);
24398
25638
  inst.unwrap = () => inst._zod.def.innerType;
24399
25639
  inst.removeDefault = inst.unwrap;
24400
25640
  });
@@ -24410,6 +25650,7 @@ function _default(innerType, defaultValue) {
24410
25650
  const ZodPrefault = /*@__PURE__*/ $constructor("ZodPrefault", (inst, def) => {
24411
25651
  $ZodPrefault.init(inst, def);
24412
25652
  ZodType.init(inst, def);
25653
+ inst._zod.processJSONSchema = (ctx, json, params) => prefaultProcessor(inst, ctx, json, params);
24413
25654
  inst.unwrap = () => inst._zod.def.innerType;
24414
25655
  });
24415
25656
  function prefault(innerType, defaultValue) {
@@ -24424,6 +25665,7 @@ function prefault(innerType, defaultValue) {
24424
25665
  const ZodNonOptional = /*@__PURE__*/ $constructor("ZodNonOptional", (inst, def) => {
24425
25666
  $ZodNonOptional.init(inst, def);
24426
25667
  ZodType.init(inst, def);
25668
+ inst._zod.processJSONSchema = (ctx, json, params) => nonoptionalProcessor(inst, ctx, json, params);
24427
25669
  inst.unwrap = () => inst._zod.def.innerType;
24428
25670
  });
24429
25671
  function nonoptional(innerType, params) {
@@ -24436,6 +25678,7 @@ function nonoptional(innerType, params) {
24436
25678
  const ZodCatch = /*@__PURE__*/ $constructor("ZodCatch", (inst, def) => {
24437
25679
  $ZodCatch.init(inst, def);
24438
25680
  ZodType.init(inst, def);
25681
+ inst._zod.processJSONSchema = (ctx, json, params) => catchProcessor(inst, ctx, json, params);
24439
25682
  inst.unwrap = () => inst._zod.def.innerType;
24440
25683
  inst.removeCatch = inst.unwrap;
24441
25684
  });
@@ -24449,6 +25692,7 @@ function _catch(innerType, catchValue) {
24449
25692
  const ZodPipe = /*@__PURE__*/ $constructor("ZodPipe", (inst, def) => {
24450
25693
  $ZodPipe.init(inst, def);
24451
25694
  ZodType.init(inst, def);
25695
+ inst._zod.processJSONSchema = (ctx, json, params) => pipeProcessor(inst, ctx, json, params);
24452
25696
  inst.in = def.in;
24453
25697
  inst.out = def.out;
24454
25698
  });
@@ -24463,6 +25707,7 @@ function pipe(in_, out) {
24463
25707
  const ZodReadonly = /*@__PURE__*/ $constructor("ZodReadonly", (inst, def) => {
24464
25708
  $ZodReadonly.init(inst, def);
24465
25709
  ZodType.init(inst, def);
25710
+ inst._zod.processJSONSchema = (ctx, json, params) => readonlyProcessor(inst, ctx, json, params);
24466
25711
  inst.unwrap = () => inst._zod.def.innerType;
24467
25712
  });
24468
25713
  function readonly(innerType) {
@@ -24474,6 +25719,7 @@ function readonly(innerType) {
24474
25719
  const ZodCustom = /*@__PURE__*/ $constructor("ZodCustom", (inst, def) => {
24475
25720
  $ZodCustom.init(inst, def);
24476
25721
  ZodType.init(inst, def);
25722
+ inst._zod.processJSONSchema = (ctx, json, params) => customProcessor(inst, ctx);
24477
25723
  });
24478
25724
  function refine(fn, _params = {}) {
24479
25725
  return _refine(ZodCustom, fn, _params);
@@ -24682,6 +25928,7 @@ let RpgMap = class extends RpgCommonMap {
24682
25928
  if (isTest) {
24683
25929
  this.autoSync = false;
24684
25930
  this.setAutoTick(false);
25931
+ this.autoTickEnabled = false;
24685
25932
  this.throttleSync = 0;
24686
25933
  this.throttleStorage = 0;
24687
25934
  } else {
@@ -24893,7 +26140,7 @@ let RpgMap = class extends RpgCommonMap {
24893
26140
  player.conn = conn;
24894
26141
  player._onInit();
24895
26142
  this.dataIsReady$.pipe(
24896
- finalize(async () => {
26143
+ finalize$1(async () => {
24897
26144
  if (this.stopAllSoundsBeforeJoin) {
24898
26145
  player.stopAllSounds();
24899
26146
  }
@@ -25473,8 +26720,7 @@ let RpgMap = class extends RpgCommonMap {
25473
26720
  }
25474
26721
  eventInstance.map = this;
25475
26722
  eventInstance.context = context$1;
25476
- eventInstance.x.set(x);
25477
- eventInstance.y.set(y);
26723
+ await eventInstance.teleport({ x, y });
25478
26724
  this.events()[id] = eventInstance;
25479
26725
  await eventInstance.execMethod("onInit");
25480
26726
  }