@alwatr/signal 5.0.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/{computed-signal.d.ts → core/computed-signal.d.ts} +32 -9
  3. package/dist/core/computed-signal.d.ts.map +1 -0
  4. package/dist/{effect-signal.d.ts → core/effect-signal.d.ts} +25 -7
  5. package/dist/core/effect-signal.d.ts.map +1 -0
  6. package/dist/{event-signal.d.ts → core/event-signal.d.ts} +4 -4
  7. package/dist/core/event-signal.d.ts.map +1 -0
  8. package/dist/{signal-base.d.ts → core/signal-base.d.ts} +19 -14
  9. package/dist/core/signal-base.d.ts.map +1 -0
  10. package/dist/{state-signal.d.ts → core/state-signal.d.ts} +27 -4
  11. package/dist/core/state-signal.d.ts.map +1 -0
  12. package/dist/creators/computed.d.ts +34 -0
  13. package/dist/creators/computed.d.ts.map +1 -0
  14. package/dist/creators/effect.d.ts +43 -0
  15. package/dist/creators/effect.d.ts.map +1 -0
  16. package/dist/creators/event.d.ts +28 -0
  17. package/dist/creators/event.d.ts.map +1 -0
  18. package/dist/creators/state.d.ts +25 -0
  19. package/dist/creators/state.d.ts.map +1 -0
  20. package/dist/main.cjs +225 -92
  21. package/dist/main.cjs.map +3 -3
  22. package/dist/main.d.ts +10 -5
  23. package/dist/main.d.ts.map +1 -1
  24. package/dist/main.mjs +219 -91
  25. package/dist/main.mjs.map +3 -3
  26. package/dist/operators/debounce.d.ts +57 -0
  27. package/dist/operators/debounce.d.ts.map +1 -0
  28. package/dist/operators/filter.d.ts +47 -0
  29. package/dist/operators/filter.d.ts.map +1 -0
  30. package/dist/operators/map.d.ts +36 -0
  31. package/dist/operators/map.d.ts.map +1 -0
  32. package/dist/type.d.ts +57 -15
  33. package/dist/type.d.ts.map +1 -1
  34. package/package.json +8 -8
  35. package/dist/computed-signal.d.ts.map +0 -1
  36. package/dist/effect-signal.d.ts.map +0 -1
  37. package/dist/event-signal.d.ts.map +0 -1
  38. package/dist/signal-base.d.ts.map +0 -1
  39. package/dist/state-signal.d.ts.map +0 -1
  40. /package/src/{computed-signal.test.js → core/computed-signal.test.js} +0 -0
  41. /package/src/{effect-signal.test.js → core/effect-signal.test.js} +0 -0
  42. /package/src/{event-signal.test.js → core/event-signal.test.js} +0 -0
  43. /package/src/{state-signal.test.js → core/state-signal.test.js} +0 -0
package/dist/main.mjs CHANGED
@@ -1,52 +1,46 @@
1
- /* @alwatr/signal v5.0.0 */
1
+ /* @alwatr/signal v5.2.0 */
2
2
 
3
- // src/signal-base.ts
4
- import { packageTracer } from "@alwatr/package-tracer";
5
- __dev_mode__: packageTracer.add("@alwatr/signal", "5.0.0");
3
+ // src/core/signal-base.ts
6
4
  var SignalBase = class {
7
- /**
8
- * Initializes a new `SignalBase`.
9
- * @param config The configuration for the signal, containing its `signalId`.
10
- */
11
- constructor(config) {
5
+ constructor(config_) {
6
+ this.config_ = config_;
7
+ /**
8
+ * The unique identifier for this signal instance.
9
+ * Useful for debugging and logging.
10
+ */
11
+ this.signalId = this.config_.signalId;
12
12
  /**
13
13
  * The list of observers (listeners) subscribed to this signal.
14
14
  * @protected
15
15
  */
16
16
  this.observers_ = [];
17
- this.isDestroyed_ = false;
18
17
  /**
19
- * Throws an error if the signal has been destroyed.
20
- * This is a safeguard to prevent interaction with a defunct signal.
21
- * @protected
18
+ * A flag indicating whether the signal has been destroyed.
19
+ * @private
22
20
  */
23
- this.checkDestroyed_ = () => {
24
- if (this.isDestroyed_) {
25
- this.logger_.accident("checkDestroyed_", "attempt_to_use_destroyed_signal");
26
- throw new Error(`Cannot interact with a destroyed signal (id: ${this.signalId})`);
27
- }
28
- };
29
- this.signalId = config.signalId;
21
+ this.isDestroyed__ = false;
30
22
  }
31
23
  /**
32
24
  * Indicates whether the signal has been destroyed.
33
25
  * A destroyed signal cannot be used and will throw an error if interacted with.
26
+ *
34
27
  * @returns `true` if the signal is destroyed, `false` otherwise.
35
28
  */
36
29
  get isDestroyed() {
37
- return this.isDestroyed_;
30
+ return this.isDestroyed__;
38
31
  }
39
32
  /**
40
33
  * Removes a specific observer from the observers list.
34
+ *
41
35
  * @param observer The observer instance to remove.
42
36
  * @protected
43
37
  */
44
38
  removeObserver_(observer) {
45
- if (this.isDestroyed_) {
39
+ this.logger_.logMethod?.("removeObserver_");
40
+ if (this.isDestroyed__) {
46
41
  this.logger_.incident?.("removeObserver_", "remove_observer_on_destroyed_signal");
47
42
  return;
48
43
  }
49
- this.logger_.logMethod?.("removeObserver_");
50
44
  const index = this.observers_.indexOf(observer);
51
45
  if (index !== -1) {
52
46
  this.observers_.splice(index, 1);
@@ -70,8 +64,9 @@ var SignalBase = class {
70
64
  } else {
71
65
  this.observers_.push(observer);
72
66
  }
73
- const unsubscribe = () => this.removeObserver_(observer);
74
- return { unsubscribe };
67
+ return {
68
+ unsubscribe: () => this.removeObserver_(observer)
69
+ };
75
70
  }
76
71
  /**
77
72
  * Notifies all registered observers about a new value.
@@ -83,11 +78,11 @@ var SignalBase = class {
83
78
  * @protected
84
79
  */
85
80
  notify_(value) {
86
- if (this.isDestroyed_) {
81
+ this.logger_.logMethodArgs?.("notify_", value);
82
+ if (this.isDestroyed__) {
87
83
  this.logger_.incident?.("notify_", "notify_on_destroyed_signal");
88
84
  return;
89
85
  }
90
- this.logger_.logMethodArgs?.("notify_", value);
91
86
  const currentObservers = [...this.observers_];
92
87
  for (const observer of currentObservers) {
93
88
  if (observer.options?.once) {
@@ -96,9 +91,7 @@ var SignalBase = class {
96
91
  try {
97
92
  const result = observer.callback(value);
98
93
  if (result instanceof Promise) {
99
- result.catch((err) => {
100
- this.logger_.error("notify_", "async_callback_failed", err, { observer });
101
- });
94
+ result.catch((err) => this.logger_.error("notify_", "async_callback_failed", err, { observer }));
102
95
  }
103
96
  } catch (err) {
104
97
  this.logger_.error("notify_", "sync_callback_failed", err);
@@ -140,21 +133,38 @@ var SignalBase = class {
140
133
  */
141
134
  destroy() {
142
135
  this.logger_.logMethod?.("destroy");
143
- this.isDestroyed_ = true;
136
+ if (this.isDestroyed__) {
137
+ this.logger_.incident?.("destroy_", "double_destroy_attempt");
138
+ return;
139
+ }
140
+ this.isDestroyed__ = true;
144
141
  this.observers_.length = 0;
142
+ this.config_.onDestroy?.();
143
+ this.config_ = null;
144
+ }
145
+ /**
146
+ * Throws an error if the signal has been destroyed.
147
+ * This is a safeguard to prevent interaction with a defunct signal.
148
+ * @protected
149
+ */
150
+ checkDestroyed_() {
151
+ if (this.isDestroyed__) {
152
+ this.logger_.accident("checkDestroyed_", "attempt_to_use_destroyed_signal");
153
+ throw new Error(`Cannot interact with a destroyed signal (id: ${this.signalId})`);
154
+ }
145
155
  }
146
156
  };
147
157
 
148
- // src/event-signal.ts
158
+ // src/core/event-signal.ts
149
159
  import { delay } from "@alwatr/delay";
150
160
  import { createLogger } from "@alwatr/logger";
151
161
  var EventSignal = class extends SignalBase {
152
- /**
153
- * Initializes a new `EventSignal`.
154
- * @param config The configuration for the signal, containing its `signalId`.
155
- */
156
162
  constructor(config) {
157
163
  super(config);
164
+ /**
165
+ * The logger instance for this signal.
166
+ * @protected
167
+ */
158
168
  this.logger_ = createLogger(`event-signal: ${this.signalId}`);
159
169
  this.logger_.logMethod?.("constructor");
160
170
  }
@@ -166,24 +176,22 @@ var EventSignal = class extends SignalBase {
166
176
  * @param payload The data to send with the event.
167
177
  */
168
178
  dispatch(payload) {
169
- this.logger_.logMethodArgs?.("dispatch", payload);
179
+ this.logger_.logMethodArgs?.("dispatch", { payload });
170
180
  this.checkDestroyed_();
171
- delay.nextMicrotask().then(() => {
172
- this.notify_(payload);
173
- });
181
+ delay.nextMicrotask().then(() => this.notify_(payload));
174
182
  }
175
183
  };
176
184
 
177
- // src/state-signal.ts
185
+ // src/core/state-signal.ts
178
186
  import { delay as delay2 } from "@alwatr/delay";
179
187
  import { createLogger as createLogger2 } from "@alwatr/logger";
180
188
  var StateSignal = class extends SignalBase {
181
- /**
182
- * Initializes a new `StateSignal`.
183
- * @param config The configuration for the state signal, including `signalId` and `initialValue`.
184
- */
185
189
  constructor(config) {
186
190
  super(config);
191
+ /**
192
+ * The logger instance for this signal.
193
+ * @protected
194
+ */
187
195
  this.logger_ = createLogger2(`state-signal: ${this.signalId}`);
188
196
  this.value__ = config.initialValue;
189
197
  this.logger_.logMethodArgs?.("constructor", { initialValue: this.value__ });
@@ -218,11 +226,31 @@ var StateSignal = class extends SignalBase {
218
226
  set(newValue) {
219
227
  this.logger_.logMethodArgs?.("set", { newValue });
220
228
  this.checkDestroyed_();
221
- if (Object.is(this.value__, newValue) && (typeof newValue !== "object" || newValue === null)) return;
229
+ if (Object.is(this.value__, newValue) && (typeof newValue !== "object" || newValue === null)) {
230
+ return;
231
+ }
222
232
  this.value__ = newValue;
223
- delay2.nextMicrotask().then(() => {
224
- this.notify_(newValue);
225
- });
233
+ delay2.nextMicrotask().then(() => this.notify_(newValue));
234
+ }
235
+ /**
236
+ * Updates the signal's value based on its previous value.
237
+ *
238
+ * This method is particularly useful for state transitions that depend on the current value,
239
+ * especially for objects or arrays, as it promotes an immutable update pattern.
240
+ *
241
+ * @param updater A function that receives the current value and returns the new value.
242
+ *
243
+ * @example
244
+ * // For a counter
245
+ * counterSignal.update(current => current + 1);
246
+ *
247
+ * // For an object state
248
+ * userSignal.update(currentUser => ({ ...currentUser, loggedIn: true }));
249
+ */
250
+ update(updater) {
251
+ this.logger_.logMethod?.("update");
252
+ this.checkDestroyed_();
253
+ this.set(updater(this.value__));
226
254
  }
227
255
  /**
228
256
  * Subscribes a listener to this signal.
@@ -237,11 +265,8 @@ var StateSignal = class extends SignalBase {
237
265
  subscribe(callback, options = {}) {
238
266
  this.logger_.logMethodArgs?.("subscribe", { options });
239
267
  this.checkDestroyed_();
240
- const receivePrevious = options.receivePrevious !== false;
241
- if (receivePrevious) {
242
- delay2.nextMicrotask().then(() => callback(this.value__)).catch((err) => {
243
- this.logger_.error("subscribe", "run_callback_immediate_failed", err);
244
- });
268
+ if (options.receivePrevious !== false) {
269
+ delay2.nextMicrotask().then(() => callback(this.value__)).catch((err) => this.logger_.error("subscribe", "immediate_callback_failed", err));
245
270
  if (options.once) {
246
271
  return { unsubscribe: () => {
247
272
  } };
@@ -254,22 +279,25 @@ var StateSignal = class extends SignalBase {
254
279
  * This is crucial for memory management to prevent leaks.
255
280
  */
256
281
  destroy() {
257
- super.destroy();
258
282
  this.value__ = null;
283
+ super.destroy();
259
284
  }
260
285
  };
261
286
 
262
- // src/computed-signal.ts
287
+ // src/core/computed-signal.ts
263
288
  import { delay as delay3 } from "@alwatr/delay";
264
289
  import { createLogger as createLogger3 } from "@alwatr/logger";
265
290
  var ComputedSignal = class {
266
- /**
267
- * Initializes a new `ComputedSignal`.
268
- * @param config The configuration, including dependencies (`deps`) and the getter function (`get`).
269
- */
270
291
  constructor(config_) {
271
292
  this.config_ = config_;
293
+ /**
294
+ * The unique identifier for this signal instance.
295
+ */
272
296
  this.signalId = this.config_.signalId;
297
+ /**
298
+ * The logger instance for this signal.
299
+ * @protected
300
+ */
273
301
  this.logger_ = createLogger3(`computed-signal: ${this.signalId}`);
274
302
  /**
275
303
  * The internal `StateSignal` that holds the computed value.
@@ -277,17 +305,23 @@ var ComputedSignal = class {
277
305
  * @protected
278
306
  */
279
307
  this.internalSignal_ = new StateSignal({
280
- signalId: this.signalId + "-internal",
308
+ signalId: `${this.signalId}-internal`,
281
309
  initialValue: this.config_.get()
282
310
  });
283
- this.subscriptionList__ = [];
311
+ /**
312
+ * A list of subscriptions to dependency signals.
313
+ * @private
314
+ */
315
+ this.dependencySubscriptions__ = [];
316
+ /**
317
+ * A flag to prevent concurrent recalculations.
318
+ * @private
319
+ */
284
320
  this.isRecalculating__ = false;
285
- this.subscribe = this.internalSignal_.subscribe.bind(this.internalSignal_);
286
- this.untilNext = this.internalSignal_.untilNext.bind(this.internalSignal_);
287
321
  this.logger_.logMethod?.("constructor");
288
322
  this.recalculate_ = this.recalculate_.bind(this);
289
323
  for (const signal of config_.deps) {
290
- this.subscriptionList__.push(signal.subscribe(this.recalculate_, { receivePrevious: false }));
324
+ this.dependencySubscriptions__.push(signal.subscribe(this.recalculate_, { receivePrevious: false }));
291
325
  }
292
326
  }
293
327
  /**
@@ -308,6 +342,25 @@ var ComputedSignal = class {
308
342
  get isDestroyed() {
309
343
  return this.internalSignal_.isDestroyed;
310
344
  }
345
+ /**
346
+ * Subscribes a listener to this signal.
347
+ * The listener will be called whenever the computed value changes.
348
+ *
349
+ * @param callback The function to be called with the new value.
350
+ * @param options Subscription options.
351
+ * @returns A `SubscribeResult` object with an `unsubscribe` method.
352
+ */
353
+ subscribe(callback, options) {
354
+ return this.internalSignal_.subscribe(callback, options);
355
+ }
356
+ /**
357
+ * Returns a Promise that resolves with the next computed value.
358
+ *
359
+ * @returns A Promise that resolves with the next value.
360
+ */
361
+ untilNext() {
362
+ return this.internalSignal_.untilNext();
363
+ }
311
364
  /**
312
365
  * Permanently disposes of the computed signal.
313
366
  *
@@ -319,15 +372,16 @@ var ComputedSignal = class {
319
372
  */
320
373
  destroy() {
321
374
  this.logger_.logMethod?.("destroy");
322
- if (this.internalSignal_.isDestroyed) {
375
+ if (this.isDestroyed) {
323
376
  this.logger_.incident?.("destroy", "already_destroyed");
324
377
  return;
325
378
  }
326
- for (const subscription of this.subscriptionList__) {
379
+ for (const subscription of this.dependencySubscriptions__) {
327
380
  subscription.unsubscribe();
328
381
  }
329
- this.subscriptionList__.length = 0;
382
+ this.dependencySubscriptions__.length = 0;
330
383
  this.internalSignal_.destroy();
384
+ this.config_.onDestroy?.();
331
385
  this.config_ = null;
332
386
  }
333
387
  /**
@@ -339,23 +393,24 @@ var ComputedSignal = class {
339
393
  * @protected
340
394
  */
341
395
  async recalculate_() {
396
+ this.logger_.logMethod?.("recalculate_");
342
397
  if (this.internalSignal_.isDestroyed) {
343
- this.logger_.incident?.("recalculate", "recalculate_on_destroyed_signal");
398
+ this.logger_.incident?.("recalculate_", "recalculate_on_destroyed_signal");
344
399
  return;
345
400
  }
346
401
  if (this.isRecalculating__) {
347
- this.logger_.logMethod?.("recalculate_//skipped");
402
+ this.logger_.logStep?.("recalculate_", "skipping_recalculation_already_scheduled");
348
403
  return;
349
404
  }
350
- this.logger_.logMethod?.("recalculate_//scheduled");
351
405
  this.isRecalculating__ = true;
352
406
  try {
353
407
  await delay3.nextMacrotask();
354
- if (this.internalSignal_.isDestroyed) {
355
- this.logger_.incident?.("recalculate", "destroyed_during_delay");
408
+ if (this.isDestroyed) {
409
+ this.logger_.incident?.("recalculate_", "destroyed_during_delay");
410
+ this.isRecalculating__ = false;
356
411
  return;
357
412
  }
358
- this.logger_.logMethod?.("recalculate_//executing");
413
+ this.logger_.logStep?.("recalculate_", "recalculating_value");
359
414
  this.internalSignal_.set(this.config_.get());
360
415
  } catch (err) {
361
416
  this.logger_.error("recalculate_", "recalculation_failed", err);
@@ -364,24 +419,40 @@ var ComputedSignal = class {
364
419
  }
365
420
  };
366
421
 
367
- // src/effect-signal.ts
422
+ // src/core/effect-signal.ts
368
423
  import { delay as delay4 } from "@alwatr/delay";
369
424
  import { createLogger as createLogger4 } from "@alwatr/logger";
370
425
  var EffectSignal = class {
371
- /**
372
- * Initializes a new `EffectSignal`.
373
- * @param config The configuration, including dependencies (`deps`) and the `run` function.
374
- */
375
426
  constructor(config_) {
376
427
  this.config_ = config_;
377
- this.logger_ = createLogger4(`effect-signal`);
378
- this.subscriptionList__ = [];
428
+ /**
429
+ * The unique identifier for this signal instance.
430
+ */
431
+ this.signalId = this.config_.signalId ? this.config_.signalId : `[${this.config_.deps.map((dep) => dep.signalId).join(", ")}]`;
432
+ /**
433
+ * The logger instance for this signal.
434
+ * @protected
435
+ */
436
+ this.logger_ = createLogger4(`effect-signal: ${this.signalId}`);
437
+ /**
438
+ * A list of subscriptions to dependency signals.
439
+ * @private
440
+ */
441
+ this.dependencySubscriptions__ = [];
442
+ /**
443
+ * A flag to prevent concurrent executions of the effect.
444
+ * @private
445
+ */
379
446
  this.isRunning__ = false;
447
+ /**
448
+ * A flag indicating whether the effect has been destroyed.
449
+ * @private
450
+ */
380
451
  this.isDestroyed__ = false;
381
452
  this.logger_.logMethod?.("constructor");
382
453
  this.run_ = this.run_.bind(this);
383
454
  for (const signal of config_.deps) {
384
- this.subscriptionList__.push(signal.subscribe(this.run_, { receivePrevious: false }));
455
+ this.dependencySubscriptions__.push(signal.subscribe(this.run_, { receivePrevious: false }));
385
456
  }
386
457
  if (config_.runImmediately === true) {
387
458
  void this.run_();
@@ -389,7 +460,8 @@ var EffectSignal = class {
389
460
  }
390
461
  /**
391
462
  * Indicates whether the effect signal has been destroyed.
392
- * A destroyed signal cannot be used and will throw an error if interacted with.
463
+ * A destroyed signal will no longer execute its effect and cannot be reused.
464
+ *
393
465
  * @returns `true` if the signal is destroyed, `false` otherwise.
394
466
  */
395
467
  get isDestroyed() {
@@ -404,29 +476,29 @@ var EffectSignal = class {
404
476
  * @protected
405
477
  */
406
478
  async run_() {
479
+ this.logger_.logMethod?.("run_");
407
480
  if (this.isDestroyed__) {
408
481
  this.logger_.incident?.("run_", "run_on_destroyed_signal");
409
482
  return;
410
483
  }
411
484
  if (this.isRunning__) {
412
- this.logger_.logMethod?.("run_//skipped");
485
+ this.logger_.logStep?.("run_", "skipped_because_already_running");
413
486
  return;
414
487
  }
415
- this.logger_.logMethod?.("run_//scheduled");
416
488
  this.isRunning__ = true;
417
489
  try {
418
490
  await delay4.nextMacrotask();
419
491
  if (this.isDestroyed__) {
420
492
  this.logger_.incident?.("run_", "destroyed_during_delay");
493
+ this.isRunning__ = false;
421
494
  return;
422
495
  }
423
- this.logger_.logMethod?.("run_//executing");
496
+ this.logger_.logStep?.("run_", "executing_effect");
424
497
  await this.config_.run();
425
498
  } catch (err) {
426
499
  this.logger_.error("run_", "effect_failed", err);
427
- } finally {
428
- this.isRunning__ = false;
429
500
  }
501
+ this.isRunning__ = false;
430
502
  }
431
503
  /**
432
504
  * Permanently disposes of the effect signal.
@@ -442,18 +514,74 @@ var EffectSignal = class {
442
514
  return;
443
515
  }
444
516
  this.isDestroyed__ = true;
445
- for (const subscription of this.subscriptionList__) {
517
+ for (const subscription of this.dependencySubscriptions__) {
446
518
  subscription.unsubscribe();
447
519
  }
448
- this.subscriptionList__.length = 0;
520
+ this.dependencySubscriptions__.length = 0;
521
+ this.config_.onDestroy?.();
449
522
  this.config_ = null;
450
523
  }
451
524
  };
525
+
526
+ // src/creators/event.ts
527
+ function createEventSignal(config) {
528
+ return new EventSignal(config);
529
+ }
530
+
531
+ // src/creators/state.ts
532
+ function createStateSignal(config) {
533
+ return new StateSignal(config);
534
+ }
535
+
536
+ // src/creators/computed.ts
537
+ function createComputedSignal(config) {
538
+ return new ComputedSignal(config);
539
+ }
540
+
541
+ // src/creators/effect.ts
542
+ function createEffect(config) {
543
+ return new EffectSignal(config);
544
+ }
545
+
546
+ // src/operators/debounce.ts
547
+ import { createDebouncer } from "@alwatr/debounce";
548
+ function createDebouncedSignal(sourceSignal, config) {
549
+ const signalId = config.signalId ?? `${sourceSignal.signalId}-debounced`;
550
+ const internalSignal = new StateSignal({
551
+ signalId: `${signalId}-internal`,
552
+ initialValue: sourceSignal.value
553
+ });
554
+ const debouncer = createDebouncer({
555
+ ...config,
556
+ func: (value) => {
557
+ internalSignal.set(value);
558
+ }
559
+ });
560
+ const subscription = sourceSignal.subscribe(debouncer.trigger);
561
+ return createComputedSignal({
562
+ signalId,
563
+ deps: [internalSignal],
564
+ get: () => internalSignal.value,
565
+ onDestroy: () => {
566
+ if (internalSignal.isDestroyed) return;
567
+ subscription.unsubscribe();
568
+ debouncer.cancel();
569
+ internalSignal.destroy();
570
+ config.onDestroy?.();
571
+ config = null;
572
+ }
573
+ });
574
+ }
452
575
  export {
453
576
  ComputedSignal,
454
577
  EffectSignal,
455
578
  EventSignal,
456
579
  SignalBase,
457
- StateSignal
580
+ StateSignal,
581
+ createComputedSignal,
582
+ createDebouncedSignal,
583
+ createEffect,
584
+ createEventSignal,
585
+ createStateSignal
458
586
  };
459
587
  //# sourceMappingURL=main.mjs.map