@dooboostore/simple-boot-http-server 1.0.26 → 1.0.28

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.
Files changed (71) hide show
  1. package/README.md +138 -17
  2. package/dist/cjs/SimpleBootHttpServer.js +33 -16
  3. package/dist/cjs/SimpleBootHttpServer.js.map +2 -2
  4. package/dist/cjs/codes/Mimes.js +2 -0
  5. package/dist/cjs/codes/Mimes.js.map +2 -2
  6. package/dist/cjs/decorators/MethodMapping.js +2 -2
  7. package/dist/cjs/decorators/MethodMapping.js.map +2 -2
  8. package/dist/cjs/filters/ResourceFilter.js +0 -1
  9. package/dist/cjs/filters/ResourceFilter.js.map +2 -2
  10. package/dist/cjs/models/RequestResponse.js +52 -0
  11. package/dist/cjs/models/RequestResponse.js.map +3 -3
  12. package/dist/cjs/proxy/RequestResponseInjectProxy.js +35 -0
  13. package/dist/cjs/proxy/RequestResponseInjectProxy.js.map +7 -0
  14. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js +1 -1
  15. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js.map +2 -2
  16. package/dist/cjs/proxy/index.js +3 -1
  17. package/dist/cjs/proxy/index.js.map +2 -2
  18. package/dist/cjs/resolvers/Resolver.js.map +1 -1
  19. package/dist/cjs/websocket/WebSocketManager.js +68 -40
  20. package/dist/cjs/websocket/WebSocketManager.js.map +2 -2
  21. package/dist/esm/SimpleBootHttpServer.js +34 -17
  22. package/dist/esm/SimpleBootHttpServer.js.map +2 -2
  23. package/dist/esm/codes/Mimes.js +2 -0
  24. package/dist/esm/codes/Mimes.js.map +2 -2
  25. package/dist/esm/decorators/MethodMapping.js +2 -2
  26. package/dist/esm/decorators/MethodMapping.js.map +2 -2
  27. package/dist/esm/filters/ResourceFilter.js +0 -1
  28. package/dist/esm/filters/ResourceFilter.js.map +2 -2
  29. package/dist/esm/models/RequestResponse.js +52 -0
  30. package/dist/esm/models/RequestResponse.js.map +2 -2
  31. package/dist/esm/proxy/RequestResponseInjectProxy.js +12 -0
  32. package/dist/esm/proxy/RequestResponseInjectProxy.js.map +7 -0
  33. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js +1 -1
  34. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js.map +2 -2
  35. package/dist/esm/proxy/index.js +1 -0
  36. package/dist/esm/proxy/index.js.map +2 -2
  37. package/dist/esm/websocket/WebSocketManager.js +68 -40
  38. package/dist/esm/websocket/WebSocketManager.js.map +2 -2
  39. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js +572 -387
  40. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js.map +4 -4
  41. package/dist/types/SimpleBootHttpServer.d.ts.map +1 -1
  42. package/dist/types/codes/Mimes.d.ts +2 -0
  43. package/dist/types/codes/Mimes.d.ts.map +1 -1
  44. package/dist/types/decorators/MethodMapping.d.ts +13 -8
  45. package/dist/types/decorators/MethodMapping.d.ts.map +1 -1
  46. package/dist/types/filters/ResourceFilter.d.ts.map +1 -1
  47. package/dist/types/models/RequestResponse.d.ts +9 -0
  48. package/dist/types/models/RequestResponse.d.ts.map +1 -1
  49. package/dist/types/proxy/RequestResponseInjectProxy.d.ts +22 -0
  50. package/dist/types/proxy/RequestResponseInjectProxy.d.ts.map +1 -0
  51. package/dist/types/proxy/index.d.ts +1 -0
  52. package/dist/types/proxy/index.d.ts.map +1 -1
  53. package/dist/types/resolvers/Resolver.d.ts +2 -1
  54. package/dist/types/resolvers/Resolver.d.ts.map +1 -1
  55. package/dist/types/websocket/WebSocketManager.d.ts +3 -1
  56. package/dist/types/websocket/WebSocketManager.d.ts.map +1 -1
  57. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js +572 -387
  58. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js.map +4 -4
  59. package/dist/umd-bundle/websocket-client.umd.js +315 -149
  60. package/dist/umd-bundle/websocket-client.umd.js.map +4 -4
  61. package/package.json +9 -9
  62. package/src/SimpleBootHttpServer.ts +38 -17
  63. package/src/codes/Mimes.ts +2 -0
  64. package/src/decorators/MethodMapping.ts +151 -152
  65. package/src/filters/ResourceFilter.ts +0 -1
  66. package/src/models/RequestResponse.ts +50 -0
  67. package/src/proxy/RequestResponseInjectProxy.ts +30 -0
  68. package/src/proxy/SymbolIntentApiServiceProxy.ts +1 -1
  69. package/src/proxy/index.ts +1 -0
  70. package/src/resolvers/Resolver.ts +2 -1
  71. package/src/websocket/WebSocketManager.ts +69 -41
@@ -36,9 +36,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
36
36
  ));
37
37
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
38
 
39
- // ../../node_modules/.pnpm/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js
39
+ // ../../../node_modules/.pnpm/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js
40
40
  var require_Reflect = __commonJS({
41
- "../../node_modules/.pnpm/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js"() {
41
+ "../../../node_modules/.pnpm/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js"() {
42
42
  var Reflect2;
43
43
  (function(Reflect3) {
44
44
  (function(factory) {
@@ -1121,9 +1121,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
1121
1121
  }
1122
1122
  });
1123
1123
 
1124
- // ../../node_modules/.pnpm/mime-db@1.52.0/node_modules/mime-db/db.json
1124
+ // ../../../node_modules/.pnpm/mime-db@1.52.0/node_modules/mime-db/db.json
1125
1125
  var require_db = __commonJS({
1126
- "../../node_modules/.pnpm/mime-db@1.52.0/node_modules/mime-db/db.json"(exports, module) {
1126
+ "../../../node_modules/.pnpm/mime-db@1.52.0/node_modules/mime-db/db.json"(exports, module) {
1127
1127
  module.exports = {
1128
1128
  "application/1d-interleaved-parityfec": {
1129
1129
  source: "iana"
@@ -9646,16 +9646,16 @@ var dooboostoreSimpleBootHttpServer = (() => {
9646
9646
  }
9647
9647
  });
9648
9648
 
9649
- // ../../node_modules/.pnpm/mime-db@1.52.0/node_modules/mime-db/index.js
9649
+ // ../../../node_modules/.pnpm/mime-db@1.52.0/node_modules/mime-db/index.js
9650
9650
  var require_mime_db = __commonJS({
9651
- "../../node_modules/.pnpm/mime-db@1.52.0/node_modules/mime-db/index.js"(exports, module) {
9651
+ "../../../node_modules/.pnpm/mime-db@1.52.0/node_modules/mime-db/index.js"(exports, module) {
9652
9652
  module.exports = require_db();
9653
9653
  }
9654
9654
  });
9655
9655
 
9656
- // ../../node_modules/.pnpm/mime-types@2.1.35/node_modules/mime-types/index.js
9656
+ // ../../../node_modules/.pnpm/mime-types@2.1.35/node_modules/mime-types/index.js
9657
9657
  var require_mime_types = __commonJS({
9658
- "../../node_modules/.pnpm/mime-types@2.1.35/node_modules/mime-types/index.js"(exports) {
9658
+ "../../../node_modules/.pnpm/mime-types@2.1.35/node_modules/mime-types/index.js"(exports) {
9659
9659
  "use strict";
9660
9660
  var db = require_mime_db();
9661
9661
  var extname2 = __require("path").extname;
@@ -9743,9 +9743,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
9743
9743
  }
9744
9744
  });
9745
9745
 
9746
- // ../../node_modules/.pnpm/node-gzip@1.1.2/node_modules/node-gzip/dist/index.js
9746
+ // ../../../node_modules/.pnpm/node-gzip@1.1.2/node_modules/node-gzip/dist/index.js
9747
9747
  var require_dist = __commonJS({
9748
- "../../node_modules/.pnpm/node-gzip@1.1.2/node_modules/node-gzip/dist/index.js"(exports, module) {
9748
+ "../../../node_modules/.pnpm/node-gzip@1.1.2/node_modules/node-gzip/dist/index.js"(exports, module) {
9749
9749
  "use strict";
9750
9750
  var zlib = __require("zlib");
9751
9751
  module.exports = {
@@ -9771,9 +9771,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
9771
9771
  }
9772
9772
  });
9773
9773
 
9774
- // ../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/helpers.js
9774
+ // ../../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/helpers.js
9775
9775
  var require_helpers = __commonJS({
9776
- "../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/helpers.js"(exports) {
9776
+ "../../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/helpers.js"(exports) {
9777
9777
  var __extends = exports && exports.__extends || /* @__PURE__ */ function() {
9778
9778
  var extendStatics = function(d, b) {
9779
9779
  extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
@@ -9939,9 +9939,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
9939
9939
  }
9940
9940
  });
9941
9941
 
9942
- // ../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/core.js
9942
+ // ../../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/core.js
9943
9943
  var require_core = __commonJS({
9944
- "../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/core.js"(exports) {
9944
+ "../../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/core.js"(exports) {
9945
9945
  Object.defineProperty(exports, "__esModule", { value: true });
9946
9946
  var helpers_js_1 = require_helpers();
9947
9947
  exports.JsonPatchError = helpers_js_1.PatchError;
@@ -10272,9 +10272,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
10272
10272
  }
10273
10273
  });
10274
10274
 
10275
- // ../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/duplex.js
10275
+ // ../../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/duplex.js
10276
10276
  var require_duplex = __commonJS({
10277
- "../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/duplex.js"(exports) {
10277
+ "../../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/commonjs/duplex.js"(exports) {
10278
10278
  Object.defineProperty(exports, "__esModule", { value: true });
10279
10279
  var helpers_js_1 = require_helpers();
10280
10280
  var core_js_1 = require_core();
@@ -10446,9 +10446,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
10446
10446
  }
10447
10447
  });
10448
10448
 
10449
- // ../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/index.js
10449
+ // ../../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/index.js
10450
10450
  var require_fast_json_patch = __commonJS({
10451
- "../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/index.js"(exports) {
10451
+ "../../../node_modules/.pnpm/fast-json-patch@3.1.1/node_modules/fast-json-patch/index.js"(exports) {
10452
10452
  var core = require_core();
10453
10453
  Object.assign(exports, core);
10454
10454
  var duplex = require_duplex();
@@ -10461,9 +10461,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
10461
10461
  }
10462
10462
  });
10463
10463
 
10464
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js
10464
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/constants.js
10465
10465
  var require_constants = __commonJS({
10466
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js"(exports, module) {
10466
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/constants.js"(exports, module) {
10467
10467
  "use strict";
10468
10468
  var BINARY_TYPES = ["nodebuffer", "arraybuffer", "fragments"];
10469
10469
  var hasBlob = typeof Blob !== "undefined";
@@ -10484,9 +10484,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
10484
10484
  }
10485
10485
  });
10486
10486
 
10487
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/buffer-util.js
10487
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/buffer-util.js
10488
10488
  var require_buffer_util = __commonJS({
10489
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/buffer-util.js"(exports, module) {
10489
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/buffer-util.js"(exports, module) {
10490
10490
  "use strict";
10491
10491
  var { EMPTY_BUFFER } = require_constants();
10492
10492
  var FastBuffer = Buffer[Symbol.species];
@@ -10559,9 +10559,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
10559
10559
  }
10560
10560
  });
10561
10561
 
10562
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/limiter.js
10562
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/limiter.js
10563
10563
  var require_limiter = __commonJS({
10564
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/limiter.js"(exports, module) {
10564
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/limiter.js"(exports, module) {
10565
10565
  "use strict";
10566
10566
  var kDone = Symbol("kDone");
10567
10567
  var kRun = Symbol("kRun");
@@ -10609,9 +10609,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
10609
10609
  }
10610
10610
  });
10611
10611
 
10612
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/permessage-deflate.js
10612
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/permessage-deflate.js
10613
10613
  var require_permessage_deflate = __commonJS({
10614
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/permessage-deflate.js"(exports, module) {
10614
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/permessage-deflate.js"(exports, module) {
10615
10615
  "use strict";
10616
10616
  var zlib = __require("zlib");
10617
10617
  var bufferUtil = require_buffer_util();
@@ -10992,9 +10992,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
10992
10992
  }
10993
10993
  });
10994
10994
 
10995
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/validation.js
10995
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/validation.js
10996
10996
  var require_validation = __commonJS({
10997
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/validation.js"(exports, module) {
10997
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/validation.js"(exports, module) {
10998
10998
  "use strict";
10999
10999
  var { isUtf8 } = __require("buffer");
11000
11000
  var { hasBlob } = require_constants();
@@ -11193,9 +11193,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
11193
11193
  }
11194
11194
  });
11195
11195
 
11196
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/receiver.js
11196
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/receiver.js
11197
11197
  var require_receiver = __commonJS({
11198
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/receiver.js"(exports, module) {
11198
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/receiver.js"(exports, module) {
11199
11199
  "use strict";
11200
11200
  var { Writable } = __require("stream");
11201
11201
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -11228,10 +11228,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
11228
11228
  * extensions
11229
11229
  * @param {Boolean} [options.isServer=false] Specifies whether to operate in
11230
11230
  * client or server mode
11231
- * @param {Number} [options.maxBufferedChunks=0] The maximum number of
11232
- * buffered data chunks
11233
- * @param {Number} [options.maxFragments=0] The maximum number of message
11234
- * fragments
11235
11231
  * @param {Number} [options.maxPayload=0] The maximum allowed message length
11236
11232
  * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
11237
11233
  * not to skip UTF-8 validation for text and close messages
@@ -11242,8 +11238,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
11242
11238
  this._binaryType = options.binaryType || BINARY_TYPES[0];
11243
11239
  this._extensions = options.extensions || {};
11244
11240
  this._isServer = !!options.isServer;
11245
- this._maxBufferedChunks = options.maxBufferedChunks | 0;
11246
- this._maxFragments = options.maxFragments | 0;
11247
11241
  this._maxPayload = options.maxPayload | 0;
11248
11242
  this._skipUTF8Validation = !!options.skipUTF8Validation;
11249
11243
  this[kWebSocket] = void 0;
@@ -11273,18 +11267,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
11273
11267
  */
11274
11268
  _write(chunk, encoding, cb) {
11275
11269
  if (this._opcode === 8 && this._state == GET_INFO) return cb();
11276
- if (this._maxBufferedChunks > 0 && this._buffers.length >= this._maxBufferedChunks) {
11277
- cb(
11278
- this.createError(
11279
- RangeError,
11280
- "Too many buffered chunks",
11281
- false,
11282
- 1008,
11283
- "WS_ERR_TOO_MANY_BUFFERED_PARTS"
11284
- )
11285
- );
11286
- return;
11287
- }
11288
11270
  this._bufferedBytes += chunk.length;
11289
11271
  this._buffers.push(chunk);
11290
11272
  this.startLoop(cb);
@@ -11614,17 +11596,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
11614
11596
  return;
11615
11597
  }
11616
11598
  if (data.length) {
11617
- if (this._maxFragments > 0 && this._fragments.length >= this._maxFragments) {
11618
- const error = this.createError(
11619
- RangeError,
11620
- "Too many message fragments",
11621
- false,
11622
- 1008,
11623
- "WS_ERR_TOO_MANY_BUFFERED_PARTS"
11624
- );
11625
- cb(error);
11626
- return;
11627
- }
11628
11599
  this._messageLength = this._totalPayloadLength;
11629
11600
  this._fragments.push(data);
11630
11601
  }
@@ -11654,17 +11625,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
11654
11625
  cb(error);
11655
11626
  return;
11656
11627
  }
11657
- if (this._maxFragments > 0 && this._fragments.length >= this._maxFragments) {
11658
- const error = this.createError(
11659
- RangeError,
11660
- "Too many message fragments",
11661
- false,
11662
- 1008,
11663
- "WS_ERR_TOO_MANY_BUFFERED_PARTS"
11664
- );
11665
- cb(error);
11666
- return;
11667
- }
11668
11628
  this._fragments.push(buf);
11669
11629
  }
11670
11630
  this.dataMessage(cb);
@@ -11825,15 +11785,12 @@ var dooboostoreSimpleBootHttpServer = (() => {
11825
11785
  }
11826
11786
  });
11827
11787
 
11828
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/sender.js
11788
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/sender.js
11829
11789
  var require_sender = __commonJS({
11830
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/sender.js"(exports, module) {
11790
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/sender.js"(exports, module) {
11831
11791
  "use strict";
11832
11792
  var { Duplex } = __require("stream");
11833
11793
  var { randomFillSync } = __require("crypto");
11834
- var {
11835
- types: { isUint8Array }
11836
- } = __require("util");
11837
11794
  var PerMessageDeflate2 = require_permessage_deflate();
11838
11795
  var { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants();
11839
11796
  var { isBlob, isValidStatusCode } = require_validation();
@@ -11987,10 +11944,8 @@ var dooboostoreSimpleBootHttpServer = (() => {
11987
11944
  buf.writeUInt16BE(code, 0);
11988
11945
  if (typeof data === "string") {
11989
11946
  buf.write(data, 2);
11990
- } else if (isUint8Array(data)) {
11991
- buf.set(data, 2);
11992
11947
  } else {
11993
- throw new TypeError("Second argument must be a string or a Uint8Array");
11948
+ buf.set(data, 2);
11994
11949
  }
11995
11950
  }
11996
11951
  const options = {
@@ -12318,9 +12273,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
12318
12273
  }
12319
12274
  });
12320
12275
 
12321
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/event-target.js
12276
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/event-target.js
12322
12277
  var require_event_target = __commonJS({
12323
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/event-target.js"(exports, module) {
12278
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/event-target.js"(exports, module) {
12324
12279
  "use strict";
12325
12280
  var { kForOnEventAttribute, kListener } = require_constants();
12326
12281
  var kCode = Symbol("kCode");
@@ -12547,9 +12502,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
12547
12502
  }
12548
12503
  });
12549
12504
 
12550
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/extension.js
12505
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/extension.js
12551
12506
  var require_extension = __commonJS({
12552
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/extension.js"(exports, module) {
12507
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/extension.js"(exports, module) {
12553
12508
  "use strict";
12554
12509
  var { tokenChars } = require_validation();
12555
12510
  function push(dest, name, elem) {
@@ -12700,9 +12655,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
12700
12655
  }
12701
12656
  });
12702
12657
 
12703
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/websocket.js
12658
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/websocket.js
12704
12659
  var require_websocket = __commonJS({
12705
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/websocket.js"(exports, module) {
12660
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/websocket.js"(exports, module) {
12706
12661
  "use strict";
12707
12662
  var EventEmitter = __require("events");
12708
12663
  var https = __require("https");
@@ -12871,10 +12826,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
12871
12826
  * multiple times in the same tick
12872
12827
  * @param {Function} [options.generateMask] The function used to generate the
12873
12828
  * masking key
12874
- * @param {Number} [options.maxBufferedChunks=0] The maximum number of
12875
- * buffered data chunks
12876
- * @param {Number} [options.maxFragments=0] The maximum number of message
12877
- * fragments
12878
12829
  * @param {Number} [options.maxPayload=0] The maximum allowed message size
12879
12830
  * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
12880
12831
  * not to skip UTF-8 validation for text and close messages
@@ -12886,8 +12837,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
12886
12837
  binaryType: this.binaryType,
12887
12838
  extensions: this._extensions,
12888
12839
  isServer: this._isServer,
12889
- maxBufferedChunks: options.maxBufferedChunks,
12890
- maxFragments: options.maxFragments,
12891
12840
  maxPayload: options.maxPayload,
12892
12841
  skipUTF8Validation: options.skipUTF8Validation
12893
12842
  });
@@ -13187,8 +13136,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
13187
13136
  autoPong: true,
13188
13137
  closeTimeout: CLOSE_TIMEOUT,
13189
13138
  protocolVersion: protocolVersions[1],
13190
- maxBufferedChunks: 1024 * 1024,
13191
- maxFragments: 128 * 1024,
13192
13139
  maxPayload: 100 * 1024 * 1024,
13193
13140
  skipUTF8Validation: false,
13194
13141
  perMessageDeflate: true,
@@ -13431,8 +13378,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
13431
13378
  websocket.setSocket(socket, head, {
13432
13379
  allowSynchronousEvents: opts.allowSynchronousEvents,
13433
13380
  generateMask: opts.generateMask,
13434
- maxBufferedChunks: opts.maxBufferedChunks,
13435
- maxFragments: opts.maxFragments,
13436
13381
  maxPayload: opts.maxPayload,
13437
13382
  skipUTF8Validation: opts.skipUTF8Validation
13438
13383
  });
@@ -13596,9 +13541,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
13596
13541
  }
13597
13542
  });
13598
13543
 
13599
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/stream.js
13544
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/stream.js
13600
13545
  var require_stream = __commonJS({
13601
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/stream.js"(exports, module) {
13546
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/stream.js"(exports, module) {
13602
13547
  "use strict";
13603
13548
  var WebSocket3 = require_websocket();
13604
13549
  var { Duplex } = __require("stream");
@@ -13694,9 +13639,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
13694
13639
  }
13695
13640
  });
13696
13641
 
13697
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/subprotocol.js
13642
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/subprotocol.js
13698
13643
  var require_subprotocol = __commonJS({
13699
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/subprotocol.js"(exports, module) {
13644
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/subprotocol.js"(exports, module) {
13700
13645
  "use strict";
13701
13646
  var { tokenChars } = require_validation();
13702
13647
  function parse2(header) {
@@ -13739,9 +13684,9 @@ var dooboostoreSimpleBootHttpServer = (() => {
13739
13684
  }
13740
13685
  });
13741
13686
 
13742
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/websocket-server.js
13687
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/websocket-server.js
13743
13688
  var require_websocket_server = __commonJS({
13744
- "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/websocket-server.js"(exports, module) {
13689
+ "../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/websocket-server.js"(exports, module) {
13745
13690
  "use strict";
13746
13691
  var EventEmitter = __require("events");
13747
13692
  var http = __require("http");
@@ -13775,10 +13720,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
13775
13720
  * called
13776
13721
  * @param {Function} [options.handleProtocols] A hook to handle protocols
13777
13722
  * @param {String} [options.host] The hostname where to bind the server
13778
- * @param {Number} [options.maxBufferedChunks=1048576] The maximum number of
13779
- * buffered data chunks
13780
- * @param {Number} [options.maxFragments=131072] The maximum number of message
13781
- * fragments
13782
13723
  * @param {Number} [options.maxPayload=104857600] The maximum allowed message
13783
13724
  * size
13784
13725
  * @param {Boolean} [options.noServer=false] Enable no server mode
@@ -13800,8 +13741,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
13800
13741
  options = {
13801
13742
  allowSynchronousEvents: true,
13802
13743
  autoPong: true,
13803
- maxBufferedChunks: 1024 * 1024,
13804
- maxFragments: 128 * 1024,
13805
13744
  maxPayload: 100 * 1024 * 1024,
13806
13745
  skipUTF8Validation: false,
13807
13746
  perMessageDeflate: false,
@@ -14081,8 +14020,6 @@ var dooboostoreSimpleBootHttpServer = (() => {
14081
14020
  socket.removeListener("error", socketOnError);
14082
14021
  ws.setSocket(socket, head, {
14083
14022
  allowSynchronousEvents: this.options.allowSynchronousEvents,
14084
- maxBufferedChunks: this.options.maxBufferedChunks,
14085
- maxFragments: this.options.maxFragments,
14086
14023
  maxPayload: this.options.maxPayload,
14087
14024
  skipUTF8Validation: this.options.skipUTF8Validation
14088
14025
  });
@@ -14221,6 +14158,7 @@ var dooboostoreSimpleBootHttpServer = (() => {
14221
14158
  getUrlMapping: () => getUrlMapping,
14222
14159
  getUrlMappings: () => getUrlMappings,
14223
14160
  headMethod: () => headMethod,
14161
+ injectRequestResponse: () => injectRequestResponse,
14224
14162
  isDataDist: () => isDataDist,
14225
14163
  isPathDist: () => isPathDist,
14226
14164
  makeIntentHeaderBySymbolFor: () => makeIntentHeaderBySymbolFor,
@@ -14260,6 +14198,8 @@ var dooboostoreSimpleBootHttpServer = (() => {
14260
14198
  Mimes2["ImageXpixmap"] = "image/x-xpixmap";
14261
14199
  Mimes2["ImageXxbm"] = "image/x-xbm";
14262
14200
  Mimes2["MultipartFormData"] = "multipart/form-data";
14201
+ Mimes2["TextEventStream"] = "text/event-stream";
14202
+ Mimes2["ApplicationXndjson"] = "application/x-ndjson";
14263
14203
  Mimes2["ApplicationJsonPostSimpleBootSsrIntentScheme"] = "application/json-post+simple-boot-ssr-intent-scheme";
14264
14204
  Mimes2["Intent"] = "intent";
14265
14205
  return Mimes2;
@@ -14392,6 +14332,7 @@ var dooboostoreSimpleBootHttpServer = (() => {
14392
14332
  Fetcher: () => Fetcher,
14393
14333
  FormValidator: () => FormValidator,
14394
14334
  FunctionUtils: () => FunctionUtils,
14335
+ HashUtils: () => HashUtils,
14395
14336
  HttpFetcher: () => HttpFetcher,
14396
14337
  HttpJsonFetcher: () => HttpJsonFetcher,
14397
14338
  HttpResponseError: () => HttpResponseError,
@@ -14472,6 +14413,7 @@ var dooboostoreSimpleBootHttpServer = (() => {
14472
14413
  isCssCommentItem: () => isCssCommentItem,
14473
14414
  isCssDeclarationItem: () => isCssDeclarationItem,
14474
14415
  isCssRuleItem: () => isCssRuleItem,
14416
+ isDefined: () => isDefined,
14475
14417
  isHttpResponseError: () => isHttpResponseError,
14476
14418
  isPoint2DType: () => isPoint2DType,
14477
14419
  isPoint3DType: () => isPoint3DType,
@@ -14517,6 +14459,12 @@ var dooboostoreSimpleBootHttpServer = (() => {
14517
14459
  return false;
14518
14460
  }
14519
14461
  };
14462
+ ValidUtils22.isGenerator = (value) => {
14463
+ return value !== null && typeof value === "object" && typeof value.next === "function" && typeof value[Symbol.iterator] === "function";
14464
+ };
14465
+ ValidUtils22.isAsyncGenerator = (value) => {
14466
+ return value !== null && typeof value === "object" && typeof value.next === "function" && typeof value[Symbol.asyncIterator] === "function";
14467
+ };
14520
14468
  ValidUtils22.isFrozen = (obj) => {
14521
14469
  return Object.isFrozen(obj);
14522
14470
  };
@@ -16431,6 +16379,12 @@ var dooboostoreSimpleBootHttpServer = (() => {
16431
16379
  this.z = z ?? 0;
16432
16380
  }
16433
16381
  }
16382
+ /**
16383
+ * 성분 대입 (파괴적). 벡터 전달 시 그 성분을 복사.
16384
+ * @example
16385
+ * v.set(1, 2, 3); // v = (1, 2, 3)
16386
+ * v.set(otherVector); // v = other와 동일 성분
16387
+ */
16434
16388
  set(v, y = 0, z = 0) {
16435
16389
  if (v instanceof _Vector || v instanceof Point3D) {
16436
16390
  this.set(v.x || 0, v.y || 0, v.z || 0);
@@ -16441,16 +16395,45 @@ var dooboostoreSimpleBootHttpServer = (() => {
16441
16395
  }
16442
16396
  return this;
16443
16397
  }
16398
+ /**
16399
+ * 복사본 반환 (비파괴). 파괴적 메서드와 조합해 원본 보존용.
16400
+ * @example
16401
+ * const s = a.get(); s.add(b); // s = a+b, a는 그대로
16402
+ */
16444
16403
  get() {
16445
16404
  return new _Vector(this.x, this.y, this.z);
16446
16405
  }
16447
- // 피타고라스의 정리는 a의 제곱 더하기 b 의 제곱은 c 의 제곱과 같다는 것을 정의합니다.
16448
- mag() {
16406
+ /**
16407
+ * 노름(norm). 평평한 공간(유클리드 공간)에서의 직선 거리.
16408
+ * - 수식: ‖v‖ = √(x² + y² + z²)
16409
+ * - 2D에서는 피타고라스 정리 그 자체. 3D는 두 번 적용한 것과 같음.
16410
+ * (바닥 대각선 √(x²+y²) → 공간 대각선 √((바닥)²+z²))
16411
+ * - "유클리드"는 평평한 공간의 기하학을 말함 (좌표계는 데카르트의 것, 유클리드는 좌표 없이 기하학을 세움).
16412
+ * 휘어진 공간(구면·쌍곡)에서는 이 공식이 성립하지 않음.
16413
+ * @example
16414
+ * new Vector(3, 4, 0).norm(); // 5
16415
+ * new Vector(6, 8, 0).norm(); // 10
16416
+ */
16417
+ norm() {
16449
16418
  const x = this.x;
16450
16419
  const y = this.y;
16451
16420
  const z = this.z;
16452
16421
  return Math.sqrt(x * x + y * y + z * z);
16453
16422
  }
16423
+ /**
16424
+ * norm()의 별칭 (p5.js 호환).
16425
+ * @example
16426
+ * new Vector(3, 4, 0).mag(); // 5
16427
+ */
16428
+ mag() {
16429
+ return this.norm();
16430
+ }
16431
+ /**
16432
+ * 덧셈 (파괴적). 성분별 합. 기하학적으로 평행사변형의 대각선.
16433
+ * - 수식: a + b = (ax+bx, ay+by, az+bz)
16434
+ * @example
16435
+ * const a = new Vector(4, 2); a.add(new Vector(-2, 3)); // a = (2, 5)
16436
+ */
16454
16437
  add(v, y = 0, z = 0) {
16455
16438
  if (v instanceof _Vector || v instanceof Point3D) {
16456
16439
  this.x += v.x;
@@ -16462,12 +16445,24 @@ var dooboostoreSimpleBootHttpServer = (() => {
16462
16445
  this.z += z;
16463
16446
  }
16464
16447
  }
16448
+ /**
16449
+ * 덧셈 결과의 새 벡터 반환 (비파괴).
16450
+ * - 수식: a + b = (ax+bx, ay+by, az+bz)
16451
+ * @example
16452
+ * const s = a.toAdd(a, b); // s = a+b, a·b는 그대로
16453
+ */
16465
16454
  toAdd(v1, v2) {
16466
16455
  return new _Vector(v1.x + v2.x, v1.y + v2.y, v1.x + v2.y);
16467
16456
  }
16468
16457
  // public static add(v1: Vector, v2: Vector): Vector {
16469
16458
  // return new Vector(v1.x + v2.x, v1.y + v2.y, v1.x + v2.y);
16470
16459
  // }
16460
+ /**
16461
+ * 뺄셈 (파괴적). a - b는 "a에서 b를 되돌리는" 벡터.
16462
+ * - 수식: a - b = (ax-bx, ay-by, az-bz)
16463
+ * @example
16464
+ * const a = new Vector(4, 2); a.sub(new Vector(1, 1)); // a = (3, 1)
16465
+ */
16471
16466
  sub(v, y = 0, z = 0) {
16472
16467
  if (v instanceof _Vector || v instanceof Point3D) {
16473
16468
  this.x -= v.x;
@@ -16479,6 +16474,12 @@ var dooboostoreSimpleBootHttpServer = (() => {
16479
16474
  this.z -= z;
16480
16475
  }
16481
16476
  }
16477
+ /**
16478
+ * 뺄셈 결과의 새 벡터 반환 (비파괴).
16479
+ * - 수식: a - b = (ax-bx, ay-by, az-bz)
16480
+ * @example
16481
+ * const d = a.toSub(b); // d = a-b, a·b는 그대로
16482
+ */
16482
16483
  toSub(v2) {
16483
16484
  const v1 = this;
16484
16485
  return new _Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
@@ -16487,6 +16488,12 @@ var dooboostoreSimpleBootHttpServer = (() => {
16487
16488
  // public static sub(v1: Vector, v2: Vector): Vector {
16488
16489
  // return new Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
16489
16490
  // }
16491
+ /**
16492
+ * 스칼라배 또는 성분별 곱 (파괴적). 스칼라 k>1이면 늘어나고, 0<k<1이면 줄어듦. k<0이면 반대 방향.
16493
+ * - 수식(스칼라): k·v = (k·x, k·y, k·z)
16494
+ * @example
16495
+ * const v = new Vector(1, 2); v.mult(3); // v = (3, 6)
16496
+ */
16490
16497
  mult(v) {
16491
16498
  if (v instanceof _Vector || v instanceof Point3D) {
16492
16499
  this.x *= v.x;
@@ -16499,6 +16506,12 @@ var dooboostoreSimpleBootHttpServer = (() => {
16499
16506
  }
16500
16507
  return this;
16501
16508
  }
16509
+ /**
16510
+ * 성분별 곱 결과의 새 벡터 반환 (비파괴).
16511
+ * - 수식: (ax·bx, ay·by, az·bz)
16512
+ * @example
16513
+ * const m = a.toMult(b); // m = 성분별 곱, a·b는 그대로
16514
+ */
16502
16515
  toMult(v2) {
16503
16516
  const v1 = this;
16504
16517
  return new _Vector(v1.x *= v2.x, v1.y *= v2.y, v1.z *= v2.z);
@@ -16506,6 +16519,12 @@ var dooboostoreSimpleBootHttpServer = (() => {
16506
16519
  // public static mult(v1: Vector, v2: Vector) {
16507
16520
  // return new Vector(v1.x *= v2.x, v1.y *= v2.y, v1.z *= v2.z);
16508
16521
  // }
16522
+ /**
16523
+ * 스칼라 나눗셈 또는 성분별 나눗셈 (파괴적). 정규화의 핵심 연산.
16524
+ * - 수식(스칼라): v/k = (x/k, y/k, z/k)
16525
+ * @example
16526
+ * const v = new Vector(6, 8); v.div(2); // v = (3, 4)
16527
+ */
16509
16528
  div(v) {
16510
16529
  if (v instanceof _Vector || v instanceof Point3D) {
16511
16530
  this.x /= v.x;
@@ -16518,6 +16537,12 @@ var dooboostoreSimpleBootHttpServer = (() => {
16518
16537
  }
16519
16538
  return this;
16520
16539
  }
16540
+ /**
16541
+ * 스칼라 나눗셈 결과의 새 벡터 반환 (비파괴).
16542
+ * - 수식: v/k = (x/k, y/k, z/k)
16543
+ * @example
16544
+ * const h = v.toDiv(2); // h = v/2, v는 그대로
16545
+ */
16521
16546
  toDiv(d) {
16522
16547
  const v = this;
16523
16548
  const rv = v.get();
@@ -16533,10 +16558,22 @@ var dooboostoreSimpleBootHttpServer = (() => {
16533
16558
  // rv.z /= d;
16534
16559
  // return rv;
16535
16560
  // }
16561
+ /**
16562
+ * 두 점(벡터) 사이 거리. 차 벡터의 크기.
16563
+ * - 수식: d = √((dx)² + (dy)² + (dz)²)
16564
+ * @example
16565
+ * new Vector(0, 0).dist(new Vector(3, 4)); // 5
16566
+ */
16536
16567
  dist(v) {
16537
16568
  const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
16538
16569
  return Math.sqrt(dx * dx + dy * dy + dz * dz);
16539
16570
  }
16571
+ /**
16572
+ * 두 점(벡터) 사이 거리 (toDist는 dist와 동일, 비파괴).
16573
+ * - 수식: d = √((dx)² + (dy)² + (dz)²)
16574
+ * @example
16575
+ * a.toDist(b); // a와 b 사이 거리
16576
+ */
16540
16577
  toDist(v2) {
16541
16578
  const v1 = this;
16542
16579
  const dx = v1.x - v2.x, dy = v1.y - v2.y, dz = v1.z - v2.z;
@@ -16548,36 +16585,90 @@ var dooboostoreSimpleBootHttpServer = (() => {
16548
16585
  // dz = v1.z - v2.z;
16549
16586
  // return Math.sqrt(dx * dx + dy * dy + dz * dz);
16550
16587
  // }
16551
- dot(v, y, z) {
16588
+ /**
16589
+ * 내적(dot product). 두 벡터가 같은 방향을 향하는 정도.
16590
+ * - 수식: a·b = ax·bx + ay·by + az·bz = |a||b|cosθ
16591
+ * - θ=90°면 0(직교), 0°면 최대(같은 방향).
16592
+ * - 벡터 전달 시 y·z 생략 가능, 스칼라(x) 전달 시 y·z와 함께 사용.
16593
+ * @example
16594
+ * new Vector(5, 12).dot(new Vector(-5, 12)); // -25+144 = 119
16595
+ * new Vector(1, 0).dot(new Vector(0, 1)); // 0 (직각)
16596
+ * new Vector(1, 2).dot(3, 4); // 1*3+2*4 = 11
16597
+ */
16598
+ dot(v, y = 0, z = 0) {
16552
16599
  if (v instanceof _Vector || v instanceof Point3D) {
16553
16600
  return this.x * v.x + this.y * v.y + this.z * v.z;
16554
16601
  }
16555
16602
  ;
16556
16603
  return this.x * v + this.y * y + this.z * z;
16557
16604
  }
16605
+ /**
16606
+ * 외적(cross product). 두 벡터에 수직인 벡터. 오른손 법칙 방향.
16607
+ * - 수식: a×b = (ay·bz − az·by, az·bx − ax·bz, ax·by − ay·bx)
16608
+ * - 2D에서는 z값 = ax·by − ay·bx (부호 있는 면적, 회전 방향 판정용).
16609
+ * @example
16610
+ * new Vector(1, 0, 0).cross(new Vector(0, 1, 0)); // (0, 0, 1)
16611
+ */
16558
16612
  cross(v) {
16559
16613
  const x = this.x, y = this.y, z = this.z;
16560
16614
  return new _Vector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y);
16561
16615
  }
16616
+ /**
16617
+ * 정규화 (파괴적). 방향은 그대로, 크기를 1로. 단위벡터 v̂ 생성.
16618
+ * - 수식: v̂ = v / |v|
16619
+ * - 영벡터(|v|=0)는 0으로 나누지 않고 그대로 둠.
16620
+ * @example
16621
+ * const v = new Vector(6, 8); v.normalize(); // v = (0.6, 0.8), |v| = 1
16622
+ */
16562
16623
  normalize() {
16563
- const m = this.mag();
16624
+ const m = this.norm();
16564
16625
  if (m > 0) this.div(m);
16565
16626
  }
16627
+ /**
16628
+ * 크기 상한 (파괴적). 속도가 high를 넘으면 방향 유지한 채 high로 자름. 물리 시뮬레이션 최고속도용.
16629
+ * - 수식: |v| > high → v = v̂ · high
16630
+ * @example
16631
+ * const v = new Vector(6, 8); v.limit(5); // |v|=10 → 5, v = (3, 4)
16632
+ */
16566
16633
  limit(high) {
16567
- if (this.mag() > high) {
16634
+ if (this.norm() > high) {
16568
16635
  this.normalize();
16569
16636
  this.mult(high);
16570
16637
  }
16571
16638
  }
16639
+ /**
16640
+ * 2D 방향각. +x축 기준 반시계 방향 라디안 (-π ~ π).
16641
+ * - 수식: θ = atan2(y, x)
16642
+ * @example
16643
+ * new Vector(1, 1).heading2D(); // π/4 (45°)
16644
+ * new Vector(-1, 0).heading2D(); // π (180°)
16645
+ */
16572
16646
  heading2D() {
16573
16647
  return -Math.atan2(-this.y, this.x);
16574
16648
  }
16649
+ /**
16650
+ * 무작위 방향 단위벡터 반환 (새 Vector, 자신은 변경 안 함).
16651
+ * @example
16652
+ * const r = new Vector().random2D(); // |r| = 1, 방향 랜덤
16653
+ */
16575
16654
  random2D() {
16576
16655
  return this.fromAngle(Math.random() * (2 * Math.PI));
16577
16656
  }
16657
+ /**
16658
+ * 각도→벡터. 각도 θ, 길이 L인 2D 벡터 반환 (새 Vector).
16659
+ * - 수식: (L·cosθ, L·sinθ, 0)
16660
+ * @example
16661
+ * new Vector().fromAngle(Math.PI / 3, 2); // (1, 1.73, 0)
16662
+ */
16578
16663
  fromAngle(angle, length = 1) {
16579
16664
  return new _Vector(length * Math.cos(angle), length * Math.sin(angle), 0);
16580
16665
  }
16666
+ /**
16667
+ * 구면좌표→3D 벡터 (새 Vector 반환, p5.js 컨벤션).
16668
+ * - 수식: (L·sinθ·sinφ, −L·cosθ, L·sinθ·cosφ)
16669
+ * @example
16670
+ * new Vector().fromAngles(Math.PI / 2, Math.PI / 2, 1); // (1, 0, 0)
16671
+ */
16581
16672
  fromAngles(theta, phi, length = 1) {
16582
16673
  const cosPhi = Math.cos(phi);
16583
16674
  const sinPhi = Math.sin(phi);
@@ -16589,18 +16680,43 @@ var dooboostoreSimpleBootHttpServer = (() => {
16589
16680
  length * sinTheta * cosPhi
16590
16681
  );
16591
16682
  }
16683
+ /**
16684
+ * 성분 배열 반환. [x, y, z] 순서.
16685
+ * @example
16686
+ * new Vector(1, 2, 3).array(); // [1, 2, 3]
16687
+ */
16592
16688
  array() {
16593
16689
  return [this.x, this.y, this.z];
16594
16690
  }
16691
+ /**
16692
+ * Point3D로 변환 (위치 의미로 바꿀 때).
16693
+ * @example
16694
+ * new Vector(1, 2, 3).toPoint3D(); // Point3D(1, 2, 3)
16695
+ */
16595
16696
  toPoint3D() {
16596
16697
  return new Point3D(this.x, this.y, this.z);
16597
16698
  }
16699
+ /**
16700
+ * Point2D로 변환 (z 버림).
16701
+ * @example
16702
+ * new Vector(1, 2, 3).toPoint2D(); // Point2D(1, 2)
16703
+ */
16598
16704
  toPoint2D() {
16599
16705
  return new Point2D(this.x, this.y);
16600
16706
  }
16707
+ /**
16708
+ * 복사본 반환 (get()과 동일, 비파괴).
16709
+ * @example
16710
+ * const c = v.copy(); // v와 같은 성분의 새 벡터
16711
+ */
16601
16712
  copy() {
16602
16713
  return new _Vector(this.x, this.y, this.z);
16603
16714
  }
16715
+ /**
16716
+ * 문자열 표현. "[x, y, z]" 형식.
16717
+ * @example
16718
+ * new Vector(1, 2).toString(); // "[1, 2, 0]"
16719
+ */
16604
16720
  toString() {
16605
16721
  return "[" + this.x + ", " + this.y + ", " + this.z + "]";
16606
16722
  }
@@ -18793,87 +18909,64 @@ var dooboostoreSimpleBootHttpServer = (() => {
18793
18909
  // ../core/dist/esm/promise/AbortablePromise.js
18794
18910
  var AbortablePromise = class _AbortablePromise {
18795
18911
  constructor(executor, signal) {
18796
- this.steps = [];
18797
- this.initialExecutor = executor;
18798
18912
  this.signal = signal;
18913
+ if (typeof executor !== "function") {
18914
+ this.source = Promise.resolve(executor);
18915
+ } else if (signal?.aborted) {
18916
+ this.source = Promise.reject(signal.reason);
18917
+ } else {
18918
+ this.source = Promise.resolve().then(executor);
18919
+ }
18920
+ }
18921
+ /**
18922
+ * source 를 abort 와 경쟁시킨 promise. 실제로 소비될 때(then/toPromise) 한 번만 만든다 —
18923
+ * await 는 then() 이 돌려준 새 인스턴스를 버리므로, 미리 만들면 아무도 안 받는 reject 가 unhandled 로 남는다.
18924
+ */
18925
+ get promise() {
18926
+ if (this.guarded) return this.guarded;
18927
+ const signal = this.signal;
18928
+ if (!signal) return this.guarded = this.source;
18929
+ if (signal.aborted) {
18930
+ this.source.catch(() => {
18931
+ });
18932
+ return this.guarded = Promise.reject(signal.reason);
18933
+ }
18934
+ return this.guarded = new Promise((resolve2, reject) => {
18935
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
18936
+ const onAbort = () => reject(signal.reason);
18937
+ signal.addEventListener("abort", onAbort, { once: true });
18938
+ this.source.then(
18939
+ (value) => {
18940
+ cleanup();
18941
+ resolve2(value);
18942
+ },
18943
+ (reason) => {
18944
+ cleanup();
18945
+ reject(reason);
18946
+ }
18947
+ );
18948
+ });
18799
18949
  }
18800
18950
  then(onfulfilled, onrejected) {
18801
- const newPromise = new _AbortablePromise(
18802
- this.initialExecutor,
18803
- this.signal
18951
+ const signal = this.signal;
18952
+ const next = this.promise.then(
18953
+ onfulfilled ? (value) => {
18954
+ if (signal?.aborted) throw signal.reason;
18955
+ return onfulfilled(value);
18956
+ } : void 0,
18957
+ onrejected
18804
18958
  );
18805
- newPromise.steps = [...this.steps];
18806
- if (onfulfilled) {
18807
- newPromise.steps.push(onfulfilled);
18808
- }
18809
- if (onrejected) {
18810
- newPromise.errorHandler = onrejected;
18811
- } else if (this.errorHandler) {
18812
- newPromise.errorHandler = this.errorHandler;
18813
- }
18814
- return newPromise;
18959
+ return new _AbortablePromise(next, signal);
18815
18960
  }
18816
18961
  catch(onrejected) {
18817
18962
  return this.then(void 0, onrejected);
18818
18963
  }
18819
18964
  finally(onfinally) {
18820
- return this.then(
18821
- (value) => {
18822
- onfinally?.();
18823
- return value;
18824
- },
18825
- (reason) => {
18826
- onfinally?.();
18827
- throw reason;
18828
- }
18829
- );
18965
+ return new _AbortablePromise(this.promise.finally(onfinally), this.signal);
18830
18966
  }
18831
- async execute() {
18832
- try {
18833
- if (this.signal?.aborted) {
18834
- throw new Error(this.signal.reason || "Aborted");
18835
- }
18836
- const abortPromise = new Promise((_, reject) => {
18837
- if (this.signal?.aborted) {
18838
- return reject(new Error(this.signal.reason || "Aborted"));
18839
- }
18840
- const callback = (e) => {
18841
- const target = e.target;
18842
- this.signal?.removeEventListener("abort", callback);
18843
- reject(new Error(target.reason || "Aborted"));
18844
- };
18845
- this.signal?.addEventListener("abort", callback, { once: true });
18846
- });
18847
- const pipelineRunner = async () => {
18848
- let lastResult;
18849
- if (typeof this.initialExecutor === "function") {
18850
- if (this.signal?.aborted) {
18851
- throw new Error(this.signal.reason || "Aborted");
18852
- }
18853
- lastResult = await this.initialExecutor();
18854
- } else {
18855
- lastResult = await this.initialExecutor;
18856
- }
18857
- for (let i = 0; i < this.steps.length; i++) {
18858
- if (this.signal?.aborted) {
18859
- throw new Error(this.signal.reason || "Aborted");
18860
- }
18861
- const step = this.steps[i];
18862
- lastResult = await step(lastResult);
18863
- }
18864
- return lastResult;
18865
- };
18866
- return await Promise.race([pipelineRunner(), abortPromise]);
18867
- } catch (error) {
18868
- if (this.errorHandler) {
18869
- return await this.errorHandler(error);
18870
- }
18871
- throw error;
18872
- }
18873
- }
18874
- // Convert to native Promise
18967
+ // 네이티브 Promise 로 변환 (그냥 await 해도 된다)
18875
18968
  toPromise() {
18876
- return this.execute();
18969
+ return this.promise;
18877
18970
  }
18878
18971
  };
18879
18972
 
@@ -19746,11 +19839,15 @@ var dooboostoreSimpleBootHttpServer = (() => {
19746
19839
  resolve2(gdata);
19747
19840
  }).catch(async (e) => {
19748
19841
  this.error(config, pipe, e);
19749
- config?.error?.();
19842
+ config?.error?.(e);
19750
19843
  if (config?.errorTransform) {
19751
19844
  e = await config.errorTransform(e);
19752
19845
  }
19753
- e = await this.errorTransform(e);
19846
+ try {
19847
+ e = await this.errorTransform(e);
19848
+ } catch (ee) {
19849
+ e = ee;
19850
+ }
19754
19851
  reject(e);
19755
19852
  }).finally(() => {
19756
19853
  this.finally(config, pipe);
@@ -19767,41 +19864,30 @@ var dooboostoreSimpleBootHttpServer = (() => {
19767
19864
  return data instanceof HttpResponseError;
19768
19865
  };
19769
19866
  var HttpFetcher = class extends Fetcher {
19867
+ // get/post/put/patch/head/delete가 전부 config.config.fetch.method를 세팅하려고 caller가
19868
+ // 넘긴 config(.fetch) 객체를 직접 mutate했다 - 같은 config 객체를 여러 호출이 공유하면
19869
+ // (예: Promise.all로 동시에 get/post) 서로의 method를 덮어쓰는 레이스가 생겼다. caller의
19870
+ // 객체는 절대 건드리지 않고, 얕은 복사본 위에 method만 얹어서 반환한다.
19871
+ withMethod(config, method) {
19872
+ return { ...config, config: { ...config.config, fetch: { ...config.config?.fetch, method } } };
19873
+ }
19770
19874
  get(config) {
19771
- config.config ?? (config.config = {});
19772
- config.config.fetch = config.config?.fetch ?? {};
19773
- config.config.fetch.method = "GET";
19774
- return this.fetch(config);
19875
+ return this.fetch(this.withMethod(config, "GET"));
19775
19876
  }
19776
19877
  post(config) {
19777
- config.config ?? (config.config = {});
19778
- config.config.fetch = config.config?.fetch ?? {};
19779
- config.config.fetch.method = "POST";
19780
- return this.fetch(config);
19878
+ return this.fetch(this.withMethod(config, "POST"));
19781
19879
  }
19782
19880
  patch(config) {
19783
- config.config ?? (config.config = {});
19784
- config.config.fetch = config.config?.fetch ?? {};
19785
- config.config.fetch.method = "PATCH";
19786
- return this.fetch(config);
19881
+ return this.fetch(this.withMethod(config, "PATCH"));
19787
19882
  }
19788
19883
  put(config) {
19789
- config.config ?? (config.config = {});
19790
- config.config.fetch = config.config?.fetch ?? {};
19791
- config.config.fetch.method = "PUT";
19792
- return this.fetch(config);
19884
+ return this.fetch(this.withMethod(config, "PUT"));
19793
19885
  }
19794
19886
  head(config) {
19795
- config.config ?? (config.config = {});
19796
- config.config.fetch = config.config?.fetch ?? {};
19797
- config.config.fetch.method = "HEAD";
19798
- return this.fetch(config);
19887
+ return this.fetch(this.withMethod(config, "HEAD"));
19799
19888
  }
19800
19889
  delete(config) {
19801
- config.config ?? (config.config = {});
19802
- config.config.fetch = config.config?.fetch ?? {};
19803
- config.config.fetch.method = "DELETE";
19804
- return this.fetch(config);
19890
+ return this.fetch(this.withMethod(config, "DELETE"));
19805
19891
  }
19806
19892
  async beforeProxyFetch(config) {
19807
19893
  return config;
@@ -19838,7 +19924,7 @@ var dooboostoreSimpleBootHttpServer = (() => {
19838
19924
  }
19839
19925
  } else {
19840
19926
  httpResponseError.body = e;
19841
- httpResponseError.message = e.message;
19927
+ httpResponseError.message = e?.message;
19842
19928
  }
19843
19929
  return httpResponseError;
19844
19930
  }
@@ -19848,7 +19934,7 @@ var dooboostoreSimpleBootHttpServer = (() => {
19848
19934
  if (!(target instanceof URL) && typeof target !== "string") {
19849
19935
  const searchParams = ConvertUtils.toURLSearchParams(target.searchParams ?? {});
19850
19936
  try {
19851
- const url = typeof target.url === "string" ? new URL(target.url) : target.url;
19937
+ const url = new URL(target.url);
19852
19938
  searchParams.forEach((value, key) => {
19853
19939
  url.searchParams.append(key, value);
19854
19940
  });
@@ -19863,43 +19949,30 @@ var dooboostoreSimpleBootHttpServer = (() => {
19863
19949
  }
19864
19950
  }
19865
19951
  const beforeProxyData = { requestInfo: target, init: config?.fetch };
19866
- let beforeData = config?.beforeProxyFetch ? await config?.beforeProxyFetch(config) : beforeProxyData.requestInfo;
19867
- beforeData = config?.skipGlobalBeforeProxyFetch ? beforeProxyData : await this.beforeProxyFetch(beforeProxyData);
19952
+ let beforeData = config?.beforeProxyFetch ? await config?.beforeProxyFetch(beforeProxyData) : beforeProxyData;
19953
+ beforeData = config?.skipGlobalBeforeProxyFetch ? beforeData : await this.beforeProxyFetch(beforeData);
19868
19954
  target = beforeData.requestInfo;
19869
19955
  if (beforeData.init) {
19870
19956
  config ?? (config = {});
19871
19957
  config.fetch = beforeData.init;
19872
19958
  }
19873
- let abortedTimeout;
19959
+ let requestInit = config?.fetch;
19874
19960
  if (config?.fetch && "timeout" in config.fetch) {
19875
- const abortController = new AbortController();
19876
- abortedTimeout = setTimeout(() => {
19877
- if (config?.fetch?.signal) {
19878
- const inputSignal = config.fetch.signal;
19879
- const listener = () => {
19880
- if (!abortController.signal.aborted) {
19881
- abortController.abort();
19882
- }
19883
- inputSignal.removeEventListener("abort", listener);
19884
- };
19885
- inputSignal.addEventListener("abort", listener);
19886
- }
19887
- if (!abortController.signal.aborted) {
19888
- abortController.abort();
19889
- }
19890
- }, config.fetch.timeout);
19891
- config.fetch.signal = abortController.signal;
19961
+ const timeoutSignal = AbortSignal.timeout(config.fetch.timeout);
19962
+ const signal = config.fetch.signal ? AbortSignal.any([timeoutSignal, config.fetch.signal]) : timeoutSignal;
19963
+ requestInit = { ...config.fetch, signal };
19892
19964
  }
19893
- this.beforeFetch({ target, requestInit: config?.fetch });
19894
- return (config.fetcher ?? fetch)(target, config?.fetch).then(async (it) => {
19895
- this.afterFetch({ target, requestInit: config?.fetch }, it);
19965
+ this.beforeFetch({ target, requestInit });
19966
+ return (config.fetcher ?? fetch)(target, requestInit).then(async (it) => {
19967
+ this.afterFetch({ target, requestInit }, it);
19896
19968
  const afterProxyData = {
19897
- fetch: { target, requestInit: config.fetch },
19969
+ fetch: { target, requestInit },
19898
19970
  config: beforeData,
19899
19971
  response: it
19900
19972
  };
19901
- it = config?.afterProxyFetch ? await config.afterProxyFetch(afterProxyData) : it;
19902
- it = config?.skipGlobalAfterProxyFetch ? it : await this.afterProxyFetch(afterProxyData);
19973
+ afterProxyData.response = config?.afterProxyFetch ? await config.afterProxyFetch(afterProxyData) : it;
19974
+ afterProxyData.response = config?.skipGlobalAfterProxyFetch ? afterProxyData.response : await this.afterProxyFetch(afterProxyData);
19975
+ it = afterProxyData.response;
19903
19976
  config?.fetchResponseAfterCallBack?.(it, config);
19904
19977
  if (!config?.allowedResponseNotOk && !it.ok) {
19905
19978
  throw it;
@@ -19909,30 +19982,31 @@ var dooboostoreSimpleBootHttpServer = (() => {
19909
19982
  throw data;
19910
19983
  }
19911
19984
  return it;
19912
- }).finally(() => {
19913
- if (abortedTimeout) {
19914
- clearTimeout(abortedTimeout);
19915
- }
19916
19985
  });
19917
19986
  }
19918
19987
  };
19919
19988
 
19920
19989
  // ../core/dist/esm/fetch/HttpJsonFetcher.js
19921
19990
  var HttpJsonFetcher = class extends HttpFetcher {
19991
+ // config.config/config.config.fetch를 직접 mutate하면(예전처럼) 같은 config 객체를 여러
19992
+ // postJson/patchJson/putJson 호출이 동시에 공유할 때 서로의 headers/body를 덮어쓰는 레이스가
19993
+ // 생긴다(HttpFetcher.get/post의 method 레이스랑 같은 문제). caller의 객체는 안 건드리고,
19994
+ // 얕은 복사본을 만들어서 새 config 객체를 리턴한다.
19922
19995
  updateJsonFetchConfigAndData(config) {
19923
- var _a4, _b3;
19924
19996
  const headers = {
19925
19997
  "Content-Type": "application/json",
19926
19998
  Accept: "application/json, text/plain, */*"
19927
19999
  };
19928
- config.config ?? (config.config = {});
19929
- (_a4 = config.config).fetch ?? (_a4.fetch = {});
19930
- (_b3 = config.config.fetch).headers ?? (_b3.headers = {});
19931
- config.config.fetch.headers = { ...headers, ...config.config.fetch?.headers };
19932
- if (config.config?.fetch?.body && typeof config.config?.fetch?.body !== "string") {
19933
- config.config.fetch.body = JSON.stringify(config.config.fetch.body);
20000
+ const fetchInit = { ...config.config?.fetch };
20001
+ const merged = new Headers(headers);
20002
+ if (fetchInit.headers) {
20003
+ new Headers(fetchInit.headers).forEach((value, key) => merged.set(key, value));
19934
20004
  }
19935
- return config;
20005
+ fetchInit.headers = merged;
20006
+ if (fetchInit.body && typeof fetchInit.body !== "string") {
20007
+ fetchInit.body = JSON.stringify(fetchInit.body);
20008
+ }
20009
+ return { ...config, config: { ...config.config, fetch: fetchInit } };
19936
20010
  }
19937
20011
  get(config) {
19938
20012
  return super.get(config);
@@ -21446,7 +21520,7 @@ var dooboostoreSimpleBootHttpServer = (() => {
21446
21520
 
21447
21521
  // ../core/dist/esm/url/UrlUtils.js
21448
21522
  var UrlUtils;
21449
- ((UrlUtils2) => {
21523
+ (function(UrlUtils2) {
21450
21524
  UrlUtils2.origin = (fullurl) => {
21451
21525
  return new URL(fullurl).origin;
21452
21526
  };
@@ -21484,15 +21558,28 @@ var dooboostoreSimpleBootHttpServer = (() => {
21484
21558
  });
21485
21559
  return searchParams;
21486
21560
  };
21561
+ UrlUtils2.toAbsoluteUrl = (relative2, base) => {
21562
+ return new URL(relative2, base);
21563
+ };
21564
+ function toAbsoluteRequest(input, base) {
21565
+ if (input instanceof URL) {
21566
+ return UrlUtils2.toAbsoluteUrl(input.href, base);
21567
+ }
21568
+ if (typeof input === "string") {
21569
+ return UrlUtils2.toAbsoluteUrl(input, base).href;
21570
+ }
21571
+ return new Request(UrlUtils2.toAbsoluteUrl(input.url, base).href, input);
21572
+ }
21573
+ UrlUtils2.toAbsoluteRequest = toAbsoluteRequest;
21487
21574
  UrlUtils2.manipulateSearchParams = (searchParams, options) => {
21488
21575
  if (options?.delete) {
21489
- (0, UrlUtils2.deleteSearchParam)(searchParams, options.delete);
21576
+ UrlUtils2.deleteSearchParam(searchParams, options.delete);
21490
21577
  }
21491
21578
  if (options?.append) {
21492
- (0, UrlUtils2.appendSearchParam)(searchParams, options.append);
21579
+ UrlUtils2.appendSearchParam(searchParams, options.append);
21493
21580
  }
21494
21581
  if (options?.upsert) {
21495
- (0, UrlUtils2.upsertSearchParam)(searchParams, options.upsert);
21582
+ UrlUtils2.upsertSearchParam(searchParams, options.upsert);
21496
21583
  }
21497
21584
  return searchParams;
21498
21585
  };
@@ -21743,12 +21830,13 @@ var dooboostoreSimpleBootHttpServer = (() => {
21743
21830
  ReflectUtils2.findMetadata = (metadataKey, target, propertyKey) => {
21744
21831
  if (target == null) return void 0;
21745
21832
  let searchTarget = typeof target === "object" && typeof target !== "function" ? target.constructor : target;
21746
- while (searchTarget && searchTarget !== Object) {
21833
+ const seen = /* @__PURE__ */ new Set();
21834
+ while (searchTarget && searchTarget !== Object && !seen.has(searchTarget)) {
21835
+ seen.add(searchTarget);
21747
21836
  const data = propertyKey ? Reflect.getOwnMetadata(metadataKey, searchTarget, propertyKey) : Reflect.getOwnMetadata(metadataKey, searchTarget);
21748
21837
  if (data !== void 0) return data;
21749
21838
  const proto = Object.getPrototypeOf(searchTarget);
21750
21839
  searchTarget = proto && typeof proto === "function" ? proto : proto?.constructor || null;
21751
- if (searchTarget === target) break;
21752
21840
  }
21753
21841
  return void 0;
21754
21842
  };
@@ -21756,12 +21844,13 @@ var dooboostoreSimpleBootHttpServer = (() => {
21756
21844
  const results = [];
21757
21845
  if (target == null) return results;
21758
21846
  let searchTarget = typeof target === "object" && typeof target !== "function" ? target.constructor : target;
21759
- while (searchTarget && searchTarget !== Object) {
21847
+ const seen = /* @__PURE__ */ new Set();
21848
+ while (searchTarget && searchTarget !== Object && !seen.has(searchTarget)) {
21849
+ seen.add(searchTarget);
21760
21850
  const data = propertyKey ? Reflect.getOwnMetadata(metadataKey, searchTarget, propertyKey) : Reflect.getOwnMetadata(metadataKey, searchTarget);
21761
21851
  if (data !== void 0) results.unshift(data);
21762
21852
  const proto = Object.getPrototypeOf(searchTarget);
21763
21853
  searchTarget = proto && typeof proto === "function" ? proto : proto?.constructor || null;
21764
- if (searchTarget === target) break;
21765
21854
  }
21766
21855
  return results;
21767
21856
  };
@@ -23886,6 +23975,23 @@ ${indentStr}}`;
23886
23975
  };
23887
23976
  }
23888
23977
 
23978
+ // ../core/dist/esm/hash/HashUtils.js
23979
+ var HashUtils;
23980
+ ((HashUtils2) => {
23981
+ const core53 = (str, seed) => {
23982
+ let h1 = 3735928559 ^ seed, h2 = 1103547991 ^ seed;
23983
+ for (let i = 0; i < str.length; i++) {
23984
+ const ch = str.charCodeAt(i);
23985
+ h1 = Math.imul(h1 ^ ch, 2654435761);
23986
+ h2 = Math.imul(h2 ^ ch, 1597334677);
23987
+ }
23988
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
23989
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
23990
+ return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16).padStart(14, "0");
23991
+ };
23992
+ HashUtils2.hash53 = (str, seed = 0, xyz = 16) => `${core53(str, seed)}${core53(str, seed + 1)}`.slice(0, Math.max(1, xyz));
23993
+ })(HashUtils || (HashUtils = {}));
23994
+
23889
23995
  // ../core/dist/esm/index.js
23890
23996
  var src_default = {
23891
23997
  // Core utilities are exported as named exports above
@@ -24003,7 +24109,7 @@ ${indentStr}}`;
24003
24109
  return getUrlMapping(target, propertyKey);
24004
24110
  };
24005
24111
  var getPATCHS = (target) => {
24006
- return getUrlMappings(target)?.filter((it) => it.config?.method.toUpperCase() === "GET" /* GET */);
24112
+ return getUrlMappings(target)?.filter((it) => it.config?.method.toUpperCase() === "PATCH" /* PATCH */);
24007
24113
  };
24008
24114
  function OPTIONS(configOrTarget, propertyKey, descriptor) {
24009
24115
  if (propertyKey && descriptor) {
@@ -24035,7 +24141,7 @@ ${indentStr}}`;
24035
24141
  return getUrlMapping(target, propertyKey);
24036
24142
  };
24037
24143
  var getHEADS = (target) => {
24038
- return getUrlMappings(target)?.filter((it) => it.config?.method.toUpperCase() === "GET" /* GET */);
24144
+ return getUrlMappings(target)?.filter((it) => it.config?.method.toUpperCase() === "HEAD" /* HEAD */);
24039
24145
  };
24040
24146
  function TRACE(configOrTarget, propertyKey, descriptor) {
24041
24147
  if (propertyKey && descriptor) {
@@ -24991,7 +25097,16 @@ ${indentStr}}`;
24991
25097
  }
24992
25098
  if (!this.value) {
24993
25099
  if (typeof this.type.targetKeyType === "symbol") {
24994
- this.value = this.simstanceManager.findFirstSim(this.type.targetKeyType)?.getValue();
25100
+ const stored = this.simstanceManager.getStoreSet(this.type.targetKeyType);
25101
+ if (ValidUtils.isArrowFunction(stored?.instance)) {
25102
+ const fresh = stored.instance();
25103
+ if (this.getConfig()?.scope === Lifecycle.Singleton) {
25104
+ this.simstanceManager.setStoreSet(this.type.targetKeyType, fresh, stored.type);
25105
+ this.value = fresh;
25106
+ }
25107
+ return fresh;
25108
+ }
25109
+ this.value = stored?.instance;
24995
25110
  } else {
24996
25111
  this.value = this.simstanceManager.getOrNewSim({ target: this.type.targetKeyType, originTypeTarget: this.type.originalType, newInstanceCarrier: config?.newInstanceCarrier });
24997
25112
  }
@@ -25546,7 +25661,7 @@ ${indentStr}}`;
25546
25661
  registerStore(targetKey, regTyps) {
25547
25662
  const itemMap = this.storage.get(targetKey) ?? /* @__PURE__ */ new Map();
25548
25663
  regTyps.forEach((it) => {
25549
- const { type, value } = typeof it === "object" ? { type: it.constructor, value: it } : { type: it, value: void 0 };
25664
+ const { type, value } = ValidUtils.isArrowFunction(it) ? { type: it, value: it } : typeof it === "object" ? { type: it.constructor, value: it } : { type: it, value: void 0 };
25550
25665
  if (!itemMap.has(type) || value !== void 0 && itemMap.get(type) === void 0) {
25551
25666
  itemMap.set(type, value);
25552
25667
  }
@@ -25799,9 +25914,16 @@ ${indentStr}}`;
25799
25914
  }
25800
25915
  run(otherInstanceSim = /* @__PURE__ */ new Map()) {
25801
25916
  for (const [k, v] of Array.from(otherInstanceSim.entries())) {
25802
- const storageKey = typeof k === "object" && k !== null && "type" in k ? k.type : k;
25803
- this.registerStore(storageKey, /* @__PURE__ */ new Set([v]));
25804
- if (typeof k === "object" && k !== null && "symbol" in k && k.symbol) {
25917
+ const hasType = typeof k === "object" && k !== null && "type" in k;
25918
+ const hasSymbol = typeof k === "object" && k !== null && !!k.symbol;
25919
+ const storageKey = hasType ? k.type : k;
25920
+ if (hasType || !hasSymbol) {
25921
+ this.registerStore(storageKey, /* @__PURE__ */ new Set([v]));
25922
+ }
25923
+ if (hasSymbol) {
25924
+ if (!ReflectUtils.getMetadata(SimMetadataKey, v)) {
25925
+ ReflectUtils.defineMetadata(SimMetadataKey, { ...k, scope: k.scope ?? Lifecycle.Singleton }, v);
25926
+ }
25805
25927
  this.registerStore(k.symbol, /* @__PURE__ */ new Set([v]));
25806
25928
  }
25807
25929
  }
@@ -27759,7 +27881,6 @@ ${indentStr}}`;
27759
27881
  return it.test(url);
27760
27882
  }
27761
27883
  if (typeof it === "string") {
27762
- console.log("url!!!!!!!", url);
27763
27884
  return it === url;
27764
27885
  }
27765
27886
  if (typeof it === "function") {
@@ -27931,7 +28052,7 @@ ${indentStr}}`;
27931
28052
  fetch: {
27932
28053
  credentials: "include",
27933
28054
  headers,
27934
- body: ConvertUtils.toFormData(userConfig?.body)
28055
+ body: userConfig?.body ? ConvertUtils.toFormData(userConfig.body) : void 0
27935
28056
  }
27936
28057
  }
27937
28058
  });
@@ -28244,6 +28365,16 @@ ${indentStr}}`;
28244
28365
  };
28245
28366
  };
28246
28367
 
28368
+ // src/proxy/RequestResponseInjectProxy.ts
28369
+ var injectRequestResponse = (sim2, rr) => new Proxy(sim2, {
28370
+ get(target, prop) {
28371
+ const value = target[prop];
28372
+ if (prop === "constructor" || typeof value !== "function") return value;
28373
+ if (!rr) return value.bind(target);
28374
+ return (...args) => value.apply(target, [...args, rr]);
28375
+ }
28376
+ });
28377
+
28247
28378
  // src/inject/InjectSituationType.ts
28248
28379
  var InjectSituationType2;
28249
28380
  ((InjectSituationType3) => {
@@ -28268,6 +28399,7 @@ ${indentStr}}`;
28268
28399
 
28269
28400
  // src/models/RequestResponse.ts
28270
28401
  var import_node_gzip = __toESM(require_dist(), 1);
28402
+ var import_zlib = __require("zlib");
28271
28403
  var import_node_buffer2 = __require("node:buffer");
28272
28404
  var RequestResponse = class _RequestResponse {
28273
28405
  constructor(req, res, config) {
@@ -28706,6 +28838,57 @@ ${indentStr}}`;
28706
28838
  this.createRequestResponseChain(this.res.writeHead(statusCode, headers));
28707
28839
  this.res.end();
28708
28840
  }
28841
+ /**
28842
+ * 헤더를 즉시 보내고, source 가 내놓는 값을 하나씩 바로 body 에 쓴 뒤 end.
28843
+ * (SSE / 스트리밍 응답용. resWrite 는 버퍼링 후 resEnd 에서 한 번에 보내므로 스트리밍 불가)
28844
+ * - 문자열/Buffer 는 그대로, 그 외는 JSON.stringify
28845
+ * - Accept-Encoding 에 gzip 이 있으면 gzip 스트림으로 압축하고, 청크마다 Z_SYNC_FLUSH 로 바로 내보낸다
28846
+ * (flush 없이 쓰면 zlib 내부 버퍼에 모였다가 늦게 나가서 SSE 실시간성이 깨짐)
28847
+ * - 클라이언트가 끊으면 source.return() 으로 제너레이터를 종료시켜 finally 가 돌게 한다
28848
+ */
28849
+ async resStream(source) {
28850
+ const res = this.res;
28851
+ const gz = this.reqHeaderFirst(HttpHeaders.AcceptEncoding)?.includes("gzip") ? (0, import_zlib.createGzip)() : void 0;
28852
+ if (gz) {
28853
+ res.setHeader(HttpHeaders.ContentEncoding, "gzip");
28854
+ res.removeHeader(HttpHeaders.ContentLength);
28855
+ gz.pipe(res);
28856
+ }
28857
+ const out = gz ?? res;
28858
+ res.flushHeaders();
28859
+ let closed = false;
28860
+ const onClose = () => {
28861
+ closed = true;
28862
+ source.return?.();
28863
+ };
28864
+ res.once("close", onClose);
28865
+ try {
28866
+ for await (const chunk of source) {
28867
+ if (closed) break;
28868
+ const data = typeof chunk === "string" || import_buffer.Buffer.isBuffer(chunk) ? chunk : JSON.stringify(chunk);
28869
+ const ok = out.write(data);
28870
+ gz?.flush(import_zlib.constants.Z_SYNC_FLUSH);
28871
+ if (!ok) await new Promise((resolve2) => {
28872
+ out.once("drain", resolve2);
28873
+ res.once("close", resolve2);
28874
+ });
28875
+ }
28876
+ } catch (e) {
28877
+ if (!closed) throw e;
28878
+ } finally {
28879
+ res.off("close", onClose);
28880
+ if (closed) {
28881
+ gz?.destroy();
28882
+ } else if (!res.writableEnded) {
28883
+ const finished = new Promise((resolve2) => {
28884
+ res.once("finish", resolve2);
28885
+ res.once("close", resolve2);
28886
+ });
28887
+ out.end();
28888
+ await finished;
28889
+ }
28890
+ }
28891
+ }
28709
28892
  resIsDone() {
28710
28893
  return this.res.finished || this.res.writableEnded || this.res.headersSent;
28711
28894
  }
@@ -28953,7 +29136,7 @@ ${indentStr}}`;
28953
29136
  var import_http = __require("http");
28954
29137
  var import_https = __require("https");
28955
29138
 
28956
- // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/wrapper.mjs
29139
+ // ../../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/wrapper.mjs
28957
29140
  var import_stream = __toESM(require_stream(), 1);
28958
29141
  var import_extension = __toESM(require_extension(), 1);
28959
29142
  var import_permessage_deflate = __toESM(require_permessage_deflate(), 1);
@@ -29053,6 +29236,11 @@ ${indentStr}}`;
29053
29236
  otherStorage.set(RequestResponse, rr);
29054
29237
  otherStorage.set(import_http.IncomingMessage, req);
29055
29238
  otherStorage.set(import_http.ServerResponse, res);
29239
+ const abortController = new AbortController();
29240
+ res.once("close", () => {
29241
+ if (!res.writableFinished) abortController.abort();
29242
+ });
29243
+ otherStorage.set(AbortSignal, abortController.signal);
29056
29244
  try {
29057
29245
  transactionManager?.try();
29058
29246
  if (this.option.requestEndPoints) {
@@ -29209,23 +29397,35 @@ ${indentStr}}`;
29209
29397
  target: moduleInstance,
29210
29398
  targetKey: it.propertyKey
29211
29399
  }, otherStorage);
29212
- if (it.config?.resolver) {
29213
- const execute = typeof it.config.resolver === "function" ? this.simstanceManager.getOrNewSim({ target: it.config.resolver }) : it.config.resolver;
29214
- data = await execute?.resolve?.(data, rr);
29215
- }
29216
- const status = it.config?.res?.status ?? 200 /* Ok */;
29217
- const headers = it.config?.res?.header ?? {};
29218
- if (it.config?.res?.contentType) {
29219
- headers[HttpHeaders.ContentType] = it.config?.res?.contentType;
29220
- }
29221
- if ((it.config?.res?.contentType?.toLowerCase().indexOf("application/json" /* ApplicationJson */.toLowerCase()) ?? -1) > -1) {
29222
- data = JSON.stringify(data);
29223
- } else if (data && typeof data === "object") {
29224
- data = JSON.stringify(data);
29400
+ const resConfig = it.config?.res;
29401
+ if (resConfig === "manual") {
29402
+ } else if (ValidUtils.isGenerator(data) || ValidUtils.isAsyncGenerator(data)) {
29403
+ const headers = resConfig?.header ?? {};
29404
+ if (resConfig?.contentType) {
29405
+ headers[HttpHeaders.ContentType] = resConfig.contentType;
29406
+ }
29407
+ rr.resSetHeaders(headers);
29408
+ rr.resSetStatusCode(resConfig?.status ?? 200 /* Ok */);
29409
+ await rr.resStream(data);
29410
+ } else {
29411
+ if (it.config?.resolver) {
29412
+ const execute = typeof it.config.resolver === "function" ? this.simstanceManager.getOrNewSim({ target: it.config.resolver }) : it.config.resolver;
29413
+ data = await execute?.resolve?.(data, rr, resConfig);
29414
+ }
29415
+ const status = resConfig?.status ?? 200 /* Ok */;
29416
+ const headers = resConfig?.header ?? {};
29417
+ if (resConfig?.contentType) {
29418
+ headers[HttpHeaders.ContentType] = resConfig.contentType;
29419
+ }
29420
+ if ((resConfig?.contentType?.toLowerCase().indexOf("application/json" /* ApplicationJson */.toLowerCase()) ?? -1) > -1) {
29421
+ data = JSON.stringify(data);
29422
+ } else if (data && typeof data === "object") {
29423
+ data = JSON.stringify(data);
29424
+ }
29425
+ rr.resSetHeaders(headers);
29426
+ rr.resSetStatusCode(status);
29427
+ rr.resWrite(data);
29225
29428
  }
29226
- rr.resSetHeaders(headers);
29227
- rr.resSetStatusCode(status);
29228
- rr.resWrite(data);
29229
29429
  }
29230
29430
  }
29231
29431
  if (this.option.noSuchRouteEndPointMappingThrow && methods.length <= 0 && rr.reqMethod()?.toUpperCase() !== "OPTIONS" /* OPTIONS */) {
@@ -29522,7 +29722,7 @@ ${indentStr}}`;
29522
29722
  var ElementApply = class _ElementApply {
29523
29723
  constructor(el, config) {
29524
29724
  this.el = el;
29525
- this.window = this.el.ownerDocument.defaultView;
29725
+ this.window = this.el.ownerDocument.defaultView ?? globalThis;
29526
29726
  this.document = this.el.ownerDocument;
29527
29727
  this.id = config?.id ?? el.id;
29528
29728
  this.variableWrap = config?.variableWrap ?? { start: "@", end: "@" };
@@ -29545,6 +29745,8 @@ ${indentStr}}`;
29545
29745
  let match;
29546
29746
  while ((match = regex.exec(script)) !== null) {
29547
29747
  variables.push(match[1]);
29748
+ const root = match[1].split(/[.[(]/)[0].trim();
29749
+ if (root && root !== match[1]) variables.push(root);
29548
29750
  }
29549
29751
  return variables;
29550
29752
  }
@@ -29649,10 +29851,15 @@ ${indentStr}}`;
29649
29851
  type.variables.forEach((v) => variables.add(v));
29650
29852
  });
29651
29853
  }
29854
+ const bind = config?.bind;
29855
+ const fromBind = (key) => bind != null && typeof key === "string" && !(key in (config?.context ?? {})) && _ElementApply.isUserMember(bind, key);
29652
29856
  const context = new Proxy(config?.context ?? {}, {
29857
+ has(target, key) {
29858
+ return key in target || fromBind(key);
29859
+ },
29653
29860
  get(target, key) {
29654
- const value = target[key];
29655
- return typeof value === "function" ? value.bind(config?.bind ?? target) : value;
29861
+ const value = key in target ? target[key] : fromBind(key) ? bind[key] : void 0;
29862
+ return typeof value === "function" ? value.bind(bind ?? target) : value;
29656
29863
  }
29657
29864
  });
29658
29865
  if (!config?.targetVariableName || config?.targetVariableName && variables.has(config?.targetVariableName)) {
@@ -29677,7 +29884,6 @@ ${indentStr}}`;
29677
29884
  }
29678
29885
  }
29679
29886
  `)(context).bind(it.node);
29680
- console.log("------------------->", it, tit);
29681
29887
  if (tit.type === "attribute" && !config?.exclude?.attribute) {
29682
29888
  it.node.setAttribute(tit.name, data());
29683
29889
  } else if (tit.type === "property" && !config?.exclude?.property) {
@@ -29697,6 +29903,15 @@ ${indentStr}}`;
29697
29903
  }
29698
29904
  }
29699
29905
  }
29906
+ /** key 가 네이티브(DOM/내장) prototype 이 아니라 사용자 클래스나 인스턴스에 정의돼 있으면 true */
29907
+ static isUserMember(obj, key) {
29908
+ for (let p = obj; p; p = Object.getPrototypeOf(p)) {
29909
+ if (!Object.prototype.hasOwnProperty.call(p, key)) continue;
29910
+ const ctor = p === obj ? null : p.constructor;
29911
+ return !(typeof ctor === "function" && /\[native code\]/.test(Function.prototype.toString.call(ctor)));
29912
+ }
29913
+ return false;
29914
+ }
29700
29915
  removeAllEventListener() {
29701
29916
  const m = this.findAllTarget().filter((it) => it.nodeType === "element").flatMap((it) => it.types.map((sit) => ({ ...sit, node: it.node })).filter((it2) => it2.type === "event"));
29702
29917
  m.forEach((tit) => {
@@ -30074,15 +30289,21 @@ ${indentStr}}`;
30074
30289
  const slots = this.findSlots();
30075
30290
  return slots.map((s) => s.nodes());
30076
30291
  }
30077
- append(...args) {
30078
- let targetId;
30079
- let items = [];
30080
- if (typeof args[0] === "string" && args.length > 1) {
30081
- targetId = args[0];
30082
- items = args.slice(1);
30083
- } else {
30084
- items = args;
30292
+ /**
30293
+ * Shared disambiguation for the `(...items)` / `(targetId, ...items)` overload pair.
30294
+ * Items are always Node instances (or strings meant as literal content) coming from
30295
+ * callers; a leading string is therefore always treated as `targetId`, even when no
30296
+ * items follow — this avoids misclassifying `targetId` itself as content when the
30297
+ * caller has zero items to insert (e.g. a decorated method returning undefined).
30298
+ */
30299
+ static parseTargetArgs(args) {
30300
+ if (typeof args[0] === "string") {
30301
+ return { targetId: args[0], items: args.slice(1) };
30085
30302
  }
30303
+ return { targetId: void 0, items: args };
30304
+ }
30305
+ append(...args) {
30306
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30086
30307
  if (!items || items.length === 0) return;
30087
30308
  const slots = this.findSlots(targetId);
30088
30309
  if (!slots || slots.length === 0) return;
@@ -30091,38 +30312,17 @@ ${indentStr}}`;
30091
30312
  }
30092
30313
  }
30093
30314
  appendHtml(...args) {
30094
- let targetId;
30095
- let items = [];
30096
- if (typeof args[0] === "string" && args.length > 1) {
30097
- targetId = args[0];
30098
- items = args.slice(1);
30099
- } else {
30100
- items = args;
30101
- }
30315
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30102
30316
  const slots = this.findSlots(targetId);
30103
30317
  for (const s of slots) s.appendHtml(...items);
30104
30318
  }
30105
30319
  appendText(...args) {
30106
- let targetId;
30107
- let items = [];
30108
- if (typeof args[0] === "string" && args.length > 1) {
30109
- targetId = args[0];
30110
- items = args.slice(1);
30111
- } else {
30112
- items = args;
30113
- }
30320
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30114
30321
  const slots = this.findSlots(targetId);
30115
30322
  for (const s of slots) s.appendText(...items);
30116
30323
  }
30117
30324
  appendCopy(...args) {
30118
- let targetId;
30119
- let items = [];
30120
- if (typeof args[0] === "string" && args.length > 1) {
30121
- targetId = args[0];
30122
- items = args.slice(1);
30123
- } else {
30124
- items = args;
30125
- }
30325
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30126
30326
  if (!items || items.length === 0) return;
30127
30327
  const slots = this.findSlots(targetId);
30128
30328
  if (!slots || slots.length === 0) return;
@@ -30131,14 +30331,7 @@ ${indentStr}}`;
30131
30331
  }
30132
30332
  }
30133
30333
  prepend(...args) {
30134
- let targetId;
30135
- let items = [];
30136
- if (typeof args[0] === "string" && args.length > 1) {
30137
- targetId = args[0];
30138
- items = args.slice(1);
30139
- } else {
30140
- items = args;
30141
- }
30334
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30142
30335
  if (!items || items.length === 0) return;
30143
30336
  const slots = this.findSlots(targetId);
30144
30337
  if (!slots || slots.length === 0) return;
@@ -30147,38 +30340,17 @@ ${indentStr}}`;
30147
30340
  }
30148
30341
  }
30149
30342
  prependHtml(...args) {
30150
- let targetId;
30151
- let items = [];
30152
- if (typeof args[0] === "string" && args.length > 1) {
30153
- targetId = args[0];
30154
- items = args.slice(1);
30155
- } else {
30156
- items = args;
30157
- }
30343
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30158
30344
  const slots = this.findSlots(targetId);
30159
30345
  for (const s of slots) s.prependHtml(...items);
30160
30346
  }
30161
30347
  prependText(...args) {
30162
- let targetId;
30163
- let items = [];
30164
- if (typeof args[0] === "string" && args.length > 1) {
30165
- targetId = args[0];
30166
- items = args.slice(1);
30167
- } else {
30168
- items = args;
30169
- }
30348
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30170
30349
  const slots = this.findSlots(targetId);
30171
30350
  for (const s of slots) s.prependText(...items);
30172
30351
  }
30173
30352
  prependCopy(...args) {
30174
- let targetId;
30175
- let items = [];
30176
- if (typeof args[0] === "string" && args.length > 1) {
30177
- targetId = args[0];
30178
- items = args.slice(1);
30179
- } else {
30180
- items = args;
30181
- }
30353
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30182
30354
  if (!items || items.length === 0) return;
30183
30355
  const slots = this.findSlots(targetId);
30184
30356
  if (!slots || slots.length === 0) return;
@@ -30198,14 +30370,7 @@ ${indentStr}}`;
30198
30370
  }
30199
30371
  }
30200
30372
  replaceChildren(...args) {
30201
- let targetId;
30202
- let items = [];
30203
- if (typeof args[0] === "string" && args.length > 1) {
30204
- targetId = args[0];
30205
- items = args.slice(1);
30206
- } else {
30207
- items = args;
30208
- }
30373
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30209
30374
  const slots = this.findSlots(targetId);
30210
30375
  if (!slots || slots.length === 0) return;
30211
30376
  for (const s of slots) {
@@ -30213,14 +30378,7 @@ ${indentStr}}`;
30213
30378
  }
30214
30379
  }
30215
30380
  replaceChildrenHtml(...args) {
30216
- let targetId;
30217
- let items = [];
30218
- if (typeof args[0] === "string" && args.length > 1) {
30219
- targetId = args[0];
30220
- items = args.slice(1);
30221
- } else {
30222
- items = args;
30223
- }
30381
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30224
30382
  const slots = this.findSlots(targetId);
30225
30383
  if (!slots || slots.length === 0) return;
30226
30384
  for (const s of slots) {
@@ -30228,14 +30386,7 @@ ${indentStr}}`;
30228
30386
  }
30229
30387
  }
30230
30388
  replaceChildrenText(...args) {
30231
- let targetId;
30232
- let items = [];
30233
- if (typeof args[0] === "string" && args.length > 1) {
30234
- targetId = args[0];
30235
- items = args.slice(1);
30236
- } else {
30237
- items = args;
30238
- }
30389
+ const { targetId, items } = _NodeSlot.parseTargetArgs(args);
30239
30390
  const slots = this.findSlots(targetId);
30240
30391
  if (!slots || slots.length === 0) return;
30241
30392
  for (const s of slots) {
@@ -30926,6 +31077,7 @@ ${indentStr}}`;
30926
31077
  var ROUTER_NO_EVENT_MARKER = "__ROUTER_NO_EVENT__";
30927
31078
  var Router2 = class {
30928
31079
  constructor(config) {
31080
+ this.leaveGuards = /* @__PURE__ */ new Set();
30929
31081
  this._config = config;
30930
31082
  let routeData;
30931
31083
  if (config?.firstUrl) {
@@ -30946,13 +31098,39 @@ ${indentStr}}`;
30946
31098
  this.behaviorSubject = new BehaviorSubject(routeData);
30947
31099
  }
30948
31100
  this.config.window.addEventListener("popstate", (event) => {
30949
- const routeData2 = { ...this.getRouteData(), triggerPoint: "end" };
30950
- this.behaviorSubject.next(routeData2);
31101
+ const publish = () => this.behaviorSubject.next({ ...this.getRouteData(), triggerPoint: "end" });
31102
+ if (!this.leaveGuards.size) return publish();
31103
+ const from = this.value;
31104
+ void this.canLeave(this.getRouteData(), from).then((ok) => {
31105
+ if (ok) publish();
31106
+ else this.config.window.history?.pushState(from.data ?? null, "", from.url);
31107
+ });
30951
31108
  });
30952
31109
  }
30953
31110
  get value() {
30954
31111
  return this.behaviorSubject.getValue();
30955
31112
  }
31113
+ /**
31114
+ * 이동 전 가드 등록. go() 와 뒤로/앞으로 가기(popstate)에 적용된다 (pushState/replaceState 직접 호출은 제외).
31115
+ * 리턴한 함수를 부르면 해제된다.
31116
+ */
31117
+ addLeaveGuard(guard) {
31118
+ this.leaveGuards.add(guard);
31119
+ return () => {
31120
+ this.leaveGuards.delete(guard);
31121
+ };
31122
+ }
31123
+ /** 가드가 하나라도 있는지 (없으면 호출자가 동기로 진행해도 된다) */
31124
+ get hasLeaveGuards() {
31125
+ return this.leaveGuards.size > 0;
31126
+ }
31127
+ /** 등록된 가드를 순서대로 평가. 하나라도 false 면 false */
31128
+ async canLeave(to, from) {
31129
+ for (const guard of [...this.leaveGuards]) {
31130
+ if (await guard(to, from) === false) return false;
31131
+ }
31132
+ return true;
31133
+ }
30956
31134
  get observable() {
30957
31135
  return this.behaviorSubject.asObservable();
30958
31136
  }
@@ -31083,17 +31261,24 @@ ${indentStr}}`;
31083
31261
  if (typeof config === "string") {
31084
31262
  config = { path: config };
31085
31263
  }
31086
- if (config?.replace) {
31087
- this.replace(config.path, config.state);
31088
- } else {
31089
- this.push(config.path, config.state);
31090
- }
31091
- if (config.scrollToTop !== false) {
31092
- try {
31093
- this._config.window?.scrollTo?.(0, 0);
31094
- } catch (e) {
31264
+ const target = config;
31265
+ const navigate = () => {
31266
+ if (target?.replace) {
31267
+ this.replace(target.path, target.state);
31268
+ } else {
31269
+ this.push(target.path, target.state);
31095
31270
  }
31096
- }
31271
+ if (target.scrollToTop !== false) {
31272
+ try {
31273
+ this._config.window?.scrollTo?.(0, 0);
31274
+ } catch (e) {
31275
+ }
31276
+ }
31277
+ };
31278
+ if (!this.leaveGuards.size) return navigate();
31279
+ return this.canLeave(this.getRouteData({ pathOrUrl: this.toUrl(target.path) }), this.value).then((ok) => {
31280
+ if (ok) navigate();
31281
+ });
31097
31282
  }
31098
31283
  toUrl(data) {
31099
31284
  let targetPath;