@beignet/core 0.0.32 → 0.0.34

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 (139) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +409 -34
  3. package/dist/application/index.d.ts.map +1 -1
  4. package/dist/application/index.js +63 -47
  5. package/dist/application/index.js.map +1 -1
  6. package/dist/contracts/contract-builder.d.ts +0 -4
  7. package/dist/contracts/contract-builder.d.ts.map +1 -1
  8. package/dist/contracts/contract-builder.js +0 -6
  9. package/dist/contracts/contract-builder.js.map +1 -1
  10. package/dist/events/index.d.ts +6 -0
  11. package/dist/events/index.d.ts.map +1 -1
  12. package/dist/events/index.js +20 -10
  13. package/dist/events/index.js.map +1 -1
  14. package/dist/flags/index.d.ts +0 -4
  15. package/dist/flags/index.d.ts.map +1 -1
  16. package/dist/flags/index.js +0 -4
  17. package/dist/flags/index.js.map +1 -1
  18. package/dist/jobs/index.d.ts +415 -4
  19. package/dist/jobs/index.d.ts.map +1 -1
  20. package/dist/jobs/index.js +392 -3
  21. package/dist/jobs/index.js.map +1 -1
  22. package/dist/notifications/index.d.ts +194 -10
  23. package/dist/notifications/index.d.ts.map +1 -1
  24. package/dist/notifications/index.js +397 -59
  25. package/dist/notifications/index.js.map +1 -1
  26. package/dist/outbox/index.d.ts +150 -1
  27. package/dist/outbox/index.d.ts.map +1 -1
  28. package/dist/outbox/index.js +170 -1
  29. package/dist/outbox/index.js.map +1 -1
  30. package/dist/ports/events.d.ts +2 -2
  31. package/dist/ports/index.d.ts +7 -2
  32. package/dist/ports/index.d.ts.map +1 -1
  33. package/dist/ports/index.js +2 -1
  34. package/dist/ports/index.js.map +1 -1
  35. package/dist/providers/instrumentation.d.ts +4 -0
  36. package/dist/providers/instrumentation.d.ts.map +1 -1
  37. package/dist/providers/instrumentation.js.map +1 -1
  38. package/dist/providers/provider.d.ts +1 -1
  39. package/dist/schedules/index.d.ts +8 -7
  40. package/dist/schedules/index.d.ts.map +1 -1
  41. package/dist/schedules/index.js +47 -16
  42. package/dist/schedules/index.js.map +1 -1
  43. package/dist/server/hooks/index.d.ts +1 -0
  44. package/dist/server/hooks/index.d.ts.map +1 -1
  45. package/dist/server/hooks/index.js +1 -0
  46. package/dist/server/hooks/index.js.map +1 -1
  47. package/dist/server/hooks/rate-limit.d.ts +26 -13
  48. package/dist/server/hooks/rate-limit.d.ts.map +1 -1
  49. package/dist/server/hooks/rate-limit.js +28 -34
  50. package/dist/server/hooks/rate-limit.js.map +1 -1
  51. package/dist/server/hooks/security.d.ts +179 -0
  52. package/dist/server/hooks/security.d.ts.map +1 -0
  53. package/dist/server/hooks/security.js +225 -0
  54. package/dist/server/hooks/security.js.map +1 -0
  55. package/dist/server/index.d.ts +8 -0
  56. package/dist/server/index.d.ts.map +1 -1
  57. package/dist/server/index.js +8 -0
  58. package/dist/server/index.js.map +1 -1
  59. package/dist/server/instrumentation.d.ts.map +1 -1
  60. package/dist/server/instrumentation.js +22 -6
  61. package/dist/server/instrumentation.js.map +1 -1
  62. package/dist/server/request-context.d.ts +4 -0
  63. package/dist/server/request-context.d.ts.map +1 -1
  64. package/dist/server/request-context.js +3 -0
  65. package/dist/server/request-context.js.map +1 -1
  66. package/dist/server/runtime-integrity.d.ts +84 -0
  67. package/dist/server/runtime-integrity.d.ts.map +1 -0
  68. package/dist/server/runtime-integrity.js +160 -0
  69. package/dist/server/runtime-integrity.js.map +1 -0
  70. package/dist/server/server.d.ts +10 -10
  71. package/dist/server/server.d.ts.map +1 -1
  72. package/dist/server/server.js +75 -11
  73. package/dist/server/server.js.map +1 -1
  74. package/dist/server/trusted-proxy.d.ts +77 -0
  75. package/dist/server/trusted-proxy.d.ts.map +1 -0
  76. package/dist/server/trusted-proxy.js +129 -0
  77. package/dist/server/trusted-proxy.js.map +1 -0
  78. package/dist/tasks/index.d.ts +6 -7
  79. package/dist/tasks/index.d.ts.map +1 -1
  80. package/dist/tasks/index.js +22 -5
  81. package/dist/tasks/index.js.map +1 -1
  82. package/dist/tenancy/index.d.ts +41 -0
  83. package/dist/tenancy/index.d.ts.map +1 -0
  84. package/dist/tenancy/index.js +34 -0
  85. package/dist/tenancy/index.js.map +1 -0
  86. package/dist/testing/index.d.ts +1 -1
  87. package/dist/testing/index.d.ts.map +1 -1
  88. package/dist/testing/index.js +1 -0
  89. package/dist/testing/index.js.map +1 -1
  90. package/dist/tracing/execution.d.ts +14 -0
  91. package/dist/tracing/execution.d.ts.map +1 -0
  92. package/dist/tracing/execution.js +17 -0
  93. package/dist/tracing/execution.js.map +1 -0
  94. package/dist/tracing/index.d.ts +49 -0
  95. package/dist/tracing/index.d.ts.map +1 -1
  96. package/dist/tracing/index.js +59 -0
  97. package/dist/tracing/index.js.map +1 -1
  98. package/dist/uploads/client.d.ts.map +1 -1
  99. package/dist/uploads/client.js +44 -6
  100. package/dist/uploads/client.js.map +1 -1
  101. package/dist/uploads/index.d.ts +71 -0
  102. package/dist/uploads/index.d.ts.map +1 -1
  103. package/dist/uploads/index.js +344 -15
  104. package/dist/uploads/index.js.map +1 -1
  105. package/dist/webhooks/index.d.ts +55 -4
  106. package/dist/webhooks/index.d.ts.map +1 -1
  107. package/dist/webhooks/index.js +106 -2
  108. package/dist/webhooks/index.js.map +1 -1
  109. package/package.json +5 -5
  110. package/skills/app-architecture/SKILL.md +31 -2
  111. package/src/application/index.ts +88 -56
  112. package/src/contracts/contract-builder.ts +0 -7
  113. package/src/events/index.ts +27 -14
  114. package/src/flags/index.ts +0 -5
  115. package/src/jobs/index.ts +895 -7
  116. package/src/notifications/index.ts +678 -70
  117. package/src/outbox/index.ts +358 -2
  118. package/src/ports/events.ts +2 -2
  119. package/src/ports/index.ts +17 -1
  120. package/src/providers/instrumentation.ts +4 -0
  121. package/src/providers/provider.ts +1 -1
  122. package/src/schedules/index.ts +60 -26
  123. package/src/server/hooks/index.ts +10 -0
  124. package/src/server/hooks/rate-limit.ts +52 -46
  125. package/src/server/hooks/security.ts +503 -0
  126. package/src/server/index.ts +8 -0
  127. package/src/server/instrumentation.ts +25 -5
  128. package/src/server/request-context.ts +7 -0
  129. package/src/server/runtime-integrity.ts +322 -0
  130. package/src/server/server.ts +88 -35
  131. package/src/server/trusted-proxy.ts +249 -0
  132. package/src/tasks/index.ts +29 -12
  133. package/src/tenancy/index.ts +55 -0
  134. package/src/testing/index.ts +2 -0
  135. package/src/tracing/execution.ts +37 -0
  136. package/src/tracing/index.ts +137 -0
  137. package/src/uploads/client.ts +65 -6
  138. package/src/uploads/index.ts +539 -14
  139. package/src/webhooks/index.ts +238 -9
@@ -5,6 +5,8 @@ import {
5
5
  } from "../providers/instrumentation.js";
6
6
  import {
7
7
  createChildTraceContext,
8
+ resolveTracingPort,
9
+ runWithTracing,
8
10
  type TraceContextInput,
9
11
  } from "../tracing/index.js";
10
12
 
@@ -482,6 +484,7 @@ function getInstrumentationTrace(ctx: unknown): TraceContextInput | undefined {
482
484
  spanId: context.spanId,
483
485
  parentSpanId: context.parentSpanId,
484
486
  traceparent: context.traceparent,
487
+ tracestate: context.tracestate,
485
488
  };
486
489
  }
487
490
 
@@ -517,9 +520,9 @@ function startUseCaseRunInstrumentation(args: {
517
520
  if (!useCasesEnabled && !errorsEnabled) return undefined;
518
521
 
519
522
  const requestId = getInstrumentationRequestId(args.ctx);
520
- const trace = createChildTraceContext(
521
- getInstrumentationTrace(args.ctx) ?? {},
522
- );
523
+ const trace =
524
+ resolveTracingPort(ports)?.current() ??
525
+ createChildTraceContext(getInstrumentationTrace(args.ctx) ?? {});
523
526
 
524
527
  const record = (event: ProviderInstrumentationEventInput) => {
525
528
  try {
@@ -542,6 +545,7 @@ function startUseCaseRunInstrumentation(args: {
542
545
  spanId: trace.spanId,
543
546
  parentSpanId: trace.parentSpanId,
544
547
  traceparent: trace.traceparent,
548
+ tracestate: trace.tracestate,
545
549
  name: args.name,
546
550
  kind: args.kind,
547
551
  phase,
@@ -558,6 +562,7 @@ function startUseCaseRunInstrumentation(args: {
558
562
  spanId: trace.spanId,
559
563
  parentSpanId: trace.parentSpanId,
560
564
  traceparent: trace.traceparent,
565
+ tracestate: trace.tracestate,
561
566
  message: getRunErrorMessage(error),
562
567
  stack: error instanceof Error ? error.stack : undefined,
563
568
  useCaseName: args.name,
@@ -725,61 +730,88 @@ class UseCaseBuilder<
725
730
  : never,
726
731
  parseInput: boolean,
727
732
  ) => {
728
- const startedAt = Date.now();
729
- const instrumentation = instrumented
730
- ? startUseCaseRunInstrumentation({
731
- ctx: args.ctx,
733
+ const traceAttributes = {
734
+ "beignet.use_case.name": useCaseName,
735
+ "beignet.use_case.kind": useCaseKind,
736
+ } as const;
737
+
738
+ return await runWithTracing(
739
+ args.ctx,
740
+ {
741
+ name: `beignet.use_case ${useCaseName}`,
742
+ type: "useCase",
743
+ kind: "internal",
744
+ attributes: traceAttributes,
745
+ metricAttributes: traceAttributes,
746
+ },
747
+ async () => {
748
+ const startedAt = Date.now();
749
+ const instrumentation = instrumented
750
+ ? startUseCaseRunInstrumentation({
751
+ ctx: args.ctx,
752
+ name: useCaseName,
753
+ kind: useCaseKind,
754
+ })
755
+ : undefined;
756
+ onRun?.({
732
757
  name: useCaseName,
733
758
  kind: useCaseKind,
734
- })
735
- : undefined;
736
- onRun?.({
737
- name: useCaseName,
738
- kind: useCaseKind,
739
- phase: "start",
740
- ctx: args.ctx,
741
- });
742
-
743
- try {
744
- const parsedInput =
745
- parseInput && validation.input
746
- ? await parseSchema(inputSchema, args.input, useCaseName, "input")
747
- : (args.input as SchemaOutput<InputSchema>);
748
-
749
- const rawResult = await fn({
750
- ctx: args.ctx,
751
- input: parsedInput,
752
- events: eventHelpers,
753
- });
754
-
755
- const result = validation.output
756
- ? await parseSchema(outputSchema, rawResult, useCaseName, "output")
757
- : (rawResult as SchemaOutput<OutputSchema>);
758
-
759
- const durationMs = Date.now() - startedAt;
760
- instrumentation?.end(durationMs);
761
- onRun?.({
762
- name: useCaseName,
763
- kind: useCaseKind,
764
- phase: "end",
765
- durationMs,
766
- ctx: args.ctx,
767
- });
768
-
769
- return result;
770
- } catch (err) {
771
- const durationMs = Date.now() - startedAt;
772
- instrumentation?.error(durationMs, err);
773
- onRun?.({
774
- name: useCaseName,
775
- kind: useCaseKind,
776
- phase: "error",
777
- durationMs,
778
- error: err,
779
- ctx: args.ctx,
780
- });
781
- throw err;
782
- }
759
+ phase: "start",
760
+ ctx: args.ctx,
761
+ });
762
+
763
+ try {
764
+ const parsedInput =
765
+ parseInput && validation.input
766
+ ? await parseSchema(
767
+ inputSchema,
768
+ args.input,
769
+ useCaseName,
770
+ "input",
771
+ )
772
+ : (args.input as SchemaOutput<InputSchema>);
773
+
774
+ const rawResult = await fn({
775
+ ctx: args.ctx,
776
+ input: parsedInput,
777
+ events: eventHelpers,
778
+ });
779
+
780
+ const result = validation.output
781
+ ? await parseSchema(
782
+ outputSchema,
783
+ rawResult,
784
+ useCaseName,
785
+ "output",
786
+ )
787
+ : (rawResult as SchemaOutput<OutputSchema>);
788
+
789
+ const durationMs = Date.now() - startedAt;
790
+ instrumentation?.end(durationMs);
791
+ onRun?.({
792
+ name: useCaseName,
793
+ kind: useCaseKind,
794
+ phase: "end",
795
+ durationMs,
796
+ ctx: args.ctx,
797
+ });
798
+
799
+ return result;
800
+ } catch (err) {
801
+ const durationMs = Date.now() - startedAt;
802
+ instrumentation?.error(durationMs, err);
803
+ onRun?.({
804
+ name: useCaseName,
805
+ kind: useCaseKind,
806
+ phase: "error",
807
+ durationMs,
808
+ error: err,
809
+ ctx: args.ctx,
810
+ });
811
+ throw err;
812
+ }
813
+ },
814
+ );
783
815
  };
784
816
 
785
817
  type RunArgs = Parameters<typeof execute>[0];
@@ -111,13 +111,6 @@ export class ContractBuilder<
111
111
  /**
112
112
  * URL path template for this contract.
113
113
  */
114
- get pathTemplate(): TPath {
115
- return this._path;
116
- }
117
-
118
- /**
119
- * URL path template alias.
120
- */
121
114
  get path(): TPath {
122
115
  return this._path;
123
116
  }
@@ -1,4 +1,6 @@
1
1
  import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ import { runWithResolvedTracingContext } from "../tracing/execution.js";
3
+ import type { TracingPort } from "../tracing/index.js";
2
4
 
3
5
  /**
4
6
  * Any Standard Schema compatible validator.
@@ -160,6 +162,11 @@ export interface RegisterListenersOptions<Ctx> {
160
162
  * Static listener context or factory evaluated for each delivered event.
161
163
  */
162
164
  ctx?: Ctx | (() => MaybePromise<Ctx>);
165
+ /**
166
+ * Runtime tracing port used to start the listener span before a lazy context
167
+ * factory runs.
168
+ */
169
+ tracing?: TracingPort;
163
170
  /**
164
171
  * Called when a listener fails. When omitted, listener errors are rethrown to
165
172
  * the event bus subscription callback.
@@ -243,16 +250,6 @@ async function parsePayload<Schema extends StandardSchemaV1>(
243
250
  throw new Error("Invalid Standard Schema result: missing value");
244
251
  }
245
252
 
246
- async function resolveCtx<Ctx>(
247
- ctx: Ctx | (() => MaybePromise<Ctx>) | undefined,
248
- ): Promise<Ctx> {
249
- if (typeof ctx === "function") {
250
- return (ctx as () => MaybePromise<Ctx>)();
251
- }
252
-
253
- return ctx as Ctx;
254
- }
255
-
256
253
  /**
257
254
  * Define a typed event.
258
255
  *
@@ -326,10 +323,26 @@ export function registerListeners<Ctx>(
326
323
  eventBus.subscribe(listener.event, async (rawPayload) => {
327
324
  try {
328
325
  const payload = await parseEventPayload(listener.event, rawPayload);
329
- await listener.handle({
330
- event: listener.event,
331
- payload,
332
- ctx: await resolveCtx(options.ctx),
326
+ const traceAttributes = {
327
+ "beignet.listener.name": listener.name,
328
+ "beignet.event.name": listener.event.name,
329
+ } as const;
330
+ await runWithResolvedTracingContext({
331
+ tracing: options.tracing,
332
+ ctx: options.ctx as Ctx | (() => MaybePromise<Ctx>),
333
+ operation: {
334
+ name: `beignet.listener ${listener.name}`,
335
+ type: "listener",
336
+ kind: "consumer",
337
+ attributes: traceAttributes,
338
+ metricAttributes: traceAttributes,
339
+ },
340
+ run: (ctx) =>
341
+ listener.handle({
342
+ event: listener.event,
343
+ payload,
344
+ ctx,
345
+ }),
333
346
  });
334
347
  } catch (error) {
335
348
  options.onError?.(error, listener);
@@ -406,11 +406,6 @@ export function defineFlags<const TRegistry extends FlagRegistry>(
406
406
  return registry;
407
407
  }
408
408
 
409
- /**
410
- * Alias for apps that prefer to name the collection explicitly.
411
- */
412
- export const defineFlagRegistry = defineFlags;
413
-
414
409
  /**
415
410
  * Evaluate a flag through any `FlagsPort`.
416
411
  */