@restatedev/restate-sdk-gen 1.14.2 → 1.14.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/index.js CHANGED
@@ -1,4 +1,8 @@
1
+ import { t as __export } from "./chunk-Bp6m_JJh.js";
1
2
  import * as restate from "@restatedev/restate-sdk";
3
+ import { Opts, SendOpts } from "@restatedev/restate-sdk";
4
+ import { Opts as Opts$1, SendOpts as SendOpts$1, connect } from "@restatedev/restate-sdk-clients";
5
+ import { serde } from "@restatedev/restate-sdk-core";
2
6
 
3
7
  //#region src/current.ts
4
8
  let CURRENT = null;
@@ -27,6 +31,24 @@ function getCurrent() {
27
31
  return CURRENT;
28
32
  }
29
33
 
34
+ //#endregion
35
+ //#region src/invocation-reference.ts
36
+ var InvocationReferenceImpl = class {
37
+ constructor(id, _outputSerde) {
38
+ this.id = id;
39
+ this._outputSerde = _outputSerde;
40
+ }
41
+ attach(serde$1) {
42
+ return getCurrent().attach(this.id, serde$1 ?? this._outputSerde);
43
+ }
44
+ signal(name, serde$1) {
45
+ return getCurrent().invocationSignal(this.id, name, serde$1);
46
+ }
47
+ cancel() {
48
+ getCurrent().cancel(this.id);
49
+ }
50
+ };
51
+
30
52
  //#endregion
31
53
  //#region src/free.ts
32
54
  /**
@@ -38,6 +60,15 @@ function getCurrent() {
38
60
  function currentOps() {
39
61
  return getCurrent();
40
62
  }
63
+ const rand = () => currentOps().rand;
64
+ const date = () => currentOps().date;
65
+ const logger = () => currentOps().console;
66
+ /**
67
+ * Returns the current invocation's request metadata plus the optional
68
+ * virtual-object / workflow key. The `key` field is only present when
69
+ * the handler belongs to an object or workflow.
70
+ */
71
+ const handlerRequest = () => currentOps().handlerRequest();
41
72
  /**
42
73
  * Run a side-effecting closure as a journal entry. See
43
74
  * `RestateOperations.run` for full semantics.
@@ -48,24 +79,31 @@ function currentOps() {
48
79
  */
49
80
  const run = (action, opts) => currentOps().run(action, opts);
50
81
  const sleep = (duration, name) => currentOps().sleep(duration, name);
51
- const awakeable = (serde) => currentOps().awakeable(serde);
52
- const resolveAwakeable = (id, payload, serde) => currentOps().resolveAwakeable(id, payload, serde);
82
+ const awakeable = (serde$1) => currentOps().awakeable(serde$1);
83
+ const resolveAwakeable = (id, payload, serde$1) => currentOps().resolveAwakeable(id, payload, serde$1);
53
84
  const rejectAwakeable = (id, reason) => currentOps().rejectAwakeable(id, reason);
54
- const signal = (name, serde) => currentOps().signal(name, serde);
55
- const attach = (invocationId, serde) => currentOps().attach(invocationId, serde);
56
- const serviceClient = (api) => currentOps().serviceClient(api);
57
- const objectClient = (api, key) => currentOps().objectClient(api, key);
58
- const workflowClient = (api, key) => currentOps().workflowClient(api, key);
59
- const serviceSendClient = (api) => currentOps().serviceSendClient(api);
60
- const objectSendClient = (api, key) => currentOps().objectSendClient(api, key);
61
- const workflowSendClient = (api, key) => currentOps().workflowSendClient(api, key);
62
- const genericCall = (call) => currentOps().genericCall(call);
63
- const genericSend = (call) => currentOps().genericSend(call);
85
+ const signal = (name, serde$1) => currentOps().signal(name, serde$1);
86
+ const attach = (invocationId, serde$1) => currentOps().attach(invocationId, serde$1);
87
+ function client(def, key) {
88
+ return currentOps().client(def, key);
89
+ }
90
+ function sendClient(def, key) {
91
+ return currentOps().sendClient(def, key);
92
+ }
93
+ const call = (c) => currentOps().call(c);
94
+ const send = (c, outputSerde) => currentOps().send(c, outputSerde);
95
+ /**
96
+ * Create an InvocationReference from a known invocation ID (e.g. retrieved from state).
97
+ * `attach()` and `cancel()` on the result use the current fiber slot like all free functions.
98
+ */
99
+ function invocation(id, opts) {
100
+ return new InvocationReferenceImpl(id, opts?.outputSerde);
101
+ }
64
102
  const cancel = (invocationId) => currentOps().cancel(invocationId);
65
103
  const channel = () => currentOps().channel();
66
104
  const state = () => currentOps().state();
67
105
  const sharedState = () => currentOps().sharedState();
68
- const workflowPromise = (name, serde) => currentOps().workflowPromise(name, serde);
106
+ const workflowPromise = (name, serde$1) => currentOps().workflowPromise(name, serde$1);
69
107
  /**
70
108
  * Wait for every future to settle; return their values in input order.
71
109
  * Heterogeneous-tuple typing — `all([fA, fB])` where `fA: Future<A>`
@@ -91,6 +129,12 @@ const any = (futures) => currentOps().any(futures);
91
129
  * Mirrors `Promise.allSettled`.
92
130
  */
93
131
  const allSettled = (futures) => currentOps().allSettled(futures);
132
+ /**
133
+ * Register `op` as a fresh routine and return a `Future<T>` for its
134
+ * eventual outcome. Eager — the child is already in flight by the time
135
+ * `spawn` returns. See `RestateOperations.spawn` for full semantics.
136
+ */
137
+ const spawn = (op) => currentOps().spawn(op);
94
138
 
95
139
  //#endregion
96
140
  //#region src/operation.ts
@@ -119,12 +163,6 @@ function awaitRace(futures) {
119
163
  function gen(body) {
120
164
  return { [Symbol.iterator]: body };
121
165
  }
122
- function spawn(op) {
123
- return makePrimitive({
124
- _tag: "Spawn",
125
- child: op
126
- });
127
- }
128
166
  function* select(branches) {
129
167
  const tags = Object.keys(branches);
130
168
  const tag = tags[(yield* awaitRace(tags.map((t) => branches[t]))).index];
@@ -134,88 +172,6 @@ function* select(branches) {
134
172
  };
135
173
  }
136
174
 
137
- //#endregion
138
- //#region src/state.ts
139
- /**
140
- * Build a `State<TState>` over the given context. The runtime delegates
141
- * straight to `ctx.get` / `ctx.set` / etc.; the TState generic is purely
142
- * a TS-level convenience and gets erased at runtime.
143
- *
144
- * For shared (read-only) contexts, the returned State has the same
145
- * runtime shape but the caller should use the `SharedState<TState>`
146
- * type to drop the write methods. The convenience method
147
- * `RestateOperations.sharedState()` does this cast.
148
- */
149
- function makeState(ctx, sched, adapt$1) {
150
- const writeCtx = ctx;
151
- return {
152
- get(name, serde) {
153
- return sched.makeJournalFuture(adapt$1(ctx.get(name, serde)));
154
- },
155
- keys() {
156
- return sched.makeJournalFuture(adapt$1(ctx.stateKeys()));
157
- },
158
- set(name, value, serde) {
159
- writeCtx.set(name, value, serde);
160
- },
161
- clear(name) {
162
- writeCtx.clear(name);
163
- },
164
- clearAll() {
165
- writeCtx.clearAll();
166
- }
167
- };
168
- }
169
-
170
- //#endregion
171
- //#region src/clients.ts
172
- /**
173
- * Wrap an SDK `Client<M>` so each handler-invocation returns
174
- * `Future<T>` (via the supplied `toFuture` adapter) instead of
175
- * `InvocationPromise<T>`.
176
- */
177
- function wrapClient(client, toFuture) {
178
- return new Proxy(client, { get(target, prop, receiver) {
179
- const orig = Reflect.get(target, prop, receiver);
180
- if (typeof orig !== "function") return orig;
181
- return (...args) => {
182
- return toFuture(orig.apply(target, args));
183
- };
184
- } });
185
- }
186
- /**
187
- * Wrap an SDK `DurablePromise<T>` so each method returns `Future<...>`
188
- * instead of `Promise<...>`/`RestatePromise<...>`.
189
- */
190
- function wrapDurablePromise(dp, toFuture) {
191
- return {
192
- peek: () => toFuture(dp.peek()),
193
- resolve: (value) => toFuture(dp.resolve(value)),
194
- reject: (errorMsg) => toFuture(dp.reject(errorMsg)),
195
- get: () => toFuture(dp.get())
196
- };
197
- }
198
-
199
- //#endregion
200
- //#region src/default-lib.ts
201
- const defaultLib = {
202
- all(items) {
203
- return restate.RestatePromise.all(items);
204
- },
205
- race(items) {
206
- return restate.RestatePromise.race(items);
207
- },
208
- any(items) {
209
- return restate.RestatePromise.any(items);
210
- },
211
- allSettled(items) {
212
- return restate.RestatePromise.allSettled(items);
213
- },
214
- isCancellation(e) {
215
- return e instanceof restate.CancelledError;
216
- }
217
- };
218
-
219
175
  //#endregion
220
176
  //#region src/future.ts
221
177
  const futureBacking = Symbol("restateFutureBacking");
@@ -341,12 +297,6 @@ var Fiber = class {
341
297
  case "Leaf":
342
298
  outcome = this.parkOnLeaf(node);
343
299
  break;
344
- case "Spawn":
345
- outcome = {
346
- ok: true,
347
- v: this.sched.spawnFuture(node.child)
348
- };
349
- break;
350
300
  case "AwaitRace":
351
301
  outcome = this.parkOnAwaitRace(node.futures);
352
302
  break;
@@ -524,16 +474,20 @@ var Scheduler = class {
524
474
  lib;
525
475
  abortController = new AbortController();
526
476
  /**
527
- * Slot for the RestateOperations bound to this scheduler. Set by
528
- * `execute()` after construction (we can't pass it into the ctor
529
- * because RestateOperations needs the scheduler to construct itself).
477
+ * Slot for the operations object bound to this scheduler. Defaults
478
+ * to the scheduler itself so tests (which don't construct a
479
+ * `RestateOperations`) still get a slot exposing `.spawn`. Production
480
+ * `execute()` overrides this with a `RestateOperations` instance
481
+ * after construction (we can't pass it into the ctor because
482
+ * `RestateOperations` needs the scheduler to construct itself).
530
483
  * `Fiber.advance` publishes this to the module-level current-fiber
531
484
  * slot read by free-standing API functions. Typed `unknown` here to
532
485
  * keep this module independent of `restate-operations.ts`.
533
486
  */
534
- contextSlot = null;
487
+ contextSlot;
535
488
  constructor(lib) {
536
489
  this.lib = lib;
490
+ this.contextSlot = this;
537
491
  }
538
492
  /**
539
493
  * The scheduler's current AbortSignal. Aborts when invocation
@@ -558,12 +512,6 @@ var Scheduler = class {
558
512
  markDone(f) {
559
513
  this.fibers.delete(f);
560
514
  }
561
- spawnFuture(op) {
562
- return makeFuture({
563
- kind: "local",
564
- target: this.createFiber(op)
565
- });
566
- }
567
515
  createFiber(op) {
568
516
  const f = new Fiber(op, this);
569
517
  this.fibers.add(f);
@@ -577,13 +525,19 @@ var Scheduler = class {
577
525
  });
578
526
  }
579
527
  /**
580
- * Spawn an operation as a fresh fiber and return a Future that
581
- * resolves with its eventual value. Same as the SchedulerOps method;
582
- * exposed publicly for external callers (combinator helpers, the
583
- * main run() entry point).
528
+ * Register an Operation as a fresh fiber and return a Future that
529
+ * resolves with its eventual value. Eager: by the time this returns,
530
+ * the fiber is queued ready and will be advanced on the next drain.
531
+ *
532
+ * Used by combinator fallbacks (race, allSettled, …), by
533
+ * `RestateOperations.spawn`, and via the slot interface by the free
534
+ * `spawn` function.
584
535
  */
585
- spawnDetached(op) {
586
- return this.spawnFuture(op);
536
+ spawn(op) {
537
+ return makeFuture({
538
+ kind: "local",
539
+ target: this.createFiber(op)
540
+ });
587
541
  }
588
542
  /**
589
543
  * Construct a single-shot in-memory channel. Send must be called from
@@ -610,7 +564,7 @@ var Scheduler = class {
610
564
  const promises = fs.map((f) => f[futureBacking].promise);
611
565
  return this.makeJournalFuture(this.lib.all(promises));
612
566
  }
613
- return this.spawnDetached(gen(function* () {
567
+ return this.spawn(gen(function* () {
614
568
  const out = new Array(fs.length);
615
569
  for (let i = 0; i < fs.length; i++) out[i] = yield* fs[i];
616
570
  return out;
@@ -618,7 +572,7 @@ var Scheduler = class {
618
572
  }
619
573
  race(futures) {
620
574
  const fs = futures;
621
- return this.spawnDetached(gen(function* () {
575
+ return this.spawn(gen(function* () {
622
576
  const result = yield* awaitRace(fs);
623
577
  if (result.settled.ok) return result.settled.v;
624
578
  throw result.settled.e;
@@ -645,7 +599,7 @@ var Scheduler = class {
645
599
  const promises = fs.map((f) => f[futureBacking].promise);
646
600
  return this.makeJournalFuture(this.lib.any(promises));
647
601
  }
648
- return this.spawnDetached(gen(function* () {
602
+ return this.spawn(gen(function* () {
649
603
  const errors = new Array(fs.length);
650
604
  const remaining = /* @__PURE__ */ new Set();
651
605
  for (let i = 0; i < fs.length; i++) remaining.add(i);
@@ -679,7 +633,7 @@ var Scheduler = class {
679
633
  const promises = fs.map((f) => f[futureBacking].promise);
680
634
  return this.makeJournalFuture(this.lib.allSettled(promises));
681
635
  }
682
- return this.spawnDetached(gen(function* () {
636
+ return this.spawn(gen(function* () {
683
637
  const out = new Array(fs.length);
684
638
  for (let i = 0; i < fs.length; i++) try {
685
639
  out[i] = {
@@ -754,6 +708,137 @@ var Scheduler = class {
754
708
  }
755
709
  };
756
710
 
711
+ //#endregion
712
+ //#region src/state.ts
713
+ /**
714
+ * Build a `State<TState>` over the given context. The runtime delegates
715
+ * straight to `ctx.get` / `ctx.set` / etc.; the TState generic is purely
716
+ * a TS-level convenience and gets erased at runtime.
717
+ *
718
+ * For shared (read-only) contexts, the returned State has the same
719
+ * runtime shape but the caller should use the `SharedState<TState>`
720
+ * type to drop the write methods. The convenience method
721
+ * `RestateOperations.sharedState()` does this cast.
722
+ */
723
+ function makeState(ctx, sched, adapt$1) {
724
+ const writeCtx = ctx;
725
+ return {
726
+ get(name, serde$1) {
727
+ return sched.makeJournalFuture(adapt$1(ctx.get(name, serde$1)));
728
+ },
729
+ keys() {
730
+ return sched.makeJournalFuture(adapt$1(ctx.stateKeys()));
731
+ },
732
+ set(name, value, serde$1) {
733
+ writeCtx.set(name, value, serde$1);
734
+ },
735
+ clear(name) {
736
+ writeCtx.clear(name);
737
+ },
738
+ clearAll() {
739
+ writeCtx.clearAll();
740
+ }
741
+ };
742
+ }
743
+
744
+ //#endregion
745
+ //#region src/clients.ts
746
+ function makeClient(def, key, call$1) {
747
+ return new Proxy({}, { get(_target, methodName) {
748
+ return (...args) => {
749
+ const { parameter, opts } = optsFromArgs$1(args);
750
+ const callOpts = opts;
751
+ const desc = def._handlers[methodName];
752
+ const outputSerde = callOpts?.output ?? desc?._outputSerde;
753
+ return call$1({
754
+ service: def.name,
755
+ key,
756
+ method: String(methodName),
757
+ parameter,
758
+ inputSerde: callOpts?.input ?? desc?._inputSerde ?? restate.serde.json,
759
+ outputSerde: outputSerde ?? restate.serde.json,
760
+ idempotencyKey: callOpts?.idempotencyKey,
761
+ headers: callOpts?.headers,
762
+ name: callOpts?.name
763
+ });
764
+ };
765
+ } });
766
+ }
767
+ function makeSendClient(def, key, send$1) {
768
+ return new Proxy({}, { get(_target, methodName) {
769
+ return (...args) => {
770
+ const { parameter, opts } = optsFromArgs$1(args);
771
+ const sendOpts = opts;
772
+ const desc = def._handlers[methodName];
773
+ return send$1({
774
+ service: def.name,
775
+ key,
776
+ method: String(methodName),
777
+ parameter,
778
+ inputSerde: sendOpts?.input ?? desc?._inputSerde ?? restate.serde.json,
779
+ delay: sendOpts?.delay,
780
+ idempotencyKey: sendOpts?.idempotencyKey,
781
+ headers: sendOpts?.headers,
782
+ name: sendOpts?.name
783
+ }, desc?._outputSerde);
784
+ };
785
+ } });
786
+ }
787
+ function optsFromArgs$1(args) {
788
+ let parameter;
789
+ let opts;
790
+ switch (args.length) {
791
+ case 0: break;
792
+ case 1:
793
+ if (args[0] instanceof Opts) opts = args[0].getOpts();
794
+ else if (args[0] instanceof SendOpts) opts = args[0].getOpts();
795
+ else parameter = args[0];
796
+ break;
797
+ case 2:
798
+ parameter = args[0];
799
+ if (args[1] instanceof Opts) opts = args[1].getOpts();
800
+ else if (args[1] instanceof SendOpts) opts = args[1].getOpts();
801
+ else throw new TypeError("The second argument must be either Opts or SendOpts");
802
+ break;
803
+ default: throw new TypeError("unexpected number of arguments");
804
+ }
805
+ return {
806
+ parameter,
807
+ opts
808
+ };
809
+ }
810
+
811
+ //#endregion
812
+ //#region src/durable-promise.ts
813
+ function wrapDurablePromise(dp, toFuture) {
814
+ return {
815
+ peek: () => toFuture(dp.peek()),
816
+ resolve: (value) => toFuture(dp.resolve(value)),
817
+ reject: (errorMsg) => toFuture(dp.reject(errorMsg)),
818
+ get: () => toFuture(dp.get())
819
+ };
820
+ }
821
+
822
+ //#endregion
823
+ //#region src/default-lib.ts
824
+ const defaultLib = {
825
+ all(items) {
826
+ return restate.RestatePromise.all(items);
827
+ },
828
+ race(items) {
829
+ return restate.RestatePromise.race(items);
830
+ },
831
+ any(items) {
832
+ return restate.RestatePromise.any(items);
833
+ },
834
+ allSettled(items) {
835
+ return restate.RestatePromise.allSettled(items);
836
+ },
837
+ isCancellation(e) {
838
+ return e instanceof restate.CancelledError;
839
+ }
840
+ };
841
+
757
842
  //#endregion
758
843
  //#region src/restate-operations.ts
759
844
  function adapt(p) {
@@ -829,6 +914,18 @@ var RestateOperations = class {
829
914
  toFuture(p) {
830
915
  return this.sched.makeJournalFuture(adapt(p));
831
916
  }
917
+ get rand() {
918
+ return this.ctx.rand;
919
+ }
920
+ get date() {
921
+ return {
922
+ now: () => this.toFuture(this.ctx.date.now()),
923
+ toJSON: () => this.toFuture(this.ctx.date.toJSON())
924
+ };
925
+ }
926
+ get console() {
927
+ return this.ctx.console;
928
+ }
832
929
  /**
833
930
  * Run a side-effecting closure as a journal entry.
834
931
  *
@@ -876,57 +973,69 @@ var RestateOperations = class {
876
973
  sleep(duration, name) {
877
974
  return this.sched.makeJournalFuture(adapt(this.ctx.sleep(duration, name)));
878
975
  }
879
- awakeable(serde) {
880
- const { id, promise } = this.ctx.awakeable(serde);
976
+ awakeable(serde$1) {
977
+ const { id, promise } = this.ctx.awakeable(serde$1);
881
978
  return {
882
979
  id,
883
980
  promise: this.sched.makeJournalFuture(adapt(promise))
884
981
  };
885
982
  }
886
- resolveAwakeable(id, payload, serde) {
887
- this.ctx.resolveAwakeable(id, payload, serde);
983
+ resolveAwakeable(id, payload, serde$1) {
984
+ this.ctx.resolveAwakeable(id, payload, serde$1);
888
985
  }
889
986
  rejectAwakeable(id, reason) {
890
987
  this.ctx.rejectAwakeable(id, reason);
891
988
  }
892
- signal(name, serde) {
893
- return this.sched.makeJournalFuture(adapt(this.ctx.signal(name, serde)));
989
+ signal(name, serde$1) {
990
+ return this.sched.makeJournalFuture(adapt(this.ctx.signal(name, serde$1)));
894
991
  }
895
- attach(invocationId, serde) {
896
- return this.sched.makeJournalFuture(adapt(this.ctx.attach(invocationId, serde)));
992
+ attach(invocationId, serde$1) {
993
+ return this.sched.makeJournalFuture(adapt(this.ctx.attach(invocationId, serde$1)));
897
994
  }
898
995
  /**
899
- * Typed RPC client for a service: `ops.serviceClient(api).foo(arg)`
900
- * yields a `Future<T>` whose value is the handler's return value.
901
- *
902
- * Same shape as `ctx.serviceClient(api)` from the SDK, but each
903
- * handler-method returns `Future<T>` rather than `InvocationPromise<T>`.
996
+ * Returns the current invocation's request metadata plus the optional
997
+ * virtual-object / workflow key. The `key` field is only present when
998
+ * the handler belongs to an object or workflow.
904
999
  */
905
- serviceClient(api) {
906
- return wrapClient(this.ctx.serviceClient(api), (p) => this.toFuture(p));
907
- }
908
- /** Typed RPC client for a virtual object. See {@link serviceClient}. */
909
- objectClient(api, key) {
910
- return wrapClient(this.ctx.objectClient(api, key), (p) => this.toFuture(p));
1000
+ handlerRequest() {
1001
+ const req = this.ctx.request();
1002
+ const ctx = this.ctx;
1003
+ return {
1004
+ attemptHeaders: req.attemptHeaders,
1005
+ body: req.body,
1006
+ extraArgs: req.extraArgs,
1007
+ headers: req.headers,
1008
+ id: req.id,
1009
+ target: req.target,
1010
+ get key() {
1011
+ return ctx.key;
1012
+ }
1013
+ };
911
1014
  }
912
- /** Typed RPC client for a workflow. See {@link serviceClient}. */
913
- workflowClient(api, key) {
914
- return wrapClient(this.ctx.workflowClient(api, key), (p) => this.toFuture(p));
1015
+ client(def, key) {
1016
+ return makeClient(def, key, (o) => this.call(o));
915
1017
  }
916
- serviceSendClient(api) {
917
- return this.ctx.serviceSendClient(api);
1018
+ sendClient(def, key) {
1019
+ return makeSendClient(def, key, (o, serde$1) => this.send(o, serde$1));
918
1020
  }
919
- objectSendClient(api, key) {
920
- return this.ctx.objectSendClient(api, key);
1021
+ call(opts) {
1022
+ const restatePromise = this.ctx.genericCall(opts);
1023
+ const resultFuture = this.toFuture(restatePromise);
1024
+ const invocation$1 = this.invocationReferenceFromHandle(restatePromise, opts.outputSerde);
1025
+ return Object.assign(resultFuture, { invocation: invocation$1 });
921
1026
  }
922
- workflowSendClient(api, key) {
923
- return this.ctx.workflowSendClient(api, key);
1027
+ send(opts, outputSerde) {
1028
+ const handle = this.ctx.genericSend(opts);
1029
+ return this.invocationReferenceFromHandle(handle, outputSerde);
924
1030
  }
925
- genericCall(call) {
926
- return this.toFuture(this.ctx.genericCall(call));
1031
+ invocationReferenceFromHandle(handle, outputSerde) {
1032
+ const idFuture = this.toFuture(handle.invocationId);
1033
+ return this.sched.spawn(gen(function* () {
1034
+ return new InvocationReferenceImpl(yield* idFuture, outputSerde);
1035
+ }));
927
1036
  }
928
- genericSend(call) {
929
- return this.ctx.genericSend(call);
1037
+ invocationSignal(invocationId, name, serde$1) {
1038
+ return this.ctx.invocation(invocationId).signal(name, serde$1);
930
1039
  }
931
1040
  /**
932
1041
  * Cancel another invocation by its id. To observe cancellation
@@ -943,12 +1052,19 @@ var RestateOperations = class {
943
1052
  * `WorkflowSharedContext`). Returns a wrapper whose `peek`/`get`/
944
1053
  * `resolve`/`reject` methods return Futures.
945
1054
  */
946
- workflowPromise(name, serde) {
1055
+ workflowPromise(name, serde$1) {
947
1056
  const wfCtx = this.ctx;
948
- return wrapDurablePromise(wfCtx.promise(name, serde), (p) => this.toFuture(p));
1057
+ return wrapDurablePromise(wfCtx.promise(name, serde$1), (p) => this.toFuture(p));
949
1058
  }
1059
+ /**
1060
+ * Register `op` as a fresh routine and return a `Future<T>` for its
1061
+ * eventual outcome. Eager: by the time `spawn` returns, the child is
1062
+ * already queued and will advance on the next scheduler tick — same
1063
+ * model as `run`/`sleep`/`awakeable`. The returned Future can be
1064
+ * yielded on, handed to combinators, or stored.
1065
+ */
950
1066
  spawn(op) {
951
- return spawn(op);
1067
+ return this.sched.spawn(op);
952
1068
  }
953
1069
  /**
954
1070
  * Create a single-shot in-memory channel. Returns a Channel<T> with
@@ -1074,5 +1190,286 @@ async function execute(context, op) {
1074
1190
  }
1075
1191
 
1076
1192
  //#endregion
1077
- export { all, allSettled, any, attach, awakeable, cancel, channel, execute, gen, genericCall, genericSend, objectClient, objectSendClient, race, rejectAwakeable, resolveAwakeable, run, select, serviceClient, serviceSendClient, sharedState, signal, sleep, spawn, state, workflowClient, workflowPromise, workflowSendClient, wrapActionForCancellation };
1193
+ //#region src/define.ts
1194
+ function makeDescriptor(inputSerde, outputSerde) {
1195
+ return {
1196
+ _inputSerde: inputSerde,
1197
+ _outputSerde: outputSerde
1198
+ };
1199
+ }
1200
+ /** HandlerDef has _genFn as an object property; bare gen fns are plain functions */
1201
+ function isHandlerDef(entry) {
1202
+ return typeof entry === "object" && entry !== null && typeof entry._genFn === "function";
1203
+ }
1204
+ /** Convert a Standard Schema to a Serde via restate.serde.schema() */
1205
+ function toSerde(schema) {
1206
+ return restate.serde.schema(schema);
1207
+ }
1208
+ function extractEntry(entry) {
1209
+ if (isHandlerDef(entry)) return {
1210
+ genFn: entry._genFn,
1211
+ inputSerde: entry._inputSerde,
1212
+ outputSerde: entry._outputSerde
1213
+ };
1214
+ return {
1215
+ genFn: entry,
1216
+ inputSerde: void 0,
1217
+ outputSerde: void 0
1218
+ };
1219
+ }
1220
+ /** serdes(opts, fn) — explicit Serde per field */
1221
+ function serdes(opts, fn) {
1222
+ return {
1223
+ _genFn: fn,
1224
+ _inputSerde: opts.input,
1225
+ _outputSerde: opts.output
1226
+ };
1227
+ }
1228
+ /** schemas(opts, fn) — Standard Schema (Zod, TypeBox, Valibot, …) per field */
1229
+ function schemas(opts, fn) {
1230
+ return {
1231
+ _genFn: fn,
1232
+ _inputSerde: toSerde(opts.input),
1233
+ _outputSerde: toSerde(opts.output)
1234
+ };
1235
+ }
1236
+ function service(config) {
1237
+ const { name, description, metadata, handlers, options } = config;
1238
+ const { handlers: perHandlerOpts,...serviceOpts } = options ?? {};
1239
+ const coreHandlers = {};
1240
+ const descriptors = {};
1241
+ for (const [handlerName, entry] of Object.entries(handlers)) {
1242
+ const { genFn, inputSerde, outputSerde } = extractEntry(entry);
1243
+ const handlerOpts = perHandlerOpts?.[handlerName] ?? {};
1244
+ coreHandlers[handlerName] = restate.handlers.handler({
1245
+ input: inputSerde,
1246
+ output: outputSerde,
1247
+ ...handlerOpts
1248
+ }, async (ctx, input) => execute(ctx, genFn(input)));
1249
+ descriptors[handlerName] = makeDescriptor(inputSerde, outputSerde);
1250
+ }
1251
+ const coreDef = restate.service({
1252
+ name,
1253
+ handlers: coreHandlers,
1254
+ description,
1255
+ metadata,
1256
+ options: serviceOpts
1257
+ });
1258
+ return Object.assign(coreDef, {
1259
+ _kind: "service",
1260
+ _handlers: descriptors
1261
+ });
1262
+ }
1263
+ function object(config) {
1264
+ const { name, description, metadata, handlers, options } = config;
1265
+ const { handlers: perHandlerOpts,...objectOpts } = options ?? {};
1266
+ const coreHandlers = {};
1267
+ const descriptors = {};
1268
+ for (const [handlerName, entry] of Object.entries(handlers)) {
1269
+ const { genFn, inputSerde, outputSerde } = extractEntry(entry);
1270
+ const { shared,...restOpts } = perHandlerOpts?.[handlerName] ?? {};
1271
+ const sdkOpts = {
1272
+ input: inputSerde,
1273
+ output: outputSerde,
1274
+ ...restOpts
1275
+ };
1276
+ const fn = async (ctx, input) => execute(ctx, genFn(input));
1277
+ coreHandlers[handlerName] = shared ? restate.handlers.object.shared(sdkOpts, fn) : restate.handlers.object.exclusive(sdkOpts, fn);
1278
+ descriptors[handlerName] = makeDescriptor(inputSerde, outputSerde);
1279
+ }
1280
+ const coreDef = restate.object({
1281
+ name,
1282
+ handlers: coreHandlers,
1283
+ description,
1284
+ metadata,
1285
+ options: objectOpts
1286
+ });
1287
+ return Object.assign(coreDef, {
1288
+ _kind: "object",
1289
+ _handlers: descriptors
1290
+ });
1291
+ }
1292
+ function workflow(config) {
1293
+ const { name, description, metadata, handlers, options } = config;
1294
+ const { handlers: perHandlerOpts,...workflowOpts } = options ?? {};
1295
+ const coreHandlers = {};
1296
+ const descriptors = {};
1297
+ for (const [handlerName, entry] of Object.entries(handlers)) {
1298
+ const { genFn, inputSerde, outputSerde } = extractEntry(entry);
1299
+ const sdkOpts = {
1300
+ input: inputSerde,
1301
+ output: outputSerde,
1302
+ ...perHandlerOpts?.[handlerName] ?? {}
1303
+ };
1304
+ const fn = async (ctx, input) => execute(ctx, genFn(input));
1305
+ coreHandlers[handlerName] = handlerName === "run" ? restate.handlers.workflow.workflow(sdkOpts, fn) : restate.handlers.workflow.shared(sdkOpts, fn);
1306
+ descriptors[handlerName] = makeDescriptor(inputSerde, outputSerde);
1307
+ }
1308
+ const coreDef = restate.workflow({
1309
+ name,
1310
+ handlers: coreHandlers,
1311
+ description,
1312
+ metadata,
1313
+ options: workflowOpts
1314
+ });
1315
+ return Object.assign(coreDef, {
1316
+ _kind: "workflow",
1317
+ _handlers: descriptors
1318
+ });
1319
+ }
1320
+
1321
+ //#endregion
1322
+ //#region src/interface.ts
1323
+ var interface_exports = /* @__PURE__ */ __export({
1324
+ implement: () => implement,
1325
+ json: () => json,
1326
+ object: () => object$1,
1327
+ schemas: () => schemas$1,
1328
+ serdes: () => serdes$1,
1329
+ service: () => service$1,
1330
+ workflow: () => workflow$1
1331
+ });
1332
+ /** json<I, O>() — type params, default JSON serde */
1333
+ function json() {
1334
+ return makeDescriptor(void 0, void 0);
1335
+ }
1336
+ /** serdes(opts) — explicit Serde per field */
1337
+ function serdes$1(opts) {
1338
+ return makeDescriptor(opts.input, opts.output);
1339
+ }
1340
+ /** schemas(opts) — Standard Schema (Zod, TypeBox, Valibot, …) per field */
1341
+ function schemas$1(opts) {
1342
+ return makeDescriptor(opts.input ? toSerde(opts.input) : void 0, opts.output ? toSerde(opts.output) : void 0);
1343
+ }
1344
+ function service$1(name, handlers) {
1345
+ return {
1346
+ name,
1347
+ _kind: "service",
1348
+ _handlers: handlers
1349
+ };
1350
+ }
1351
+ function object$1(name, handlers) {
1352
+ return {
1353
+ name,
1354
+ _kind: "object",
1355
+ _handlers: handlers
1356
+ };
1357
+ }
1358
+ function workflow$1(name, handlers) {
1359
+ return {
1360
+ name,
1361
+ _kind: "workflow",
1362
+ _handlers: handlers
1363
+ };
1364
+ }
1365
+ function implement(iface, config) {
1366
+ const handlerEntries = {};
1367
+ for (const [name, desc] of Object.entries(iface._handlers)) {
1368
+ const genFn = config.handlers[name];
1369
+ if (!genFn) throw new Error(`implement(): missing handler "${name}"`);
1370
+ handlerEntries[name] = {
1371
+ _genFn: genFn,
1372
+ _inputSerde: desc._inputSerde,
1373
+ _outputSerde: desc._outputSerde
1374
+ };
1375
+ }
1376
+ if (iface._kind === "service") return service({
1377
+ name: iface.name,
1378
+ handlers: handlerEntries,
1379
+ options: config.options
1380
+ });
1381
+ else if (iface._kind === "object") return object({
1382
+ name: iface.name,
1383
+ handlers: handlerEntries,
1384
+ options: config.options
1385
+ });
1386
+ else return workflow({
1387
+ name: iface.name,
1388
+ handlers: handlerEntries,
1389
+ options: config.options
1390
+ });
1391
+ }
1392
+
1393
+ //#endregion
1394
+ //#region src/ingress.ts
1395
+ var ingress_exports = /* @__PURE__ */ __export({
1396
+ SendOpts: () => SendOpts$1,
1397
+ client: () => client$1,
1398
+ connect: () => connect$1,
1399
+ sendClient: () => sendClient$1
1400
+ });
1401
+ /**
1402
+ * Connect to the Restate Ingress.
1403
+ *
1404
+ * @param opts connection options
1405
+ * @returns a connection the the restate ingress
1406
+ */
1407
+ function connect$1(opts) {
1408
+ return connect(opts);
1409
+ }
1410
+ function client$1(ingress, def, key) {
1411
+ return new Proxy({}, { get(_target, methodName) {
1412
+ return (...args) => {
1413
+ const { parameter, opts } = optsFromArgs(args);
1414
+ const desc = def._handlers[methodName];
1415
+ const mergedOpts = Opts$1.from({
1416
+ ...opts?.opts,
1417
+ input: opts?.opts?.input ?? desc?._inputSerde,
1418
+ output: opts?.opts?.output ?? desc?._outputSerde
1419
+ });
1420
+ return ingress.call({
1421
+ service: def.name,
1422
+ handler: methodName,
1423
+ parameter,
1424
+ key,
1425
+ opts: mergedOpts
1426
+ });
1427
+ };
1428
+ } });
1429
+ }
1430
+ function sendClient$1(ingress, def, key) {
1431
+ return new Proxy({}, { get(_target, methodName) {
1432
+ return (...args) => {
1433
+ const { parameter, opts } = optsFromArgs(args);
1434
+ const desc = def._handlers[methodName];
1435
+ const mergedOpts = SendOpts$1.from({
1436
+ ...opts?.opts,
1437
+ input: opts?.opts?.input ?? desc?._inputSerde
1438
+ });
1439
+ return ingress.send({
1440
+ service: def.name,
1441
+ handler: methodName,
1442
+ parameter,
1443
+ key,
1444
+ opts: mergedOpts
1445
+ });
1446
+ };
1447
+ } });
1448
+ }
1449
+ function optsFromArgs(args) {
1450
+ let parameter;
1451
+ let opts;
1452
+ switch (args.length) {
1453
+ case 0: break;
1454
+ case 1:
1455
+ if (args[0] instanceof Opts$1) opts = args[0];
1456
+ else if (args[0] instanceof SendOpts$1) opts = args[0];
1457
+ else parameter = args[0];
1458
+ break;
1459
+ case 2:
1460
+ parameter = args[0];
1461
+ if (args[1] instanceof Opts$1) opts = args[1];
1462
+ else if (args[1] instanceof SendOpts$1) opts = args[1];
1463
+ else throw new TypeError("The second argument must be either Opts or SendOpts");
1464
+ break;
1465
+ default: throw new TypeError("unexpected number of arguments");
1466
+ }
1467
+ return {
1468
+ parameter,
1469
+ opts
1470
+ };
1471
+ }
1472
+
1473
+ //#endregion
1474
+ export { all, allSettled, any, attach, awakeable, call, cancel, channel, client, ingress_exports as clients, date, gen, handlerRequest, interface_exports as iface, implement, invocation, logger, object, race, rand, rejectAwakeable, resolveAwakeable, run, schemas, select, send, sendClient, serde, serdes, service, sharedState, signal, sleep, spawn, state, workflow, workflowPromise, wrapActionForCancellation };
1078
1475
  //# sourceMappingURL=index.js.map