@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.
- package/dist/event-log-reader-memory.adapter.d.ts +7 -0
- package/dist/event-log-reader-memory.adapter.d.ts.map +1 -0
- package/dist/event-log-reader-memory.adapter.js +14 -0
- package/dist/event-log-reader-memory.adapter.js.map +1 -0
- package/dist/event-log-reader.port.d.ts +13 -0
- package/dist/event-log-reader.port.d.ts.map +1 -0
- package/dist/event-log-reader.port.js +2 -0
- package/dist/event-log-reader.port.js.map +1 -0
- package/dist/file-reader-raw-forgiving.adapter.js +1 -1
- package/dist/file-reader-raw-forgiving.adapter.js.map +1 -1
- package/dist/file-reader-text-forgiving.adapter.js +1 -1
- package/dist/file-reader-text-forgiving.adapter.js.map +1 -1
- package/dist/file-type-detector-text.strategy.js +1 -1
- package/dist/file-type-detector-text.strategy.js.map +1 -1
- package/dist/hash-file-metadata.adapter.d.ts +16 -0
- package/dist/hash-file-metadata.adapter.d.ts.map +1 -0
- package/dist/hash-file-metadata.adapter.js +18 -0
- package/dist/hash-file-metadata.adapter.js.map +1 -0
- package/dist/healthcheck.handler.d.ts +0 -2
- package/dist/healthcheck.handler.d.ts.map +1 -1
- package/dist/healthcheck.handler.js +0 -1
- package/dist/healthcheck.handler.js.map +1 -1
- package/dist/image-generator-web-view.adapter.d.ts +1 -0
- package/dist/image-generator-web-view.adapter.d.ts.map +1 -1
- package/dist/image-generator-web-view.adapter.js +3 -2
- package/dist/image-generator-web-view.adapter.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/job-retry-policy-composite.strategy.js +2 -1
- package/dist/job-retry-policy-composite.strategy.js.map +1 -1
- package/dist/pdf-generator-with-logger.adapter.js +1 -1
- package/dist/pdf-generator-with-logger.adapter.js.map +1 -1
- package/dist/prerequisite-verifier-sqlite-connection.adapter.d.ts +13 -0
- package/dist/prerequisite-verifier-sqlite-connection.adapter.d.ts.map +1 -0
- package/dist/prerequisite-verifier-sqlite-connection.adapter.js +20 -0
- package/dist/prerequisite-verifier-sqlite-connection.adapter.js.map +1 -0
- package/dist/projection-rebuild.service.d.ts +31 -0
- package/dist/projection-rebuild.service.d.ts.map +1 -0
- package/dist/projection-rebuild.service.js +53 -0
- package/dist/projection-rebuild.service.js.map +1 -0
- package/dist/runtime-stats-provider-noop.adapter.js +1 -1
- package/dist/runtime-stats-provider-noop.adapter.js.map +1 -1
- package/dist/runtime-stats-provider-system.adapter.d.ts.map +1 -1
- package/dist/runtime-stats-provider-system.adapter.js +1 -2
- package/dist/runtime-stats-provider-system.adapter.js.map +1 -1
- package/dist/runtime-stats-provider.port.d.ts +0 -2
- package/dist/runtime-stats-provider.port.d.ts.map +1 -1
- package/dist/shield-rate-limit-hono.strategy.d.ts.map +1 -1
- package/dist/shield-rate-limit-hono.strategy.js +4 -2
- package/dist/shield-rate-limit-hono.strategy.js.map +1 -1
- package/package.json +8 -8
- package/readme.md +5 -3
- package/src/event-log-reader-memory.adapter.ts +13 -0
- package/src/event-log-reader.port.ts +13 -0
- package/src/file-reader-raw-forgiving.adapter.ts +1 -1
- package/src/file-reader-text-forgiving.adapter.ts +1 -1
- package/src/file-type-detector-text.strategy.ts +1 -1
- package/src/hash-file-metadata.adapter.ts +27 -0
- package/src/healthcheck.handler.ts +0 -3
- package/src/image-generator-web-view.adapter.ts +6 -2
- package/src/index.ts +5 -3
- package/src/job-retry-policy-composite.strategy.ts +1 -1
- package/src/pdf-generator-with-logger.adapter.ts +1 -1
- package/src/prerequisite-verifier-sqlite-connection.adapter.ts +27 -0
- package/src/projection-rebuild.service.ts +81 -0
- package/src/runtime-stats-provider-noop.adapter.ts +1 -1
- package/src/runtime-stats-provider-system.adapter.ts +1 -2
- package/src/runtime-stats-provider.port.ts +1 -2
- package/src/shield-rate-limit-hono.strategy.ts +4 -2
- package/dist/checksum.service.d.ts +0 -5
- package/dist/checksum.service.d.ts.map +0 -1
- package/dist/checksum.service.js +0 -8
- package/dist/checksum.service.js.map +0 -1
- package/dist/clock-offset.adapter.d.ts +0 -13
- package/dist/clock-offset.adapter.d.ts.map +0 -1
- package/dist/clock-offset.adapter.js +0 -12
- package/dist/clock-offset.adapter.js.map +0 -1
- package/dist/event-loop-utilization.service.d.ts +0 -6
- package/dist/event-loop-utilization.service.d.ts.map +0 -1
- package/dist/event-loop-utilization.service.js +0 -15
- package/dist/event-loop-utilization.service.js.map +0 -1
- package/src/checksum.service.ts +0 -11
- package/src/clock-offset.adapter.ts +0 -15
- 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 }
|
|
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
|
|
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;
|
|
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()
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
16
|
-
|
|
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,
|
|
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.
|
|
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.
|
|
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.
|
|
32
|
-
"lefthook": "2.1
|
|
33
|
-
"lockfile-lint": "5.0
|
|
34
|
-
"nodemailer": "10.0
|
|
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.
|
|
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
|
|
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
|
-
|
|
13
|
-
|
|
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";
|
|
@@ -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
|
|
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 }
|
|
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()
|
|
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
|
|
9
|
+
eventLoop: { lag: EventLoopLagSnapshotType };
|
|
11
10
|
inFlight: tools.IntegerType;
|
|
12
11
|
};
|
|
13
12
|
|