@gaganref/confect-server 10.3.1-fork.41 → 10.3.1-fork.43

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 (53) hide show
  1. package/dist/ActionCall.d.ts.map +1 -1
  2. package/dist/ActionCall.js +5 -5
  3. package/dist/ActionCall.js.map +1 -1
  4. package/dist/ActionRunner.d.ts +1 -1
  5. package/dist/ActionRunner.d.ts.map +1 -1
  6. package/dist/ActionRunner.js +2 -2
  7. package/dist/ActionRunner.js.map +1 -1
  8. package/dist/Callback.js +1 -1
  9. package/dist/FunctionRegistryItem.d.ts +1 -0
  10. package/dist/FunctionRegistryItem.d.ts.map +1 -1
  11. package/dist/FunctionRegistryItem.js +1 -0
  12. package/dist/FunctionRegistryItem.js.map +1 -1
  13. package/dist/GroupImpl.js +1 -1
  14. package/dist/HttpRouter.js +1 -1
  15. package/dist/MutationRunner.d.ts +1 -1
  16. package/dist/MutationRunner.d.ts.map +1 -1
  17. package/dist/MutationRunner.js +2 -2
  18. package/dist/MutationRunner.js.map +1 -1
  19. package/dist/MutationTransactionContext.d.ts.map +1 -1
  20. package/dist/MutationTransactionContext.js +2 -1
  21. package/dist/MutationTransactionContext.js.map +1 -1
  22. package/dist/QueryStream.js +2 -2
  23. package/dist/QueryStreamKeyValues.js +1 -1
  24. package/dist/QueryStreamReadBudget.js +2 -2
  25. package/dist/RegisteredConvexFunction.d.ts +4 -2
  26. package/dist/RegisteredConvexFunction.d.ts.map +1 -1
  27. package/dist/RegisteredConvexFunction.js +10 -7
  28. package/dist/RegisteredConvexFunction.js.map +1 -1
  29. package/dist/RegisteredFunction.d.ts +17 -4
  30. package/dist/RegisteredFunction.d.ts.map +1 -1
  31. package/dist/RegisteredFunction.js +43 -19
  32. package/dist/RegisteredFunction.js.map +1 -1
  33. package/dist/RegisteredNodeFunction.d.ts.map +1 -1
  34. package/dist/RegisteredNodeFunction.js +3 -1
  35. package/dist/RegisteredNodeFunction.js.map +1 -1
  36. package/dist/Scheduler.d.ts.map +1 -1
  37. package/dist/Scheduler.js +9 -8
  38. package/dist/Scheduler.js.map +1 -1
  39. package/dist/internal/reservedArgument.d.ts +8 -0
  40. package/dist/internal/reservedArgument.d.ts.map +1 -0
  41. package/dist/internal/reservedArgument.js +30 -0
  42. package/dist/internal/reservedArgument.js.map +1 -0
  43. package/package.json +2 -2
  44. package/src/ActionCall.ts +4 -3
  45. package/src/ActionRunner.ts +3 -2
  46. package/src/FunctionRegistryItem.ts +4 -0
  47. package/src/MutationRunner.ts +3 -2
  48. package/src/MutationTransactionContext.ts +2 -1
  49. package/src/RegisteredConvexFunction.ts +19 -3
  50. package/src/RegisteredFunction.ts +71 -14
  51. package/src/RegisteredNodeFunction.ts +4 -0
  52. package/src/Scheduler.ts +13 -16
  53. package/src/internal/reservedArgument.ts +56 -0
@@ -1,4 +1,5 @@
1
- import * as Ref from "@confect/core/Ref";
1
+ import * as ReservedArgument from "./internal/reservedArgument.js";
2
+ import type * as Ref from "@confect/core/Ref";
2
3
  import { type GenericActionCtx } from "convex/server";
3
4
  import * as Effect from "effect/Effect";
4
5
  import * as Context from "effect/Context";
@@ -18,7 +19,7 @@ const make = (runAction: GenericActionCtx<any>["runAction"]) => ({
18
19
  Ref.Error<Action> | Schema.SchemaError
19
20
  > =>
20
21
  run(
21
- Ref.runWithCodec(
22
+ ReservedArgument.runWithCodec(
22
23
  action,
23
24
  (args[0] ?? {}) as Ref.Args<Action>,
24
25
  (functionReference, encodedArgs) =>
@@ -29,6 +29,7 @@ export interface ConfectFunctionRegistryItem {
29
29
  readonly [TypeId]: TypeId;
30
30
  readonly _tag: "Confect";
31
31
  readonly name: string;
32
+ readonly reservedArgument?: string;
32
33
  readonly functionVisibility: FunctionVisibility;
33
34
  readonly functionType: FunctionType;
34
35
  readonly args: Schema.Codec<any, any>;
@@ -64,6 +65,9 @@ export const make = ({
64
65
  const item = Object.assign(Object.create(FunctionRegistryItemProto), {
65
66
  _tag: "Confect" as const,
66
67
  name: functionSpec.name,
68
+ ...(functionSpec.reservedArgument === undefined
69
+ ? {}
70
+ : { reservedArgument: functionSpec.reservedArgument }),
67
71
  functionVisibility: functionSpec.functionVisibility,
68
72
  functionType: functionSpec.runtimeAndFunctionType.functionType,
69
73
  middlewareAttachments: [
@@ -1,4 +1,5 @@
1
- import * as Ref from "@confect/core/Ref";
1
+ import * as ReservedArgument from "./internal/reservedArgument.js";
2
+ import type * as Ref from "@confect/core/Ref";
2
3
  import type { GenericActionCtx } from "convex/server";
3
4
  import * as Context from "effect/Context";
4
5
  import * as Effect from "effect/Effect";
@@ -46,7 +47,7 @@ const make = (nativeRunMutation: GenericActionCtx<any>["runMutation"]) => {
46
47
  yield* MutationTransactionContext.MutationTransactionContext;
47
48
  return yield* controls.runMutation(mutation, actualArgs, options);
48
49
  }
49
- return yield* Ref.runWithCodec(
50
+ return yield* ReservedArgument.runWithCodec(
50
51
  mutation,
51
52
  actualArgs,
52
53
  (ref, encodedArgs) => nativeRunMutation(ref, encodedArgs),
@@ -1,3 +1,4 @@
1
+ import * as ReservedArgument from "./internal/reservedArgument.js";
1
2
  import * as Ref from "@confect/core/Ref";
2
3
  import type {
3
4
  AdvancedRunQueryOptions,
@@ -32,7 +33,7 @@ const make = (
32
33
  args: Ref.Args<Mutation>,
33
34
  options: MutationOptions,
34
35
  ) =>
35
- Ref.runWithCodec(mutation, args, (ref, encodedArgs) =>
36
+ ReservedArgument.runWithCodec(mutation, args, (ref, encodedArgs) =>
36
37
  ctx.runMutation(ref, encodedArgs, options),
37
38
  ),
38
39
  ),
@@ -86,6 +86,7 @@ export const prepare = (
86
86
  const definition = mutationFunction({
87
87
  databaseSchema,
88
88
  name: item.name,
89
+ reservedArgument: item.reservedArgument,
89
90
  observability,
90
91
  functionVisibility: item.functionVisibility,
91
92
  args: item.args,
@@ -103,6 +104,7 @@ export const prepare = (
103
104
  Match.when("action", () => {
104
105
  const definition = convexActionFunction(databaseSchema, {
105
106
  name: item.name,
107
+ reservedArgument: item.reservedArgument,
106
108
  observability,
107
109
  functionVisibility: item.functionVisibility,
108
110
  args: item.args,
@@ -324,9 +326,11 @@ const mutationFunction = <
324
326
  handler,
325
327
  resolvedMiddlewares,
326
328
  observability,
329
+ reservedArgument,
327
330
  }: {
328
331
  databaseSchema: DatabaseSchema_;
329
332
  name: string;
333
+ reservedArgument?: string | undefined;
330
334
  functionVisibility: FunctionVisibility;
331
335
  args: Schema.Codec<Args, ConvexArgs>;
332
336
  returns: Schema.Codec<Returns, ConvexReturns>;
@@ -337,7 +341,12 @@ const mutationFunction = <
337
341
  resolvedMiddlewares: ReadonlyArray<ResolvedMiddleware.ResolvedMiddleware>;
338
342
  observability?: Layer.Layer<never> | undefined;
339
343
  }) => ({
340
- args: compileArgsSchema(args, databaseSchema.target.scope),
344
+ args: compileArgsSchema(
345
+ args,
346
+ databaseSchema.target.scope,
347
+ reservedArgument,
348
+ name,
349
+ ),
341
350
  returns: compileReturnsSchema(returns, databaseSchema.target.scope),
342
351
  handler: (
343
352
  ctx: GenericMutationCtx<
@@ -347,7 +356,7 @@ const mutationFunction = <
347
356
  ): Promise<ConvexReturns> =>
348
357
  Effect.gen(function* () {
349
358
  const decodedArgs = yield* pipe(
350
- actualArgs,
359
+ RegisteredFunction.domainArgs(actualArgs, reservedArgument),
351
360
  Schema.decodeUnknownEffect(args),
352
361
  Effect.catchTag("SchemaError", Effect.die),
353
362
  );
@@ -372,7 +381,11 @@ const mutationFunction = <
372
381
  RegisteredFunction.combineErrorSchemas(error, resolvedMiddlewares),
373
382
  {
374
383
  scheduler: new EffectScheduler.MixedScheduler("sync"),
375
- invocation: Effect.promise(() => ctx.meta.getFunctionMetadata()),
384
+ invocation: RegisteredFunction.invocationMetadata(
385
+ ctx.meta,
386
+ actualArgs,
387
+ reservedArgument,
388
+ ),
376
389
  observability,
377
390
  },
378
391
  ),
@@ -397,8 +410,10 @@ const convexActionFunction = <
397
410
  handler,
398
411
  resolvedMiddlewares,
399
412
  observability,
413
+ reservedArgument,
400
414
  }: {
401
415
  name: string;
416
+ reservedArgument?: string | undefined;
402
417
  functionVisibility: FunctionVisibility;
403
418
  args: Schema.Codec<Args, ConvexArgs>;
404
419
  returns: Schema.Codec<Returns, ConvexReturns>;
@@ -424,6 +439,7 @@ const convexActionFunction = <
424
439
  handler,
425
440
  resolvedMiddlewares,
426
441
  observability,
442
+ reservedArgument,
427
443
  createLayer: (ctx) =>
428
444
  Layer.mergeAll(
429
445
  RegisteredFunction.actionLayer(schema, ctx),
@@ -1,3 +1,4 @@
1
+ export { Forward } from "./internal/reservedArgument.js";
1
2
  import * as ActionCallSpec from "@confect/core/ActionCall";
2
3
  import * as ActionCall from "./ActionCall.js";
3
4
  import type { FunctionSpec, RuntimeAndFunctionType } from "@confect/core";
@@ -12,6 +13,7 @@ import {
12
13
  type DefaultFunctionArgs,
13
14
  type FunctionVisibility,
14
15
  type FunctionMetadata,
16
+ type MutationMeta,
15
17
  type GenericActionCtx,
16
18
  type GenericDataModel,
17
19
  type StorageReader as ConvexStorageReader,
@@ -22,6 +24,9 @@ import {
22
24
  import type { Value } from "convex/values";
23
25
  import { ConvexError } from "convex/values";
24
26
  import { pipe } from "effect/Function";
27
+ import * as Config from "effect/Config";
28
+ import * as Option from "effect/Option";
29
+ import * as ConvexConfigProvider from "./ConvexConfigProvider.js";
25
30
  import * as Clock from "effect/Clock";
26
31
  import * as Cause from "effect/Cause";
27
32
  import * as Console from "effect/Console";
@@ -53,6 +58,40 @@ import * as ObservabilityRuntime from "./internal/observability.js";
53
58
  import * as VectorSearch from "./VectorSearch.js";
54
59
  import type * as Handler from "./Handler.js";
55
60
 
61
+ export interface ReceivedValue {
62
+ readonly value: unknown;
63
+ readonly requestId: string;
64
+ readonly deployment: string | undefined;
65
+ }
66
+
67
+ export const Received = Context.Reference<ReceivedValue | undefined>(
68
+ "@confect/server/RegisteredFunction/Received",
69
+ { defaultValue: () => undefined },
70
+ );
71
+
72
+ export const invocationMetadata = (
73
+ meta: Pick<MutationMeta, "getFunctionMetadata" | "getRequestMetadata">,
74
+ args: DefaultFunctionArgs,
75
+ reservedArgument?: string,
76
+ ): Effect.Effect<FunctionMetadata & { readonly received?: ReceivedValue }> =>
77
+ Effect.gen(function* () {
78
+ const metadata = yield* Effect.promise(() => meta.getFunctionMetadata());
79
+ if (reservedArgument === undefined) return metadata;
80
+ const { requestId } = yield* Effect.promise(() =>
81
+ meta.getRequestMetadata(),
82
+ );
83
+ const deployment = yield* Config.String("CONVEX_CLOUD_URL").pipe(
84
+ Config.option,
85
+ Effect.map(Option.getOrUndefined),
86
+ Effect.provide(ConvexConfigProvider.layer),
87
+ Effect.orDie,
88
+ );
89
+ return {
90
+ ...metadata,
91
+ received: { value: args[reservedArgument], requestId, deployment },
92
+ };
93
+ });
94
+
56
95
  export const Observability = Context.Reference<Layer.Layer<never> | undefined>(
57
96
  "@confect/server/Observability",
58
97
  { defaultValue: () => undefined },
@@ -226,7 +265,11 @@ export const runHandlerPromise =
226
265
  runOptions?: {
227
266
  readonly scheduler?: EffectScheduler.Scheduler | undefined;
228
267
  readonly clock?: Clock.Clock | undefined;
229
- readonly invocation?: Effect.Effect<FunctionMetadata> | undefined;
268
+ readonly invocation?:
269
+ | Effect.Effect<
270
+ FunctionMetadata & { readonly received?: ReceivedValue }
271
+ >
272
+ | undefined;
230
273
  readonly observability?: Layer.Layer<never> | undefined;
231
274
  },
232
275
  ) =>
@@ -269,16 +312,18 @@ export const runHandlerPromise =
269
312
  const exit = yield* Effect.exit(
270
313
  observability === undefined || invocation === undefined
271
314
  ? effect
272
- : Effect.flatMap(invocation, ({ name, type, componentPath }) =>
273
- Effect.useSpan(
274
- name,
275
- {
276
- root: true,
277
- attributes: { kind: type, componentPath },
278
- },
279
- (span) =>
280
- Effect.provideService(observed, Tracer.ParentSpan, span),
281
- ),
315
+ : Effect.flatMap(
316
+ invocation,
317
+ ({ name, type, componentPath, received }) =>
318
+ Effect.useSpan(
319
+ name,
320
+ {
321
+ root: true,
322
+ attributes: { kind: type, componentPath },
323
+ },
324
+ (span) =>
325
+ Effect.provideService(observed, Tracer.ParentSpan, span),
326
+ ).pipe(Effect.provideService(Received, received)),
282
327
  ),
283
328
  );
284
329
  if (Exit.isSuccess(exit)) {
@@ -347,6 +392,16 @@ export const runHandlerPromise =
347
392
  );
348
393
  };
349
394
 
395
+ export const domainArgs = (
396
+ args: DefaultFunctionArgs,
397
+ reservedArgument?: string,
398
+ ): DefaultFunctionArgs =>
399
+ reservedArgument === undefined
400
+ ? args
401
+ : Object.fromEntries(
402
+ Object.entries(args).filter(([key]) => key !== reservedArgument),
403
+ );
404
+
350
405
  export const actionFunctionBase = <
351
406
  Schema extends DatabaseSchema.AnyWithProps,
352
407
  Args,
@@ -366,8 +421,10 @@ export const actionFunctionBase = <
366
421
  createLayer,
367
422
  scope = IdScope.app,
368
423
  observability,
424
+ reservedArgument,
369
425
  }: {
370
426
  name: string;
427
+ reservedArgument?: string | undefined;
371
428
  functionVisibility: FunctionVisibility;
372
429
  args: Schema.Codec<Args, ConvexArgs>;
373
430
  returns: Schema.Codec<Returns, ConvexReturns>;
@@ -380,7 +437,7 @@ export const actionFunctionBase = <
380
437
  scope?: IdScope.IdScope;
381
438
  observability?: Layer.Layer<never> | undefined;
382
439
  }) => ({
383
- args: compileArgsSchema(args, scope),
440
+ args: compileArgsSchema(args, scope, reservedArgument, name),
384
441
  returns: compileReturnsSchema(returns, scope),
385
442
  handler: (
386
443
  ctx: GenericActionCtx<DataModel.ToConvex<DataModel.FromSchema<Schema>>>,
@@ -388,7 +445,7 @@ export const actionFunctionBase = <
388
445
  ): Promise<ConvexReturns> =>
389
446
  Effect.gen(function* () {
390
447
  const decodedArgs = yield* pipe(
391
- actualArgs,
448
+ domainArgs(actualArgs, reservedArgument),
392
449
  Schema.decodeUnknownEffect(args),
393
450
  Effect.catchTag("SchemaError", Effect.die),
394
451
  );
@@ -417,7 +474,7 @@ export const actionFunctionBase = <
417
474
  );
418
475
  }).pipe(
419
476
  runHandlerPromise(combineErrorSchemas(error, resolvedMiddlewares), {
420
- invocation: Effect.promise(() => ctx.meta.getFunctionMetadata()),
477
+ invocation: invocationMetadata(ctx.meta, actualArgs, reservedArgument),
421
478
  observability,
422
479
  }),
423
480
  ),
@@ -61,6 +61,7 @@ export const make = (
61
61
  return genericFunction(
62
62
  nodeActionFunction(databaseSchema, {
63
63
  name: item.name,
64
+ reservedArgument: item.reservedArgument,
64
65
  observability,
65
66
  functionVisibility: item.functionVisibility,
66
67
  args: item.args,
@@ -90,8 +91,10 @@ const nodeActionFunction = <
90
91
  handler,
91
92
  resolvedMiddlewares,
92
93
  observability,
94
+ reservedArgument,
93
95
  }: {
94
96
  name: string;
97
+ reservedArgument?: string | undefined;
95
98
  functionVisibility: FunctionVisibility;
96
99
  args: Schema.Codec<Args, ConvexArgs>;
97
100
  returns: Schema.Codec<Returns, ConvexReturns>;
@@ -118,6 +121,7 @@ const nodeActionFunction = <
118
121
  handler,
119
122
  resolvedMiddlewares,
120
123
  observability,
124
+ reservedArgument,
121
125
  createLayer: (ctx) =>
122
126
  Layer.mergeAll(
123
127
  RegisteredFunction.actionLayer(databaseSchema, ctx),
package/src/Scheduler.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as ReservedArgument from "./internal/reservedArgument.js";
1
2
  import type * as IdScope from "@confect/core/IdScope";
2
3
  import { Ref } from "@confect/core";
3
4
  import type { GenericId } from "@confect/core/GenericId";
@@ -12,38 +13,34 @@ import * as Layer from "effect/Layer";
12
13
  const make = (scheduler: ConvexScheduler) => ({
13
14
  cancel: (id: ConvexGenericId<"_scheduled_functions">) =>
14
15
  Effect.promise(() => scheduler.cancel(id)),
15
- runAfter: <Ref_ extends Ref.AnyMutation | Ref.AnyAction>(
16
- delay: Duration.Duration,
17
- ref: Ref_,
18
- ...args: Ref.OptionalArgs<Ref_>
19
- ) => {
16
+ runAfter: Effect.fn("Scheduler.runAfter")(function* <
17
+ Ref_ extends Ref.AnyMutation | Ref.AnyAction,
18
+ >(delay: Duration.Duration, ref: Ref_, ...args: Ref.OptionalArgs<Ref_>) {
20
19
  const delayMs = Duration.toMillis(delay);
21
20
  const functionReference = Ref.getFunctionReference(ref);
22
- const encodedArgs = Ref.encodeArgsSync(
21
+ const encodedArgs = yield* ReservedArgument.encodeArgs(
23
22
  ref,
24
23
  (args[0] ?? {}) as Ref.Args<Ref_>,
25
24
  );
26
25
 
27
- return Effect.promise(() =>
26
+ return yield* Effect.promise(() =>
28
27
  scheduler.runAfter(delayMs, functionReference, encodedArgs),
29
28
  );
30
- },
31
- runAt: <Ref_ extends Ref.AnyMutation | Ref.AnyAction>(
32
- dateTime: DateTime.DateTime,
33
- ref: Ref_,
34
- ...args: Ref.OptionalArgs<Ref_>
35
- ) => {
29
+ }),
30
+ runAt: Effect.fn("Scheduler.runAt")(function* <
31
+ Ref_ extends Ref.AnyMutation | Ref.AnyAction,
32
+ >(dateTime: DateTime.DateTime, ref: Ref_, ...args: Ref.OptionalArgs<Ref_>) {
36
33
  const timestamp = DateTime.toEpochMillis(dateTime);
37
34
  const functionReference = Ref.getFunctionReference(ref);
38
- const encodedArgs = Ref.encodeArgsSync(
35
+ const encodedArgs = yield* ReservedArgument.encodeArgs(
39
36
  ref,
40
37
  (args[0] ?? {}) as Ref.Args<Ref_>,
41
38
  );
42
39
 
43
- return Effect.promise(() =>
40
+ return yield* Effect.promise(() =>
44
41
  scheduler.runAt(timestamp, functionReference, encodedArgs),
45
42
  );
46
- },
43
+ }),
47
44
  });
48
45
 
49
46
  export const Scheduler = Context.Service<ReturnType<typeof make>>(
@@ -0,0 +1,56 @@
1
+ import { convexToJson, type Value } from "convex/values";
2
+ import * as Ref from "@confect/core/Ref";
3
+ import * as Context from "effect/Context";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Tracer from "effect/Tracer";
6
+
7
+ export const Forward = Context.Reference<
8
+ ((span: Tracer.Span) => unknown) | undefined
9
+ >("@confect/server/RegisteredFunction/Forward", {
10
+ defaultValue: () => undefined,
11
+ });
12
+
13
+ const inject = (
14
+ ref: Ref.Any,
15
+ encoded: unknown,
16
+ context: Context.Context<never>,
17
+ ): unknown => {
18
+ if (ref.reservedArgument === undefined || ref.functionType === "query")
19
+ return encoded;
20
+ const forward = Context.get(context, Forward);
21
+ const span = Context.getOrUndefined(context, Tracer.ParentSpan);
22
+ if (forward === undefined || span?._tag !== "Span") return encoded;
23
+ try {
24
+ const value = forward(span);
25
+ if (value === undefined) return encoded;
26
+ convexToJson(value as Value);
27
+ return {
28
+ ...(encoded as Record<string, unknown>),
29
+ [ref.reservedArgument]: value,
30
+ };
31
+ } catch {
32
+ return encoded;
33
+ }
34
+ };
35
+
36
+ export const runWithCodec = <Ref_ extends Ref.Any>(
37
+ ref: Ref_,
38
+ args: Ref.Args<Ref_>,
39
+ call: (
40
+ native: Ref.FunctionReference<Ref_>,
41
+ encoded: unknown,
42
+ ) => PromiseLike<unknown>,
43
+ ) =>
44
+ Effect.withFiber((fiber) =>
45
+ Ref.runWithCodec(ref, args, (native, encoded) =>
46
+ call(native, inject(ref, encoded, fiber.context)),
47
+ ),
48
+ );
49
+
50
+ export const encodeArgs = <Ref_ extends Ref.Any>(
51
+ ref: Ref_,
52
+ args: Ref.Args<Ref_>,
53
+ ) =>
54
+ Effect.withFiberSucceed((fiber) =>
55
+ inject(ref, Ref.encodeArgsSync(ref, args), fiber.context),
56
+ );