@bgord/bun 1.24.2 → 1.24.4

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 (86) hide show
  1. package/dist/event-log-reader-memory.adapter.d.ts +7 -0
  2. package/dist/event-log-reader-memory.adapter.d.ts.map +1 -0
  3. package/dist/event-log-reader-memory.adapter.js +14 -0
  4. package/dist/event-log-reader-memory.adapter.js.map +1 -0
  5. package/dist/event-log-reader.port.d.ts +13 -0
  6. package/dist/event-log-reader.port.d.ts.map +1 -0
  7. package/dist/event-log-reader.port.js +2 -0
  8. package/dist/event-log-reader.port.js.map +1 -0
  9. package/dist/file-reader-raw-forgiving.adapter.js +1 -1
  10. package/dist/file-reader-raw-forgiving.adapter.js.map +1 -1
  11. package/dist/file-reader-text-forgiving.adapter.js +1 -1
  12. package/dist/file-reader-text-forgiving.adapter.js.map +1 -1
  13. package/dist/file-type-detector-text.strategy.js +1 -1
  14. package/dist/file-type-detector-text.strategy.js.map +1 -1
  15. package/dist/hash-file-metadata.adapter.d.ts +16 -0
  16. package/dist/hash-file-metadata.adapter.d.ts.map +1 -0
  17. package/dist/hash-file-metadata.adapter.js +18 -0
  18. package/dist/hash-file-metadata.adapter.js.map +1 -0
  19. package/dist/healthcheck.handler.d.ts +0 -2
  20. package/dist/healthcheck.handler.d.ts.map +1 -1
  21. package/dist/healthcheck.handler.js +0 -1
  22. package/dist/healthcheck.handler.js.map +1 -1
  23. package/dist/image-generator-web-view.adapter.d.ts +1 -0
  24. package/dist/image-generator-web-view.adapter.d.ts.map +1 -1
  25. package/dist/image-generator-web-view.adapter.js +3 -2
  26. package/dist/image-generator-web-view.adapter.js.map +1 -1
  27. package/dist/index.d.ts +5 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +5 -3
  30. package/dist/index.js.map +1 -1
  31. package/dist/job-retry-policy-composite.strategy.js +2 -1
  32. package/dist/job-retry-policy-composite.strategy.js.map +1 -1
  33. package/dist/pdf-generator-with-logger.adapter.js +1 -1
  34. package/dist/pdf-generator-with-logger.adapter.js.map +1 -1
  35. package/dist/prerequisite-verifier-sqlite-connection.adapter.d.ts +13 -0
  36. package/dist/prerequisite-verifier-sqlite-connection.adapter.d.ts.map +1 -0
  37. package/dist/prerequisite-verifier-sqlite-connection.adapter.js +20 -0
  38. package/dist/prerequisite-verifier-sqlite-connection.adapter.js.map +1 -0
  39. package/dist/projection-rebuild.service.d.ts +31 -0
  40. package/dist/projection-rebuild.service.d.ts.map +1 -0
  41. package/dist/projection-rebuild.service.js +53 -0
  42. package/dist/projection-rebuild.service.js.map +1 -0
  43. package/dist/runtime-stats-provider-noop.adapter.js +1 -1
  44. package/dist/runtime-stats-provider-noop.adapter.js.map +1 -1
  45. package/dist/runtime-stats-provider-system.adapter.d.ts.map +1 -1
  46. package/dist/runtime-stats-provider-system.adapter.js +1 -2
  47. package/dist/runtime-stats-provider-system.adapter.js.map +1 -1
  48. package/dist/runtime-stats-provider.port.d.ts +0 -2
  49. package/dist/runtime-stats-provider.port.d.ts.map +1 -1
  50. package/dist/shield-rate-limit-hono.strategy.d.ts.map +1 -1
  51. package/dist/shield-rate-limit-hono.strategy.js +4 -2
  52. package/dist/shield-rate-limit-hono.strategy.js.map +1 -1
  53. package/package.json +8 -8
  54. package/readme.md +5 -3
  55. package/src/event-log-reader-memory.adapter.ts +13 -0
  56. package/src/event-log-reader.port.ts +13 -0
  57. package/src/file-reader-raw-forgiving.adapter.ts +1 -1
  58. package/src/file-reader-text-forgiving.adapter.ts +1 -1
  59. package/src/file-type-detector-text.strategy.ts +1 -1
  60. package/src/hash-file-metadata.adapter.ts +27 -0
  61. package/src/healthcheck.handler.ts +0 -3
  62. package/src/image-generator-web-view.adapter.ts +6 -2
  63. package/src/index.ts +5 -3
  64. package/src/job-retry-policy-composite.strategy.ts +1 -1
  65. package/src/pdf-generator-with-logger.adapter.ts +1 -1
  66. package/src/prerequisite-verifier-sqlite-connection.adapter.ts +27 -0
  67. package/src/projection-rebuild.service.ts +81 -0
  68. package/src/runtime-stats-provider-noop.adapter.ts +1 -1
  69. package/src/runtime-stats-provider-system.adapter.ts +1 -2
  70. package/src/runtime-stats-provider.port.ts +1 -2
  71. package/src/shield-rate-limit-hono.strategy.ts +4 -2
  72. package/dist/checksum.service.d.ts +0 -5
  73. package/dist/checksum.service.d.ts.map +0 -1
  74. package/dist/checksum.service.js +0 -8
  75. package/dist/checksum.service.js.map +0 -1
  76. package/dist/clock-offset.adapter.d.ts +0 -13
  77. package/dist/clock-offset.adapter.d.ts.map +0 -1
  78. package/dist/clock-offset.adapter.js +0 -12
  79. package/dist/clock-offset.adapter.js.map +0 -1
  80. package/dist/event-loop-utilization.service.d.ts +0 -6
  81. package/dist/event-loop-utilization.service.d.ts.map +0 -1
  82. package/dist/event-loop-utilization.service.js +0 -15
  83. package/dist/event-loop-utilization.service.js.map +0 -1
  84. package/src/checksum.service.ts +0 -11
  85. package/src/clock-offset.adapter.ts +0 -15
  86. package/src/event-loop-utilization.service.ts +0 -23
@@ -0,0 +1,31 @@
1
+ import type * as tools from "@bgord/tools";
2
+ import type { GenericEvent } from "./event.types";
3
+ import type { EventLogReaderPort } from "./event-log-reader.port";
4
+ import type { EventUpcasterPort } from "./event-upcaster.port";
5
+ import type { EventValidatorRegistryPort } from "./event-validator-registry.port";
6
+ import type { LoggerPort } from "./logger.port";
7
+ import type { EventBusPort } from "./message-bus.port";
8
+ import type { PayloadSerializerPort } from "./payload-serializer.port";
9
+ type Config = {
10
+ batch: tools.IntegerPositiveType;
11
+ };
12
+ type Dependencies<Event extends GenericEvent> = {
13
+ EventLogReader: EventLogReaderPort;
14
+ EventBus: EventBusPort<Event>;
15
+ registry: EventValidatorRegistryPort<Event>;
16
+ serializer: PayloadSerializerPort;
17
+ upcaster?: EventUpcasterPort;
18
+ transaction: (fn: () => Promise<void>) => Promise<void>;
19
+ clear: () => Promise<void>;
20
+ Logger: LoggerPort;
21
+ };
22
+ export declare class ProjectionRebuild<Event extends GenericEvent> {
23
+ private readonly config;
24
+ private readonly deps;
25
+ constructor(config: Config, deps: Dependencies<Event>);
26
+ run(): Promise<void>;
27
+ private entries;
28
+ private replay;
29
+ }
30
+ export {};
31
+ //# sourceMappingURL=projection-rebuild.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection-rebuild.service.d.ts","sourceRoot":"","sources":["../src/projection-rebuild.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAiB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,KAAK,MAAM,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC,mBAAmB,CAAA;CAAE,CAAC;AAEnD,KAAK,YAAY,CAAC,KAAK,SAAS,YAAY,IAAI;IAC9C,cAAc,EAAE,kBAAkB,CAAC;IACnC,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,EAAE,0BAA0B,CAAC,KAAK,CAAC,CAAC;IAC5C,UAAU,EAAE,qBAAqB,CAAC;IAClC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,qBAAa,iBAAiB,CAAC,KAAK,SAAS,YAAY;IAErD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFvB,YACmB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,EACxC;IAEE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAQzB;YAEc,OAAO;YAmBR,MAAM;CAqBrB"}
@@ -0,0 +1,53 @@
1
+ import { CorrelationStorage } from "./correlation-storage.service";
2
+ export class ProjectionRebuild {
3
+ config;
4
+ deps;
5
+ constructor(config, deps) {
6
+ this.config = config;
7
+ this.deps = deps;
8
+ }
9
+ async run() {
10
+ await this.deps.transaction(async () => {
11
+ await this.deps.clear();
12
+ for await (const entry of this.entries()) {
13
+ await CorrelationStorage.run(entry.correlationId, () => this.replay(entry));
14
+ }
15
+ });
16
+ }
17
+ async *entries() {
18
+ let after = 0;
19
+ while (true) {
20
+ const page = await this.deps.EventLogReader.read({
21
+ names: this.deps.registry.names,
22
+ after,
23
+ limit: this.config.batch,
24
+ });
25
+ for (const entry of page) {
26
+ after = entry.position;
27
+ yield entry;
28
+ }
29
+ if (page.length < this.config.batch)
30
+ return;
31
+ }
32
+ }
33
+ async replay(entry) {
34
+ const { position, ...serialized } = entry;
35
+ try {
36
+ const deserialized = { ...serialized, payload: this.deps.serializer.deserialize(serialized.payload) };
37
+ const upcasted = this.deps.upcaster ? this.deps.upcaster.upcast(deserialized) : deserialized;
38
+ await this.deps.EventBus.emit(this.deps.registry.validate(upcasted));
39
+ }
40
+ catch (error) {
41
+ this.deps.Logger.error({
42
+ message: "Projection rebuild error",
43
+ correlationId: entry.correlationId,
44
+ component: "infra",
45
+ operation: "projection_rebuild",
46
+ metadata: { position, id: entry.id, name: entry.name },
47
+ error,
48
+ });
49
+ throw error;
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=projection-rebuild.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection-rebuild.service.js","sourceRoot":"","sources":["../src/projection-rebuild.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAsBnE,MAAM,OAAO,iBAAiB;IAET,MAAM;IACN,IAAI;IAFvB,YACmB,MAAc,EACd,IAAyB;sBADzB,MAAM;oBACN,IAAI;IACpB,CAAC;IAEJ,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;YACrC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAExB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;gBACzC,MAAM,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,CAAC,OAAO;QACpB,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBAC/C,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK;gBAC/B,KAAK;gBACL,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;aACzB,CAAC,CAAC;YAEH,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;gBACzB,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC;gBACvB,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK;gBAAE,OAAO;QAC9C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,KAAoB;QACvC,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACtG,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;YAE7F,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;gBACrB,OAAO,EAAE,0BAA0B;gBACnC,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,SAAS,EAAE,OAAO;gBAClB,SAAS,EAAE,oBAAoB;gBAC/B,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;gBACtD,KAAK;aACN,CAAC,CAAC;YAEH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
@@ -6,7 +6,7 @@ export class RuntimeStatsProviderNoopAdapter {
6
6
  return {
7
7
  uptime: { duration: zero, formatted: "0 seconds ago" },
8
8
  memory: { total: empty, heap: { used: empty, total: empty } },
9
- eventLoop: { lag: { p50: zero, p95: zero, p99: zero }, utilization: 0 },
9
+ eventLoop: { lag: { p50: zero, p95: zero, p99: zero } },
10
10
  inFlight: tools.Int.of(0),
11
11
  };
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-stats-provider-noop.adapter.js","sourceRoot":"","sources":["../src/runtime-stats-provider-noop.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,MAAM,OAAO,+BAA+B;IAC1C,QAAQ;QACN,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAEtC,OAAO;YACL,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE;YACtD,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YAC7D,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE;YACvE,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1B,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"runtime-stats-provider-noop.adapter.js","sourceRoot":"","sources":["../src/runtime-stats-provider-noop.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,MAAM,OAAO,+BAA+B;IAC1C,QAAQ;QACN,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAEtC,OAAO;YACL,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE;YACtD,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YAC7D,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YACvD,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1B,CAAC;IACJ,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-stats-provider-system.adapter.d.ts","sourceRoot":"","sources":["../src/runtime-stats-provider-system.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAK9C,OAAO,KAAK,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGpG,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAEzC,qBAAa,iCAAkC,YAAW,wBAAwB;IACpE,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,YAAY,EAE9C;IAED,QAAQ,IAAI,oBAAoB,CAO/B;CACF"}
1
+ {"version":3,"file":"runtime-stats-provider-system.adapter.d.ts","sourceRoot":"","sources":["../src/runtime-stats-provider-system.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,OAAO,KAAK,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGpG,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAEzC,qBAAa,iCAAkC,YAAW,wBAAwB;IACpE,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,YAAY,EAE9C;IAED,QAAQ,IAAI,oBAAoB,CAO/B;CACF"}
@@ -1,5 +1,4 @@
1
1
  import { EventLoopLag } from "./event-loop-lag.service";
2
- import { EventLoopUtilization } from "./event-loop-utilization.service";
3
2
  import { InFlightRequestsTracker } from "./in-flight-requests-tracker.service";
4
3
  import { MemoryConsumption } from "./memory-consumption.service";
5
4
  import { Uptime } from "./uptime.service";
@@ -13,7 +12,7 @@ export class RuntimeStatsProviderSystemAdapter {
13
12
  return {
14
13
  uptime: Uptime.get(this.deps.Clock),
15
14
  memory: MemoryConsumption.snapshot(),
16
- eventLoop: { lag: EventLoopLag.snapshot(), utilization: EventLoopUtilization.snapshot() },
15
+ eventLoop: { lag: EventLoopLag.snapshot() },
17
16
  inFlight: InFlightRequestsTracker.get(),
18
17
  };
19
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-stats-provider-system.adapter.js","sourceRoot":"","sources":["../src/runtime-stats-provider-system.adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI1C,MAAM,OAAO,iCAAiC;IACf,IAAI;IAAjC,YAA6B,IAAkB;oBAAlB,IAAI;QAC/B,YAAY,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,QAAQ;QACN,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACnC,MAAM,EAAE,iBAAiB,CAAC,QAAQ,EAAE;YACpC,SAAS,EAAE,EAAE,GAAG,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,oBAAoB,CAAC,QAAQ,EAAE,EAAE;YACzF,QAAQ,EAAE,uBAAuB,CAAC,GAAG,EAAE;SACxC,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"runtime-stats-provider-system.adapter.js","sourceRoot":"","sources":["../src/runtime-stats-provider-system.adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI1C,MAAM,OAAO,iCAAiC;IACf,IAAI;IAAjC,YAA6B,IAAkB;oBAAlB,IAAI;QAC/B,YAAY,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,QAAQ;QACN,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACnC,MAAM,EAAE,iBAAiB,CAAC,QAAQ,EAAE;YACpC,SAAS,EAAE,EAAE,GAAG,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE;YAC3C,QAAQ,EAAE,uBAAuB,CAAC,GAAG,EAAE;SACxC,CAAC;IACJ,CAAC;CACF"}
@@ -1,6 +1,5 @@
1
1
  import type * as tools from "@bgord/tools";
2
2
  import type { EventLoopLagSnapshotType } from "./event-loop-lag.service";
3
- import type { EventLoopUtilizationSnapshot } from "./event-loop-utilization.service";
4
3
  import type { MemoryConsumptionSnapshotType } from "./memory-consumption.service";
5
4
  import type { UptimeResultType } from "./uptime.service";
6
5
  export type RuntimeStatsSnapshot = {
@@ -8,7 +7,6 @@ export type RuntimeStatsSnapshot = {
8
7
  memory: MemoryConsumptionSnapshotType;
9
8
  eventLoop: {
10
9
  lag: EventLoopLagSnapshotType;
11
- utilization: EventLoopUtilizationSnapshot;
12
10
  };
13
11
  inFlight: tools.IntegerType;
14
12
  };
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-stats-provider.port.d.ts","sourceRoot":"","sources":["../src/runtime-stats-provider.port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,6BAA6B,CAAC;IACtC,SAAS,EAAE;QAAE,GAAG,EAAE,wBAAwB,CAAC;QAAC,WAAW,EAAE,4BAA4B,CAAA;KAAE,CAAC;IACxF,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC;CAC7B,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,IAAI,oBAAoB,CAAC;CAClC"}
1
+ {"version":3,"file":"runtime-stats-provider.port.d.ts","sourceRoot":"","sources":["../src/runtime-stats-provider.port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,6BAA6B,CAAC;IACtC,SAAS,EAAE;QAAE,GAAG,EAAE,wBAAwB,CAAA;KAAE,CAAC;IAC7C,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC;CAC7B,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,IAAI,oBAAoB,CAAC;CAClC"}
@@ -1 +1 @@
1
- {"version":3,"file":"shield-rate-limit-hono.strategy.d.ts","sourceRoot":"","sources":["../src/shield-rate-limit-hono.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EACL,KAAK,qBAAqB,EAG3B,MAAM,8BAA8B,CAAC;AAEtC,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,eAAe,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE/E,qBAAa,2BAA4B,YAAW,kBAAkB;IACpE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IAEnD,YAAY,MAAM,EAAE,qBAAqB,EAAE,IAAI,EAAE,YAAY,EAE5D;IAED,MAAM,IAAI,iBAAiB,CAW1B;CACF"}
1
+ {"version":3,"file":"shield-rate-limit-hono.strategy.d.ts","sourceRoot":"","sources":["../src/shield-rate-limit-hono.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EACL,KAAK,qBAAqB,EAG3B,MAAM,8BAA8B,CAAC;AAEtC,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,eAAe,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE/E,qBAAa,2BAA4B,YAAW,kBAAkB;IACpE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IAEnD,YAAY,MAAM,EAAE,qBAAqB,EAAE,IAAI,EAAE,YAAY,EAE5D;IAED,MAAM,IAAI,iBAAiB,CAa1B;CACF"}
@@ -12,8 +12,10 @@ export class ShieldRateLimitHonoStrategy {
12
12
  const result = await this.strategy.evaluate(context);
13
13
  if (result.allowed)
14
14
  return next();
15
- c.header("Retry-After", result.retryAfter.seconds.toString());
16
- throw new HTTPException(429, { message: ShieldRateLimitStrategyError.Rejected });
15
+ throw new HTTPException(429, {
16
+ message: ShieldRateLimitStrategyError.Rejected,
17
+ res: new Response(null, { headers: { "Retry-After": result.retryAfter.seconds.toString() } }),
18
+ });
17
19
  };
18
20
  }
19
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shield-rate-limit-hono.strategy.js","sourceRoot":"","sources":["../src/shield-rate-limit-hono.strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAEL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,8BAA8B,CAAC;AAItC,MAAM,OAAO,2BAA2B;IACrB,QAAQ,CAA0B;IAEnD,YAAY,MAA6B,EAAE,IAAkB;QAC3D,IAAI,CAAC,QAAQ,GAAG,IAAI,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,OAAO,GAAG,IAAI,yBAAyB,CAAC,CAAC,CAAC,CAAC;YAEjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAErD,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,IAAI,EAAE,CAAC;YAElC,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC9D,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,4BAA4B,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnF,CAAC,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"shield-rate-limit-hono.strategy.js","sourceRoot":"","sources":["../src/shield-rate-limit-hono.strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAEL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,8BAA8B,CAAC;AAItC,MAAM,OAAO,2BAA2B;IACrB,QAAQ,CAA0B;IAEnD,YAAY,MAA6B,EAAE,IAAkB;QAC3D,IAAI,CAAC,QAAQ,GAAG,IAAI,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,OAAO,GAAG,IAAI,yBAAyB,CAAC,CAAC,CAAC,CAAC;YAEjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAErD,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,IAAI,EAAE,CAAC;YAElC,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE;gBAC3B,OAAO,EAAE,4BAA4B,CAAC,QAAQ;gBAC9C,GAAG,EAAE,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC;aAC9F,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bgord/bun",
3
- "version": "1.24.2",
3
+ "version": "1.24.4",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Bartosz Gordon",
@@ -24,14 +24,14 @@
24
24
  "@standard-schema/spec": "1.1.0",
25
25
  "@stryker-mutator/core": "10.0.0",
26
26
  "@stryker-mutator/typescript-checker": "10.0.0",
27
- "@types/bun": "1.4.2",
27
+ "@types/bun": "1.4.3",
28
28
  "@types/nodemailer": "8.0.2",
29
29
  "better-auth": "1.7.7",
30
30
  "cspell": "10.3.6",
31
- "fallow": "3.31.0",
32
- "lefthook": "2.1.14",
33
- "lockfile-lint": "5.0.1",
34
- "nodemailer": "10.0.10",
31
+ "fallow": "3.33.1",
32
+ "lefthook": "2.2.1",
33
+ "lockfile-lint": "5.1.0",
34
+ "nodemailer": "10.1.0",
35
35
  "publint": "0.3.25",
36
36
  "shellcheck": "4.1.0",
37
37
  "typescript": "7.0.2"
@@ -39,12 +39,12 @@
39
39
  "dependencies": {
40
40
  "@bgord/tools": "1.6.14",
41
41
  "emittery": "2.1.0",
42
- "hono": "4.13.8",
42
+ "hono": "4.13.13",
43
43
  "node-cache": "5.1.2"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "better-auth": "1.7.7",
47
- "nodemailer": "10.0.10"
47
+ "nodemailer": "10.1.0"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "better-auth": {
package/readme.md CHANGED
@@ -94,12 +94,10 @@ src/
94
94
  ├── certificate-inspector-noop.adapter.ts
95
95
  ├── certificate-inspector-tls.adapter.ts
96
96
  ├── certificate-inspector.port.ts
97
- ├── checksum.service.ts
98
97
  ├── client-ip.vo.ts
99
98
  ├── client-user-agent.vo.ts
100
99
  ├── client.vo.ts
101
100
  ├── clock-fixed.adapter.ts
102
- ├── clock-offset.adapter.ts
103
101
  ├── clock-system.adapter.ts
104
102
  ├── clock.port.ts
105
103
  ├── command-envelope.ts
@@ -174,8 +172,9 @@ src/
174
172
  ├── event-finder.port.ts
175
173
  ├── event-inserter-noop.adapter.ts
176
174
  ├── event-inserter.port.ts
175
+ ├── event-log-reader-memory.adapter.ts
176
+ ├── event-log-reader.port.ts
177
177
  ├── event-loop-lag.service.ts
178
- ├── event-loop-utilization.service.ts
179
178
  ├── event-revision-assigner.adapter.ts
180
179
  ├── event-revision-assigner.port.ts
181
180
  ├── event-sourced-repository.adapter.ts
@@ -252,6 +251,7 @@ src/
252
251
  ├── hash-content-noop.strategy.ts
253
252
  ├── hash-content-sha256.strategy.ts
254
253
  ├── hash-content.strategy.ts
254
+ ├── hash-file-metadata.adapter.ts
255
255
  ├── hash-file-noop.adapter.ts
256
256
  ├── hash-file-sha256.adapter.ts
257
257
  ├── hash-file.port.ts
@@ -482,6 +482,7 @@ src/
482
482
  ├── prerequisite-verifier-self.adapter.ts
483
483
  ├── prerequisite-verifier-sms.adapter.ts
484
484
  ├── prerequisite-verifier-space.adapter.ts
485
+ ├── prerequisite-verifier-sqlite-connection.adapter.ts
485
486
  ├── prerequisite-verifier-sqlite.adapter.ts
486
487
  ├── prerequisite-verifier-ssl-certificate-expiry.adapter.ts
487
488
  ├── prerequisite-verifier-timezone-utc.adapter.ts
@@ -494,6 +495,7 @@ src/
494
495
  ├── prerequisite-verifier.decorator.ts
495
496
  ├── prerequisite-verifier.port.ts
496
497
  ├── prerequisite.vo.ts
498
+ ├── projection-rebuild.service.ts
497
499
  ├── randomness-crypto.strategy.ts
498
500
  ├── randomness-math.strategy.ts
499
501
  ├── randomness-noop.strategy.ts
@@ -0,0 +1,13 @@
1
+ import type { EventLogEntry, EventLogReadConfig, EventLogReaderPort } from "./event-log-reader.port";
2
+
3
+ export class EventLogReaderMemoryAdapter implements EventLogReaderPort {
4
+ constructor(private readonly entries: ReadonlyArray<EventLogEntry>) {}
5
+
6
+ async read(config: EventLogReadConfig): Promise<ReadonlyArray<EventLogEntry>> {
7
+ return this.entries
8
+ .filter((entry) => config.names.includes(entry.name))
9
+ .filter((entry) => entry.position > config.after)
10
+ .toSorted((a, b) => a.position - b.position)
11
+ .slice(0, config.limit);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ import type { GenericEvent, GenericEventSerialized } from "./event.types";
2
+
3
+ export type EventLogEntry = GenericEventSerialized & { position: number };
4
+
5
+ export type EventLogReadConfig = {
6
+ names: ReadonlyArray<GenericEvent["name"]>;
7
+ after: number;
8
+ limit: number;
9
+ };
10
+
11
+ export interface EventLogReaderPort {
12
+ read(config: EventLogReadConfig): Promise<ReadonlyArray<EventLogEntry>>;
13
+ }
@@ -7,7 +7,7 @@ export class FileReaderRawForgivingAdapter implements FileReaderRawPort {
7
7
 
8
8
  async read(path: tools.FilePathRelative | tools.FilePathAbsolute | string): Promise<ArrayBuffer> {
9
9
  try {
10
- return Bun.file(typeof path === "string" ? path : path.get()).arrayBuffer();
10
+ return await Bun.file(typeof path === "string" ? path : path.get()).arrayBuffer();
11
11
  } catch {
12
12
  return this.fallback;
13
13
  }
@@ -7,7 +7,7 @@ export class FileReaderTextForgivingAdapter implements FileReaderTextPort {
7
7
 
8
8
  async read(path: tools.FilePathRelative | tools.FilePathAbsolute | string): Promise<string> {
9
9
  try {
10
- return Bun.file(typeof path === "string" ? path : path.get()).text();
10
+ return await Bun.file(typeof path === "string" ? path : path.get()).text();
11
11
  } catch {
12
12
  return this.fallback;
13
13
  }
@@ -15,7 +15,7 @@ export class FileTypeDetectorTextStrategy implements FileTypeDetectorStrategy {
15
15
  if (bytes.length === 0) return null;
16
16
  if (bytes.some(isControlByte)) return null;
17
17
 
18
- const text = new TextDecoder().decode(bytes);
18
+ const text = new TextDecoder().decode(bytes, { stream: file.size > bytes.length });
19
19
 
20
20
  if (text.includes("\ufffd")) return null;
21
21
  if (text.trimStart().startsWith("<")) return null;
@@ -0,0 +1,27 @@
1
+ import * as tools from "@bgord/tools";
2
+ import type { FileInspectionPort } from "./file-inspection.port";
3
+ import type { HashContentStrategy } from "./hash-content.strategy";
4
+ import type { HashFilePort, HashFileResult } from "./hash-file.port";
5
+
6
+ type Dependencies = {
7
+ HashContent: HashContentStrategy;
8
+ FileInspection: FileInspectionPort;
9
+ MimeRegistry: tools.MimeRegistry;
10
+ };
11
+
12
+ export class HashFileMetadataAdapter implements HashFilePort {
13
+ constructor(private readonly deps: Dependencies) {}
14
+
15
+ async hash(path: tools.FilePathAbsolute | tools.FilePathRelative): Promise<HashFileResult> {
16
+ const extension = path.getFilename().getExtension();
17
+ const mime = this.deps.MimeRegistry.fromExtension(extension);
18
+
19
+ if (!mime) throw new Error(tools.MimeRegistryError.MimeNotFound);
20
+
21
+ const size = await this.deps.FileInspection.size(path);
22
+ const lastModified = await this.deps.FileInspection.lastModified(path);
23
+ const etag = await this.deps.HashContent.hash(`${size.toBytes()}:${lastModified.ms}`);
24
+
25
+ return { etag, size, lastModified, mime };
26
+ }
27
+ }
@@ -3,7 +3,6 @@ import * as tools from "@bgord/tools";
3
3
  import type { BuildInfoType } from "./build-info.vo";
4
4
  import type { ClockPort } from "./clock.port";
5
5
  import type { CommitShaValueType } from "./commit-sha-value.vo";
6
- import type { EventLoopUtilizationSnapshot } from "./event-loop-utilization.service";
7
6
  import type { JobQueueStatsProviderPort, JobQueueStatsSnapshot } from "./job-queue-stats-provider.port";
8
7
  import type { LoggerStatsProviderPort, LoggerStatsSnapshot } from "./logger-stats-provider.port";
9
8
  import type { NodeEnvironmentEnum } from "./node-env.vo";
@@ -73,7 +72,6 @@ export type HealthcheckResult = {
73
72
  };
74
73
  eventLoop: {
75
74
  lag: { p50: tools.DurationMsType; p95: tools.DurationMsType; p99: tools.DurationMsType };
76
- utilization: EventLoopUtilizationSnapshot;
77
75
  };
78
76
  inFlight: tools.IntegerType;
79
77
  };
@@ -171,7 +169,6 @@ export class HealthcheckHandler {
171
169
  },
172
170
  eventLoop: {
173
171
  lag: { p50: eventLoop.lag.p50.ms, p95: eventLoop.lag.p95.ms, p99: eventLoop.lag.p99.ms },
174
- utilization: eventLoop.utilization,
175
172
  },
176
173
  inFlight,
177
174
  },
@@ -6,11 +6,15 @@ import type {
6
6
  } from "./image-generator.port";
7
7
 
8
8
  export class ImageGeneratorWebViewAdapter implements ImageGeneratorPort {
9
+ static readonly CSP =
10
+ `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; img-src data: http: https:; font-src data:">`;
11
+
9
12
  async generate(config: ImageGeneratorConfig): Promise<Uint8Array<ArrayBuffer>> {
10
13
  await using view = new Bun.WebView(config);
11
14
 
12
- // TODO: Potential XSS risk
13
- await view.navigate(`data:text/html;charset=utf-8,${encodeURIComponent(config.template)}`);
15
+ const html = ImageGeneratorWebViewAdapter.CSP + config.template;
16
+
17
+ await view.navigate(`data:text/html;charset=utf-8,${encodeURIComponent(html)}`);
14
18
 
15
19
  const image = await view.screenshot({
16
20
  encoding: "buffer",
package/src/index.ts CHANGED
@@ -69,13 +69,11 @@ export * from "./cache-value.vo";
69
69
  export * from "./certificate-inspector.port";
70
70
  export * from "./certificate-inspector-noop.adapter";
71
71
  export * from "./certificate-inspector-tls.adapter";
72
- export * from "./checksum.service";
73
72
  export * from "./client.vo";
74
73
  export * from "./client-ip.vo";
75
74
  export * from "./client-user-agent.vo";
76
75
  export * from "./clock.port";
77
76
  export * from "./clock-fixed.adapter";
78
- export * from "./clock-offset.adapter";
79
77
  export * from "./clock-system.adapter";
80
78
  export * from "./command-envelope";
81
79
  export * from "./commit-sha.vo";
@@ -148,8 +146,9 @@ export * from "./event-finder-last-noop.adapter";
148
146
  export * from "./event-finder-noop.adapter";
149
147
  export * from "./event-inserter.port";
150
148
  export * from "./event-inserter-noop.adapter";
149
+ export * from "./event-log-reader.port";
150
+ export * from "./event-log-reader-memory.adapter";
151
151
  export * from "./event-loop-lag.service";
152
- export * from "./event-loop-utilization.service";
153
152
  export * from "./event-revision-assigner.adapter";
154
153
  export * from "./event-revision-assigner.port";
155
154
  export * from "./event-sourced-repository.adapter";
@@ -226,6 +225,7 @@ export * from "./hash-content.strategy";
226
225
  export * from "./hash-content-noop.strategy";
227
226
  export * from "./hash-content-sha256.strategy";
228
227
  export * from "./hash-file.port";
228
+ export * from "./hash-file-metadata.adapter";
229
229
  export * from "./hash-file-noop.adapter";
230
230
  export * from "./hash-file-sha256.adapter";
231
231
  export * from "./hash-value.vo";
@@ -412,9 +412,11 @@ export * from "./prerequisite-verifier-self.adapter";
412
412
  export * from "./prerequisite-verifier-sms.adapter";
413
413
  export * from "./prerequisite-verifier-space.adapter";
414
414
  export * from "./prerequisite-verifier-sqlite.adapter";
415
+ export * from "./prerequisite-verifier-sqlite-connection.adapter";
415
416
  export * from "./prerequisite-verifier-ssl-certificate-expiry.adapter";
416
417
  export * from "./prerequisite-verifier-timezone-utc.adapter";
417
418
  export * from "./prerequisite-verifier-translations.adapter";
419
+ export * from "./projection-rebuild.service";
418
420
  export * from "./randomness.strategy";
419
421
  export * from "./randomness-crypto.strategy";
420
422
  export * from "./randomness-math.strategy";
@@ -21,7 +21,7 @@ export class JobRetryPolicyCompositeStrategy implements JobRetryPolicyStrategy {
21
21
 
22
22
  if (!result) return false;
23
23
 
24
- delay = result;
24
+ if (result.isLongerThan(delay)) delay = result;
25
25
  }
26
26
 
27
27
  return delay;
@@ -19,7 +19,7 @@ export class PdfGeneratorWithLoggerAdapter implements PdfGeneratorPort {
19
19
  this.deps.Logger.info({
20
20
  message: "PDF generator attempt",
21
21
  correlationId: CorrelationStorage.get(),
22
- metadata: { template, data },
22
+ metadata: { template },
23
23
  ...this.base,
24
24
  });
25
25
 
@@ -0,0 +1,27 @@
1
+ // [BUN DEPENDENCY]
2
+ import type { Database } from "bun:sqlite";
3
+ import {
4
+ PrerequisiteVerification,
5
+ type PrerequisiteVerificationResult,
6
+ type PrerequisiteVerifierPort,
7
+ } from "./prerequisite-verifier.port";
8
+
9
+ type Config = { sqlite: Database };
10
+
11
+ export class PrerequisiteVerifierSQLiteConnectionAdapter implements PrerequisiteVerifierPort {
12
+ constructor(private readonly config: Config) {}
13
+
14
+ async verify(): Promise<PrerequisiteVerificationResult> {
15
+ try {
16
+ this.config.sqlite.query("SELECT 1").get();
17
+
18
+ return PrerequisiteVerification.success;
19
+ } catch (error) {
20
+ return PrerequisiteVerification.failure(error);
21
+ }
22
+ }
23
+
24
+ get kind(): string {
25
+ return "sqlite-connection";
26
+ }
27
+ }
@@ -0,0 +1,81 @@
1
+ // cSpell:ignore upcasted
2
+ import type * as tools from "@bgord/tools";
3
+ import { CorrelationStorage } from "./correlation-storage.service";
4
+ import type { GenericEvent } from "./event.types";
5
+ import type { EventLogEntry, EventLogReaderPort } from "./event-log-reader.port";
6
+ import type { EventUpcasterPort } from "./event-upcaster.port";
7
+ import type { EventValidatorRegistryPort } from "./event-validator-registry.port";
8
+ import type { LoggerPort } from "./logger.port";
9
+ import type { EventBusPort } from "./message-bus.port";
10
+ import type { PayloadSerializerPort } from "./payload-serializer.port";
11
+
12
+ type Config = { batch: tools.IntegerPositiveType };
13
+
14
+ type Dependencies<Event extends GenericEvent> = {
15
+ EventLogReader: EventLogReaderPort;
16
+ EventBus: EventBusPort<Event>;
17
+ registry: EventValidatorRegistryPort<Event>;
18
+ serializer: PayloadSerializerPort;
19
+ upcaster?: EventUpcasterPort;
20
+ transaction: (fn: () => Promise<void>) => Promise<void>;
21
+ clear: () => Promise<void>;
22
+ Logger: LoggerPort;
23
+ };
24
+
25
+ export class ProjectionRebuild<Event extends GenericEvent> {
26
+ constructor(
27
+ private readonly config: Config,
28
+ private readonly deps: Dependencies<Event>,
29
+ ) {}
30
+
31
+ async run(): Promise<void> {
32
+ await this.deps.transaction(async () => {
33
+ await this.deps.clear();
34
+
35
+ for await (const entry of this.entries()) {
36
+ await CorrelationStorage.run(entry.correlationId, () => this.replay(entry));
37
+ }
38
+ });
39
+ }
40
+
41
+ private async *entries(): AsyncGenerator<EventLogEntry> {
42
+ let after = 0;
43
+
44
+ while (true) {
45
+ const page = await this.deps.EventLogReader.read({
46
+ names: this.deps.registry.names,
47
+ after,
48
+ limit: this.config.batch,
49
+ });
50
+
51
+ for (const entry of page) {
52
+ after = entry.position;
53
+ yield entry;
54
+ }
55
+
56
+ if (page.length < this.config.batch) return;
57
+ }
58
+ }
59
+
60
+ private async replay(entry: EventLogEntry): Promise<void> {
61
+ const { position, ...serialized } = entry;
62
+
63
+ try {
64
+ const deserialized = { ...serialized, payload: this.deps.serializer.deserialize(serialized.payload) };
65
+ const upcasted = this.deps.upcaster ? this.deps.upcaster.upcast(deserialized) : deserialized;
66
+
67
+ await this.deps.EventBus.emit(this.deps.registry.validate(upcasted));
68
+ } catch (error) {
69
+ this.deps.Logger.error({
70
+ message: "Projection rebuild error",
71
+ correlationId: entry.correlationId,
72
+ component: "infra",
73
+ operation: "projection_rebuild",
74
+ metadata: { position, id: entry.id, name: entry.name },
75
+ error,
76
+ });
77
+
78
+ throw error;
79
+ }
80
+ }
81
+ }
@@ -9,7 +9,7 @@ export class RuntimeStatsProviderNoopAdapter implements RuntimeStatsProviderPort
9
9
  return {
10
10
  uptime: { duration: zero, formatted: "0 seconds ago" },
11
11
  memory: { total: empty, heap: { used: empty, total: empty } },
12
- eventLoop: { lag: { p50: zero, p95: zero, p99: zero }, utilization: 0 },
12
+ eventLoop: { lag: { p50: zero, p95: zero, p99: zero } },
13
13
  inFlight: tools.Int.of(0),
14
14
  };
15
15
  }
@@ -1,6 +1,5 @@
1
1
  import type { ClockPort } from "./clock.port";
2
2
  import { EventLoopLag } from "./event-loop-lag.service";
3
- import { EventLoopUtilization } from "./event-loop-utilization.service";
4
3
  import { InFlightRequestsTracker } from "./in-flight-requests-tracker.service";
5
4
  import { MemoryConsumption } from "./memory-consumption.service";
6
5
  import type { RuntimeStatsProviderPort, RuntimeStatsSnapshot } from "./runtime-stats-provider.port";
@@ -17,7 +16,7 @@ export class RuntimeStatsProviderSystemAdapter implements RuntimeStatsProviderPo
17
16
  return {
18
17
  uptime: Uptime.get(this.deps.Clock),
19
18
  memory: MemoryConsumption.snapshot(),
20
- eventLoop: { lag: EventLoopLag.snapshot(), utilization: EventLoopUtilization.snapshot() },
19
+ eventLoop: { lag: EventLoopLag.snapshot() },
21
20
  inFlight: InFlightRequestsTracker.get(),
22
21
  };
23
22
  }
@@ -1,13 +1,12 @@
1
1
  import type * as tools from "@bgord/tools";
2
2
  import type { EventLoopLagSnapshotType } from "./event-loop-lag.service";
3
- import type { EventLoopUtilizationSnapshot } from "./event-loop-utilization.service";
4
3
  import type { MemoryConsumptionSnapshotType } from "./memory-consumption.service";
5
4
  import type { UptimeResultType } from "./uptime.service";
6
5
 
7
6
  export type RuntimeStatsSnapshot = {
8
7
  uptime: UptimeResultType;
9
8
  memory: MemoryConsumptionSnapshotType;
10
- eventLoop: { lag: EventLoopLagSnapshotType; utilization: EventLoopUtilizationSnapshot };
9
+ eventLoop: { lag: EventLoopLagSnapshotType };
11
10
  inFlight: tools.IntegerType;
12
11
  };
13
12